os/mm/devsound/devsoundrefplugin/src/platsec/server/AudioServer/MmfDevSoundSessionBody.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/mm/devsound/devsoundrefplugin/src/platsec/server/AudioServer/MmfDevSoundSessionBody.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,2160 @@
     1.4 +// Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +//
    1.18 +
    1.19 +#include <e32base.h>
    1.20 +#ifdef SYMBIAN_MULTIMEDIA_CODEC_API
    1.21 +#include <OMX_Core.h>
    1.22 +#endif // SYMBIAN_MULTIMEDIA_CODEC_API
    1.23 +#include "MmfDevSoundSessionBody.h"
    1.24 +#include "MmfDevSoundSessionXtnd.h"
    1.25 +#include "MmfDevSoundServer.h"
    1.26 +#include <mdaaudiotoneplayer.h>
    1.27 +#include <mmf/server/mmfdatabuffer.h>
    1.28 +#include <mmffourcc.h>
    1.29 +#include <mmfhwdeviceimplementationuids.hrh>
    1.30 +#include <mmf/server/mmfswcodecwrappercustominterfacesuids.hrh> // KUidRefDevSoundTaskConfig & KMmfUidEmptyBuffersCustomInterface
    1.31 +#include <mmf/server/mmfdevsoundcustominterfacesupport.h>
    1.32 +
    1.33 +const TUid KEmptyBuffersCustomInterfaceTypeUid	= {KMmfUidEmptyBuffersCustomInterface};
    1.34 +
    1.35 +/*
    1.36 + *
    1.37 + *	Default Constructor.
    1.38 + *
    1.39 + *	No default implementation. CMMFDevSoundProxy implements 2-phase construction.
    1.40 + *
    1.41 + */
    1.42 +CMMFDevSoundSvrImp::CMMFDevSoundSvrImp(CMMFDevSoundSessionXtnd* aParent)
    1.43 +: iParent(*aParent)
    1.44 +	{
    1.45 +	iMode= EMMFDevSoundStateIdle;
    1.46 +	//Set reasonable default values for DTMF 
    1.47 +	iDTMFGen.SetToneDurations(250000,50000,250000);
    1.48 +	}
    1.49 +
    1.50 +/*
    1.51 + *
    1.52 + *	Destructor.
    1.53 + *
    1.54 + *	Deletes all objects and releases all resource owned by this
    1.55 + *	instance.
    1.56 + *
    1.57 + */
    1.58 +CMMFDevSoundSvrImp::~CMMFDevSoundSvrImp()
    1.59 +	{
    1.60 +	delete iToneBuffer1;
    1.61 +	delete iToneBuffer2;
    1.62 +	delete iDevSoundEventHandler; 
    1.63 +	if( iAudioPolicyProxy != NULL)
    1.64 +		{
    1.65 +		iAudioPolicyProxy->Close(); 
    1.66 +		delete iAudioPolicyProxy;
    1.67 +		}
    1.68 +	delete iDevSoundUtil;
    1.69 +	delete iFixedSequences;
    1.70 +	delete iCMMFHwDevice;
    1.71 +#ifdef SYMBIAN_MULTIMEDIA_CODEC_API
    1.72 +	OMX_Deinit();
    1.73 +#endif // SYMBIAN_MULTIMEDIA_CODEC_API
    1.74 +	}
    1.75 +
    1.76 +/*
    1.77 + *
    1.78 + *	Constructs, and returns a pointer to, a new CMMFDevSoundSvrImp object.
    1.79 + *
    1.80 + *	Leaves on failure.
    1.81 + *
    1.82 + */
    1.83 +CMMFDevSoundSvrImp* CMMFDevSoundSvrImp::NewL(CMMFDevSoundSessionXtnd* aParent)
    1.84 +	{
    1.85 +	CMMFDevSoundSvrImp* self = new (ELeave) CMMFDevSoundSvrImp(aParent);
    1.86 +	return self;
    1.87 +	}
    1.88 +
    1.89 +/*
    1.90 + *
    1.91 + *	3rd phase constructor - assumes that iParent has already been set up properly
    1.92 + *                          (During ConstructL() it has yet to be
    1.93 + *
    1.94 + */
    1.95 +void CMMFDevSoundSvrImp::Construct3L(RServer2& aPolicyServerHandle)
    1.96 +	{
    1.97 +	// all these data properties should be NULL, but add ASSERTs to verity
    1.98 +	ASSERT(iAudioPolicyProxy==NULL);
    1.99 +	iAudioPolicyProxy = new (ELeave) RMMFAudioPolicyProxy();
   1.100 +	ASSERT(iDevSoundEventHandler==NULL);
   1.101 +	iDevSoundEventHandler = CMMFDevSoundEventHandler::NewL(iAudioPolicyProxy);
   1.102 +	User::LeaveIfError(iAudioPolicyProxy->Open(aPolicyServerHandle));
   1.103 +	iDevSoundEventHandler->SetDevSoundInfo(&iParent);
   1.104 +
   1.105 +	iDevSoundUtil = CMMFDevSoundUtility::NewL();
   1.106 +	// Initialize Fixed sequence related
   1.107 +	iDevSoundUtil->InitializeFixedSequenceL(&iFixedSequences);
   1.108 +	
   1.109 +#ifdef SYMBIAN_MULTIMEDIA_CODEC_API
   1.110 +	OMX_Init();
   1.111 +#endif // SYMBIAN_MULTIMEDIA_CODEC_API
   1.112 +	PreInitializeL();
   1.113 +	}
   1.114 +
   1.115 +/**
   1.116 + * internal procedure to perform all initialization prior to setting the 
   1.117 + * data type 4CC code
   1.118 + */
   1.119 +void CMMFDevSoundSvrImp::PreInitializeL()
   1.120 +	{
   1.121 +	// Set default values for priority settings: Note: Client must 
   1.122 +	// over ride default settings by calling SetPrioirtySettings
   1.123 +	iAudioPolicyPrioritySettings.iState = EMMFStateStopped;
   1.124 +	iAudioPolicyPrioritySettings.iPref = EMdaPriorityPreferenceNone;
   1.125 +	iAudioPolicyPrioritySettings.iPriority = 0;
   1.126 +
   1.127 +	// Get device capabilities and current settings from Audio Policy:
   1.128 +	User::LeaveIfError(iAudioPolicyProxy->GetPlayFormatsSupported(iPlayFormatsSupported));
   1.129 +	User::LeaveIfError(iAudioPolicyProxy->GetPlayFormat(iPlayFormat));
   1.130 +	User::LeaveIfError(iAudioPolicyProxy->GetRecordFormatsSupported(iRecordFormatsSupported));
   1.131 +	User::LeaveIfError(iAudioPolicyProxy->GetRecordFormat(iRecordFormat));
   1.132 +
   1.133 +	//default to play until we know we are recording
   1.134 +	User::LeaveIfError(InitializeFormat(iPlayFormatsSupported, iPlayFormat));
   1.135 +	}
   1.136 +
   1.137 +/*
   1.138 + *
   1.139 + *	Initializes CMMFDevSoundProxy object to play and record PCM16 raw audio data
   1.140 + *	with sampling rate of 8 KHz.
   1.141 + *
   1.142 + *	On completion of Initialization, calls InitializeComplete() on
   1.143 + *	aDevSoundObserver.
   1.144 + *
   1.145 + *	Leaves on failure.
   1.146 + *
   1.147 + *	@param	"MDevSoundObserver& aDevSoundObserver"
   1.148 + *			A reference to DevSound Observer instance.
   1.149 + *
   1.150 + *	@param	"TMMFState aMode"
   1.151 + *			Mode for which this object will be used.
   1.152 + *
   1.153 + */
   1.154 +void CMMFDevSoundSvrImp::InitializeL(MDevSoundObserver& aDevSoundObserver, TMMFState aMode)
   1.155 +
   1.156 +	{
   1.157 +	// if no HwDevice id specified, load default null implementation
   1.158 +	TUid rawUid = {KMmfUidHwDevicePCM16ToPCM16};
   1.159 +	InitializeL(aDevSoundObserver, rawUid, aMode);
   1.160 +	__ASSERT_DEBUG(!(iHasPolicy&&(iMode == EMMFDevSoundStatePlaying)), Panic(TMMFDevSoundSessionPolicyNotInvalidated));
   1.161 +	}
   1.162 +
   1.163 +/*
   1.164 + *
   1.165 + *	Configure CMMFDevSoundProxy object for the settings in aConfig.
   1.166 + *
   1.167 + *	Use this to set sampling rate, Encoding and Mono/Stereo.
   1.168 + *
   1.169 + *	@param	"TMMFCapabilities& aConfig"
   1.170 + *			Attribute values to which CMMFDevSoundProxy object will be configured to.
   1.171 + *
   1.172 + *  As part of defect 20796, the iRecordFormat has been set under the iPlayFormat, 
   1.173 + *  before it was not set at all.
   1.174 + *
   1.175 + */
   1.176 +void CMMFDevSoundSvrImp::SetConfigL(const TMMFCapabilities& aConfig)
   1.177 +	{
   1.178 +	TUint attributeValue = aConfig.iRate;
   1.179 +	// WINS supports from 8000 Hz to 96000 Hz
   1.180 +	// The ToneGenerator currently supports sample rate of 8000Hz only. 
   1.181 +	if(iMode == EMMFDevSoundStateTonePlaying && (attributeValue != EMMFSampleRate8000Hz ))
   1.182 +		{
   1.183 +		User::Leave(KErrNotSupported);
   1.184 +		}
   1.185 +	
   1.186 +	if (attributeValue & EMMFSampleRate96000Hz) 
   1.187 +		{ 
   1.188 +		iPlayFormat().iRate = 96000; 
   1.189 +		iRecordFormat().iRate = 96000;
   1.190 +		iDeviceConfig.iRate = EMMFSampleRate96000Hz;
   1.191 +		}
   1.192 +	else if (attributeValue & EMMFSampleRate88200Hz) 
   1.193 +		{ 
   1.194 +		iPlayFormat().iRate = 88200; 
   1.195 +		iRecordFormat().iRate = 88200;
   1.196 +		iDeviceConfig.iRate = EMMFSampleRate88200Hz;
   1.197 +		}
   1.198 +	else if (attributeValue & EMMFSampleRate64000Hz) 
   1.199 +		{ 
   1.200 +		iPlayFormat().iRate = 64000; 
   1.201 +		iRecordFormat().iRate = 64000;
   1.202 +		iDeviceConfig.iRate = EMMFSampleRate64000Hz;
   1.203 +		}
   1.204 +	else if (attributeValue & EMMFSampleRate48000Hz) 
   1.205 +		{ 
   1.206 +		iPlayFormat().iRate = 48000; 
   1.207 +		iRecordFormat().iRate = 48000;
   1.208 +		iDeviceConfig.iRate = EMMFSampleRate48000Hz;
   1.209 +		}
   1.210 +	else if (attributeValue & EMMFSampleRate44100Hz) 
   1.211 +		{ 
   1.212 +		iPlayFormat().iRate = 44100; 
   1.213 +		iRecordFormat().iRate = 44100;
   1.214 +		iDeviceConfig.iRate = EMMFSampleRate44100Hz;
   1.215 +		}
   1.216 +	else if (attributeValue & EMMFSampleRate32000Hz) 
   1.217 +		{ 
   1.218 +		iPlayFormat().iRate = 32000; 
   1.219 +		iRecordFormat().iRate = 32000; 
   1.220 +		iDeviceConfig.iRate = EMMFSampleRate32000Hz;
   1.221 +		}
   1.222 +	else if (attributeValue & EMMFSampleRate24000Hz)
   1.223 +		{
   1.224 +		iPlayFormat().iRate = 
   1.225 +		iRecordFormat().iRate = 24000;
   1.226 +		iDeviceConfig.iRate = EMMFSampleRate24000Hz;
   1.227 +		}
   1.228 +	else if (attributeValue & EMMFSampleRate22050Hz)
   1.229 +		{ 
   1.230 +		iPlayFormat().iRate = 22050; 
   1.231 +		iRecordFormat().iRate = 22050; 
   1.232 +		iDeviceConfig.iRate = EMMFSampleRate22050Hz;
   1.233 +		}
   1.234 +	else if (attributeValue & EMMFSampleRate16000Hz)
   1.235 +		{
   1.236 +		iPlayFormat().iRate = 16000;
   1.237 +		iRecordFormat().iRate = 16000; 
   1.238 +		iDeviceConfig.iRate = EMMFSampleRate16000Hz;
   1.239 +		}
   1.240 +	else if (attributeValue & EMMFSampleRate12000Hz)
   1.241 +		{
   1.242 +		iPlayFormat().iRate = 
   1.243 +		iRecordFormat().iRate = 12000;
   1.244 +		iDeviceConfig.iRate = EMMFSampleRate12000Hz;
   1.245 +		}
   1.246 +	else if (attributeValue & EMMFSampleRate11025Hz)
   1.247 +		{
   1.248 +		iPlayFormat().iRate = 11025;
   1.249 +		iRecordFormat().iRate = 11025;
   1.250 +		iDeviceConfig.iRate = EMMFSampleRate11025Hz;
   1.251 +		}
   1.252 +	else if (attributeValue & EMMFSampleRate8000Hz)
   1.253 +		{
   1.254 +		iPlayFormat().iRate = 8000;
   1.255 +		iRecordFormat().iRate = 8000;
   1.256 +		iDeviceConfig.iRate = EMMFSampleRate8000Hz;
   1.257 +		}
   1.258 +	else if (attributeValue) 
   1.259 +		{ //if no attribute value assume its not set
   1.260 +		User::Leave(KErrNotSupported);
   1.261 +		}
   1.262 +
   1.263 +	attributeValue = aConfig.iEncoding;
   1.264 +	// Map from MMF Encoding enums to RMdaDevSound enum
   1.265 +	if(attributeValue & EMMFSoundEncoding8BitPCM) 
   1.266 +		{
   1.267 +		iPlayFormat().iEncoding = RMdaDevSound::EMdaSoundEncoding8BitPCM;
   1.268 +		iRecordFormat().iEncoding = RMdaDevSound::EMdaSoundEncoding8BitPCM;
   1.269 +		iDeviceConfig.iEncoding = EMMFSoundEncoding8BitPCM;
   1.270 +		}
   1.271 +	else if(attributeValue & EMMFSoundEncoding8BitALaw)
   1.272 +		{
   1.273 +		iPlayFormat().iEncoding = RMdaDevSound::EMdaSoundEncoding8BitALaw;
   1.274 +		iRecordFormat().iEncoding = RMdaDevSound::EMdaSoundEncoding8BitALaw;
   1.275 +		iDeviceConfig.iEncoding = EMMFSoundEncoding8BitALaw;
   1.276 +		}
   1.277 +	else if(attributeValue & EMMFSoundEncoding8BitMuLaw) 
   1.278 +		{
   1.279 +		iPlayFormat().iEncoding = RMdaDevSound::EMdaSoundEncoding8BitMuLaw;
   1.280 +		iRecordFormat().iEncoding = RMdaDevSound::EMdaSoundEncoding8BitMuLaw;
   1.281 +		iDeviceConfig.iEncoding = EMMFSoundEncoding8BitMuLaw;
   1.282 +		}
   1.283 +	else if(attributeValue & EMMFSoundEncoding16BitPCM)
   1.284 +		{
   1.285 +		iPlayFormat().iEncoding = RMdaDevSound::EMdaSoundEncoding16BitPCM;
   1.286 +		iRecordFormat().iEncoding = RMdaDevSound::EMdaSoundEncoding16BitPCM;
   1.287 +		iDeviceConfig.iEncoding = EMMFSoundEncoding16BitPCM;
   1.288 +		}
   1.289 +	else if (attributeValue) 
   1.290 +		{ //if no attribute value assume its not set
   1.291 +		User::Leave(KErrNotSupported);
   1.292 +		}
   1.293 +
   1.294 +	// Mono/Stereo settings
   1.295 +	attributeValue = aConfig.iChannels;
   1.296 +	if(iMode == EMMFDevSoundStateTonePlaying && (attributeValue != EMMFMono ))
   1.297 +		{
   1.298 +		User::Leave(KErrNotSupported);
   1.299 +		}
   1.300 +	if(attributeValue & EMMFStereo) 
   1.301 +		{
   1.302 +		iPlayFormat().iChannels = 2;
   1.303 +		iRecordFormat().iChannels = 2;
   1.304 +		iDeviceConfig.iChannels = EMMFStereo;
   1.305 +		}
   1.306 +	else if(attributeValue & EMMFMono)
   1.307 +		{
   1.308 +		iPlayFormat().iChannels = 1;
   1.309 +		iRecordFormat().iChannels = 1;
   1.310 +		iDeviceConfig.iChannels = EMMFMono;
   1.311 +		}
   1.312 +	else if (attributeValue) 
   1.313 +		{ //if no attribute value assume its not set
   1.314 +		User::Leave(KErrNotSupported);
   1.315 +		}
   1.316 +	}
   1.317 +
   1.318 +/*
   1.319 + *
   1.320 + *	Changes the current playback volume to a specified value.
   1.321 + *
   1.322 + *	The volume can be changed before or during playback and is effective
   1.323 + *	immediately.
   1.324 + *
   1.325 + *	@param	"TInt aVolume"
   1.326 + *			The volume setting. This can be any value from zero to the value
   1.327 + *			returned by a call to CMdaAudioPlayerUtility::MaxVolume(). If the
   1.328 + *			volume is not within this range, the volume is automatically set to
   1.329 + *			minimum or maximum value based on the value that is being passed.
   1.330 + *			Setting a zero value mutes the sound. Setting the maximum value
   1.331 + *			results in the loudest possible sound.
   1.332 + *
   1.333 + */
   1.334 +void CMMFDevSoundSvrImp::SetVolume(TInt aVolume)
   1.335 +	{
   1.336 +
   1.337 +	// Check and make sure that the volume is in valid range
   1.338 +	if (aVolume < 0)
   1.339 +		aVolume = 0;
   1.340 +
   1.341 +	if (aVolume > MaxVolume())
   1.342 +		aVolume = MaxVolume();
   1.343 +
   1.344 +	iVolume = aVolume;
   1.345 +
   1.346 +	SetDeviceVolume(iVolume);
   1.347 +	}
   1.348 +
   1.349 +/*
   1.350 + *
   1.351 + *	Changes the current recording gain to a specified value.
   1.352 + *
   1.353 + *	The gain can be changed before or during recording and is effective
   1.354 + *	immediately.
   1.355 + *
   1.356 + *	@param	"TInt aGain"
   1.357 + *			The volume setting. This can be any value from zero to the value
   1.358 + *			returned by a call to CMdaAudioPlayerUtility::MaxVolume(). If the
   1.359 + *			volume is not within this range, the gain is automatically set to
   1.360 + *			minimum or maximum value based on the value that is being passed.
   1.361 + *			Setting a zero value mutes the sound. Setting the maximum value
   1.362 + *			results in the loudest possible sound.
   1.363 + *
   1.364 + */
   1.365 +void CMMFDevSoundSvrImp::SetGain(TInt aGain)
   1.366 +	{
   1.367 +	// make sure it falls with the correct range
   1.368 +	TInt maxGain = iRecordFormatsSupported().iMaxVolume;
   1.369 +	if (aGain > maxGain)
   1.370 +		aGain = maxGain;
   1.371 +	else if (aGain < 0)
   1.372 +		aGain = 0;
   1.373 +	iGain = aGain;
   1.374 +	SetDeviceRecordLevel(iGain);
   1.375 +	}
   1.376 +
   1.377 +/*
   1.378 + *
   1.379 + *	Sets the speaker balance for playing.
   1.380 + *
   1.381 + *	The speaker balance can be changed before or during playback and is
   1.382 + *	effective immediately.
   1.383 + *
   1.384 + *	@param	"TInt& aLeftPercentage"
   1.385 + *			On return contains left speaker volume perecentage. This can be any
   1.386 + *			value from zero to 100. Setting a zero value mutes the sound on left
   1.387 + *			speaker.
   1.388 + *
   1.389 + *	@param	"TInt& aRightPercentage"
   1.390 + *			On return contains right speaker volume perecentage. This can be any
   1.391 + *			value from zero to 100. Setting a zero value mutes the sound on
   1.392 + *			right speaker.
   1.393 + *
   1.394 + */
   1.395 +void CMMFDevSoundSvrImp::SetPlayBalanceL(TInt aLeftPercentage, TInt aRightPercentage)
   1.396 +	{
   1.397 +	if (aLeftPercentage < 0)
   1.398 +		aLeftPercentage = 0;
   1.399 +	else if (aLeftPercentage > 100)
   1.400 +		aLeftPercentage = 100;
   1.401 +	if (aRightPercentage < 0)
   1.402 +		aRightPercentage = 0;
   1.403 +	else if (aRightPercentage > 100)
   1.404 +		aRightPercentage = 100;
   1.405 +	iLeftPlayBalance = aLeftPercentage;
   1.406 +	iRightPlayBalance = aRightPercentage;
   1.407 +	}
   1.408 +
   1.409 +/*
   1.410 + *
   1.411 + *	Sets the microphone gain balance for recording.
   1.412 + *
   1.413 + *	The microphone gain balance can be changed before or during recording and
   1.414 + *	is effective immediately.
   1.415 + *
   1.416 + *	@param	"TInt aLeftPercentage"
   1.417 + *			Left microphone gain precentage. This can be any value from zero to
   1.418 + *			100. Setting a zero value mutes the gain on left microphone.
   1.419 + *
   1.420 + *	@param	"TInt aRightPercentage"
   1.421 + *			Right microphone gain precentage. This can be any value from zero to
   1.422 + *			100. Setting a zero value mutes the gain on right microphone.
   1.423 + *
   1.424 + */
   1.425 +void CMMFDevSoundSvrImp::SetRecordBalanceL(TInt aLeftPercentage, TInt aRightPercentage)
   1.426 +	{
   1.427 +	if (aLeftPercentage < 0)
   1.428 +		aLeftPercentage = 0;
   1.429 +	else if (aLeftPercentage > 100)
   1.430 +		aLeftPercentage = 100;
   1.431 +	if (aRightPercentage < 0)
   1.432 +		aRightPercentage = 0;
   1.433 +	else if (aRightPercentage > 100)
   1.434 +		aRightPercentage = 100;
   1.435 +	iLeftRecordBalance = aLeftPercentage;
   1.436 +	iRightRecordBalance = aRightPercentage;
   1.437 +	}
   1.438 +
   1.439 +/*
   1.440 + *
   1.441 + *	Initializes audio device and start play process. This method queries and
   1.442 + *	acquires the audio policy before initializing audio device. If there was an
   1.443 + *	error during policy initialization, PlayError() method will be called on
   1.444 + *	the observer with error code KErrAccessDenied, otherwise BufferToBeFilled()
   1.445 + *	method will be called with a buffer reference. After reading data into the
   1.446 + *	buffer reference passed, the client should call PlayData() to play data.
   1.447 + *
   1.448 + *	The amount of data that can be played is specified in
   1.449 + *	CMMFBuffer::RequestSize(). Any data that is read into buffer beyond this
   1.450 + *	size will be ignored.
   1.451 + *
   1.452 + *	Leaves on failure.
   1.453 + *
   1.454 + */
   1.455 +void CMMFDevSoundSvrImp::PlayInitL()
   1.456 +	{
   1.457 +	if (!iDevSoundObserver)
   1.458 +		User::Leave(KErrNotReady);
   1.459 +
   1.460 +	if (iAudioPolicyPrioritySettings.iState == EMMFStatePlayData)
   1.461 +		{
   1.462 +		// If policy has not been obtaing then ignore the request.
   1.463 +		// If it has then do a stop and start action on HW device
   1.464 +		// without informing policy.
   1.465 +		
   1.466 +		if (iHasPolicy)
   1.467 +			{
   1.468 +			if (iCMMFHwDevice)
   1.469 +				{
   1.470 +				TInt err = iCMMFHwDevice->Stop();
   1.471 +				if (err == KErrNone)
   1.472 +					{
   1.473 +					err = iCMMFHwDevice->Start(EDevDecode, EDevOutFlow);
   1.474 +					}
   1.475 +				
   1.476 +				if (err != KErrNone)
   1.477 +					{
   1.478 +					Error(err);
   1.479 +					}
   1.480 +				}
   1.481 +			}
   1.482 +		return;
   1.483 +		}
   1.484 +
   1.485 +	// Get audio policy
   1.486 +	iAudioPolicyPrioritySettings.iState = EMMFStatePlayData;
   1.487 +	RequestPolicy();
   1.488 +	}
   1.489 +
   1.490 +/*
   1.491 + *
   1.492 + *	Initializes audio device and start record process. 
   1.493 + *  This method:
   1.494 + *  1. Queries and acquires the audio policy before initializing audio device. 
   1.495 + *     If there was an error during policy initialization, RecordError() method will 
   1.496 + *     be called on the observer with error code KErrAccessDenied, otherwise BufferToBeEmptied()
   1.497 + *	   method will be called with a buffer reference. This buffer contains recorded
   1.498 + *	   or encoded data. After processing data in the buffer reference passed, the
   1.499 + *	   client should call RecordData() to continue recording process.
   1.500 + *
   1.501 + *  2. Checks if the requesting client process has a UserEnvironment capability.
   1.502 + *     If it does not, the audio device will not be initialized and an error 
   1.503 + *     code KErrAccessDenied will be sent to the client.
   1.504 + *
   1.505 + *	The amount of data that is available is specified in
   1.506 + *	CMMFBuffer::RequestSize().
   1.507 + *
   1.508 + *	Leaves on failure.
   1.509 + *
   1.510 + */
   1.511 +void CMMFDevSoundSvrImp::RecordInitL(const RMmfIpcMessage& aMessage)
   1.512 +	{
   1.513 +	if (!iDevSoundObserver)
   1.514 +		User::Leave(KErrNotReady);
   1.515 +	
   1.516 +	// Checkes if the client has the UserEnvironment capability
   1.517 +	if (!aMessage.HasCapability(ECapabilityUserEnvironment))
   1.518 +		{
   1.519 +		User::Leave(KErrPermissionDenied);
   1.520 +		}
   1.521 +
   1.522 +	if (iAudioPolicyPrioritySettings.iState == EMMFStateRecordData)
   1.523 +		{
   1.524 +		if (iHasPolicy)
   1.525 +			{
   1.526 +			if (iCMMFHwDevice)
   1.527 +				{
   1.528 +				TInt err = iCMMFHwDevice->Stop();
   1.529 +				if (err == KErrNone)
   1.530 +					{
   1.531 +					err = iCMMFHwDevice->Start(EDevDecode, EDevOutFlow);
   1.532 +					}
   1.533 +				
   1.534 +				if (err != KErrNone)
   1.535 +					{
   1.536 +					Error(err);
   1.537 +					}
   1.538 +				
   1.539 +				if (iHwDeviceBuffer)
   1.540 +					{
   1.541 +					iHwDeviceBuffer->SetLastBuffer(EFalse);
   1.542 +					}
   1.543 +				}
   1.544 +			}
   1.545 +		
   1.546 +		return;
   1.547 +		}
   1.548 +
   1.549 +	// Get audio policy
   1.550 +	iAudioPolicyPrioritySettings.iState = EMMFStateRecordData;
   1.551 +	RequestPolicy();
   1.552 +	}
   1.553 +
   1.554 +/*
   1.555 + *
   1.556 + *	Plays data in the buffer at the current volume. The client should fill
   1.557 + *	the buffer with audio data before calling this method. The Observer gets
   1.558 + *	reference to buffer along with callback BufferToBeFilled(). When playing of
   1.559 + *	the audio sample is complete, successfully or otherwise, the method
   1.560 + *	PlayError() on observer is called.
   1.561 + *
   1.562 + */
   1.563 +TBool CMMFDevSoundSvrImp::PlayData(const RMmfIpcMessage& aMessage)
   1.564 +	{
   1.565 +	ASSERT(iDevSoundObserver);
   1.566 +
   1.567 +	if (iAudioPolicyPrioritySettings.iState == EMMFStateStopped)
   1.568 +		{
   1.569 +		// Initialisation has been successful but an error (possibly underflow) has occurred
   1.570 +		// which the controller has yet to respond to and that has changed the state to stopped.
   1.571 +		// Allow the call to complete and processing to continue...  
   1.572 +		return ETrue;
   1.573 +		}
   1.574 +
   1.575 +	if((iAudioPolicyPrioritySettings.iState != EMMFStatePlayData) && (iAudioPolicyPrioritySettings.iState != EMMFStatePaused))
   1.576 +		{
   1.577 +		PanicClient(aMessage, EMMFDevSoundPlayDataWithoutInitialize);
   1.578 +		return EFalse;
   1.579 +		}
   1.580 +	if (iMode== EMMFDevSoundStateIdle)
   1.581 +		{
   1.582 +		return ETrue;
   1.583 +		}
   1.584 +	TInt error = KErrNone;
   1.585 +    if(iCMMFHwDevice)
   1.586 +	    {
   1.587 +		if (iPaused)
   1.588 +			{
   1.589 +			iPaused = EFalse;
   1.590 +			//note PlayData does not leave or return an error code so the Start() fails we cannot
   1.591 +			//report the error back at this point
   1.592 +			error = iCMMFHwDevice->Start(EDevDecode, EDevOutFlow);//restart hw device after pause
   1.593 +			}
   1.594 +	   else if ((iMode == EMMFDevSoundStatePlaying) && iHasPolicy)
   1.595 +		    {
   1.596 +		    TInt len = iHwDeviceBuffer->Data().Length();
   1.597 +		    if (iHwDeviceBuffer->LastBuffer())
   1.598 +		    	{
   1.599 +		    	iLastBufferReceived = ETrue;
   1.600 +		    	}
   1.601 +			// Pass the data buffer to HwDevice
   1.602 +			error = iCMMFHwDevice->ThisHwBufferFilled(*iHwDeviceBuffer);
   1.603 +            }
   1.604 +		}
   1.605 +	if (error != KErrNone)
   1.606 +		{
   1.607 +		Error(error);
   1.608 +		if(iCMMFHwDevice)
   1.609 +			{
   1.610 +			iCMMFHwDevice->Stop();	
   1.611 +			}
   1.612 +
   1.613 +		}
   1.614 +	return ETrue;
   1.615 +	}
   1.616 + 
   1.617 +/*
   1.618 + *
   1.619 + *	Stops the ongoing operation (Play, Record, TonePlay, Convert)
   1.620 + *
   1.621 + */
   1.622 +void CMMFDevSoundSvrImp::Stop()
   1.623 +	{
   1.624 +	iPaused = EFalse;
   1.625 +
   1.626 +	if (!iHasPolicy)
   1.627 +		{
   1.628 +		UpdatePolicyState(EMMFStateStopped);
   1.629 +		return;
   1.630 +		}
   1.631 +
   1.632 +	 // Stop the hw device first - this unloads sound drivers
   1.633 +    if (iCMMFHwDevice)
   1.634 +    	{
   1.635 +		iCMMFHwDevice->Stop();
   1.636 +		}
   1.637 +
   1.638 +	iDevSoundEventHandler->CancelReceiveEvents();
   1.639 +
   1.640 +	UpdatePolicyState(EMMFStateStopped);
   1.641 +	__ASSERT_DEBUG(!(iHasPolicy&&(iMode == EMMFDevSoundStatePlaying)), Panic(TMMFDevSoundSessionPolicyNotInvalidated)); 
   1.642 +	}
   1.643 +
   1.644 +/*
   1.645 + *
   1.646 + *	Temporarily Stops the ongoing operation (Play, Record, TonePlay, Convert)
   1.647 + *
   1.648 + */
   1.649 +void CMMFDevSoundSvrImp::Pause()
   1.650 +	{
   1.651 +	iPaused = ETrue;
   1.652 +
   1.653 +	if (!iHasPolicy)
   1.654 +		{
   1.655 +		return;
   1.656 +		}
   1.657 +
   1.658 +	// Pause the HW device first
   1.659 +	if (iCMMFHwDevice)
   1.660 +		{
   1.661 +		iCMMFHwDevice->Pause();
   1.662 +		}
   1.663 +	}
   1.664 +
   1.665 +/*
   1.666 + *
   1.667 + *	Returns the sample recorded so far.
   1.668 + *
   1.669 + *	@return "TInt"
   1.670 + *			Returns the samples recorded.
   1.671 + *
   1.672 + */
   1.673 +TInt CMMFDevSoundSvrImp::SamplesRecorded()
   1.674 +	{
   1.675 +	TInt samples = 0;
   1.676 +	
   1.677 +	if(iRecordCustomInterface)
   1.678 +		{
   1.679 +		samples = iRecordCustomInterface->BytesRecorded();
   1.680 +		if(NumberOfChannels() > 1)
   1.681 +			{
   1.682 +			samples /= NumberOfChannels();
   1.683 +			}
   1.684 +		if(BytesPerAudioSample() > 1)
   1.685 +			{
   1.686 +			samples /= BytesPerAudioSample();
   1.687 +			}
   1.688 +		}
   1.689 +
   1.690 +	return samples;
   1.691 +	}
   1.692 +
   1.693 +/*
   1.694 + *
   1.695 + *	Returns the sample played so far.
   1.696 + *
   1.697 + *	@return "TInt"
   1.698 + *			Returns the samples recorded.
   1.699 + *
   1.700 + */
   1.701 +TInt CMMFDevSoundSvrImp::SamplesPlayed()
   1.702 +	{
   1.703 +	TInt samples = 0;
   1.704 +	if(iPlayCustomInterface)
   1.705 +		{
   1.706 +		TUint bytesPlayed = iPlayCustomInterface->BytesPlayed();
   1.707 +		if (bytesPlayed)
   1.708 +			iPlayedBytesCount = bytesPlayed;
   1.709 +
   1.710 +		samples = iPlayedBytesCount;
   1.711 +		if(NumberOfChannels() > 1)
   1.712 +			samples /= NumberOfChannels();
   1.713 +
   1.714 +		if(BytesPerAudioSample() > 1)
   1.715 +			samples /= BytesPerAudioSample();
   1.716 +		}
   1.717 +	//note always pcm16 becuase the iPlayedBytesCount originates from 
   1.718 +	//RMdaDevSound which is always pcm16
   1.719 +	return samples; //each sample is 2 bytes
   1.720 +	}
   1.721 +
   1.722 +
   1.723 +/*
   1.724 + *
   1.725 + *	Initializes audio device and start playing tone. Tone is played with
   1.726 + *	frequency and for duration specified.
   1.727 + *
   1.728 + *	Leaves on failure.
   1.729 + *
   1.730 + *	@param	"TInt aFrequency"
   1.731 + *			Frequency at with the tone will be played.
   1.732 + *
   1.733 + *	@param	"TTimeIntervalMicroSeconds& aDuration"
   1.734 + *			The period over which the tone will be played. A zero value causes
   1.735 + *			the no tone to be played (Verify this with test app).
   1.736 + *
   1.737 + */
   1.738 +void CMMFDevSoundSvrImp::PlayToneL(TInt aFrequency, const TTimeIntervalMicroSeconds& aDuration)
   1.739 +	{
   1.740 +	if (iMode != EMMFDevSoundStateTonePlaying)
   1.741 +		{
   1.742 +		User::Leave(KErrNotSupported); //tone playing only supported in tone play state
   1.743 +		}
   1.744 +
   1.745 +	// Check whether frequency and duration is valid or not
   1.746 +	TInt64 zeroInt64(0);
   1.747 +	if ((aFrequency<0) || (aDuration.Int64() < zeroInt64))
   1.748 +		{
   1.749 +		User::Leave(KErrArgument);
   1.750 +		}
   1.751 +
   1.752 +	if (!iDevSoundObserver)
   1.753 +		{
   1.754 +		User::Leave(KErrNotReady);
   1.755 +		}
   1.756 +
   1.757 +	iToneGen.SetFrequencyAndDuration(aFrequency,aDuration);
   1.758 +
   1.759 +	// Get audio policy
   1.760 +	iAudioPolicyPrioritySettings.iState = EMMFStatePlayTone;
   1.761 +	RequestPolicy();
   1.762 +	}
   1.763 +
   1.764 +/*
   1.765 + *	Initializes audio device and start playing a dual tone. 
   1.766 + *  The tone consists of two sine waves of different frequencies summed together
   1.767 + *  Dual Tone is played with specified frequencies and for specified duration.
   1.768 + *
   1.769 + *	@param	"aFrequencyOne"
   1.770 + *			First frequency of dual tone
   1.771 + *
   1.772 + *	@param	"aFrequencyTwo"
   1.773 + *			Second frequency of dual tone
   1.774 + *
   1.775 + *	@param	"aDuration"
   1.776 + *			The period over which the tone will be played. A zero value causes
   1.777 + *			the no tone to be played (Verify this with test app).
   1.778 + */
   1.779 +void CMMFDevSoundSvrImp::PlayDualToneL(TInt aFrequencyOne, TInt aFrequencyTwo, const TTimeIntervalMicroSeconds& aDuration)
   1.780 +	{
   1.781 +	if (!iDevSoundObserver)
   1.782 +		{
   1.783 +		User::Leave(KErrNotReady);
   1.784 +		}
   1.785 +	
   1.786 +	// Check whether frequencies and duration are valid or not
   1.787 +	TInt64 zeroInt64(0);
   1.788 +	if ((aFrequencyOne<0) || (aFrequencyTwo<0) || (aDuration.Int64() < zeroInt64))
   1.789 +		{
   1.790 +		iDevSoundObserver->ToneFinished(KErrArgument);
   1.791 +		return;
   1.792 +		}
   1.793 +
   1.794 +
   1.795 +	iDualToneGen.SetFrequencyAndDuration(aFrequencyOne, aFrequencyTwo, aDuration);
   1.796 +
   1.797 +	// Get audio policy
   1.798 +	iAudioPolicyPrioritySettings.iState = EMMFStatePlayDualTone;
   1.799 +	RequestPolicy();
   1.800 +	}
   1.801 +
   1.802 +/*
   1.803 + *
   1.804 + *	Initializes audio device and start playing DTMF string aDTMFString.
   1.805 + *
   1.806 + *	Leaves on failure.
   1.807 + *
   1.808 + *	@param	"TDesC& aDTMFString"
   1.809 + *			DTMF sequence in a descriptor.
   1.810 + *
   1.811 + */
   1.812 +void CMMFDevSoundSvrImp::PlayDTMFStringL(const TDesC& aDTMFString)
   1.813 +	{
   1.814 +	if (!iDevSoundObserver)
   1.815 +		User::Leave(KErrNotReady);
   1.816 +
   1.817 +	if (iMode!= EMMFDevSoundStateTonePlaying)
   1.818 +		User::Leave(KErrNotSupported); //tone playing only supported in tone play state
   1.819 +
   1.820 +	iDTMFGen.SetString(aDTMFString);
   1.821 +
   1.822 +	// Get audio policy
   1.823 +	iAudioPolicyPrioritySettings.iState = EMMFStatePlayDTMFString;
   1.824 +	RequestPolicy();
   1.825 +	}
   1.826 +
   1.827 +/*
   1.828 + *
   1.829 + *	Initializes audio device and start playing tone sequence.
   1.830 + *
   1.831 + *	Leaves on failure.
   1.832 + *
   1.833 + *	@param	"TDesC8& aData"
   1.834 + *			Tone sequence in a descriptor.
   1.835 + *
   1.836 + */
   1.837 +void CMMFDevSoundSvrImp::PlayToneSequenceL(const TDesC8& aData)
   1.838 +	{
   1.839 +	if (!iDevSoundObserver)
   1.840 +		User::Leave(KErrNotReady);
   1.841 +
   1.842 +	if (iMode!= EMMFDevSoundStateTonePlaying)
   1.843 +		User::Leave(KErrNotSupported); //tone playing only supported in tone play state
   1.844 +
   1.845 +	// Check whether the sequence is valid or not
   1.846 +	if (!iDevSoundUtil->RecognizeSequence(aData))
   1.847 +		User::Leave(KErrCorrupt);
   1.848 +
   1.849 +	iSequenceGen.SetSequenceData(aData);
   1.850 +
   1.851 +	// Get audio policy
   1.852 +	iAudioPolicyPrioritySettings.iState = EMMFStatePlayToneSequence;
   1.853 +	RequestPolicy();
   1.854 +	}
   1.855 +
   1.856 +/*
   1.857 + *
   1.858 + *	Initializes audio device and start playing the specified pre-defined tone
   1.859 + *	sequence.
   1.860 + *
   1.861 + *	Leaves on failure.
   1.862 + *
   1.863 + *	@param	"TInt aSequenceNumber"
   1.864 + *			The index identifying the specific pre-defined tone sequence. Index
   1.865 + *			values are relative to zero.
   1.866 + *			This can be any value from zero to the value returned by a call to
   1.867 + *			FixedSequenceCount() - 1.
   1.868 + *			The function raises a panic if sequence number is not within this
   1.869 + *			range.
   1.870 + *
   1.871 + *	@see	FixesSequenceCount()
   1.872 + *
   1.873 + */
   1.874 +void CMMFDevSoundSvrImp::PlayFixedSequenceL(TInt aSequenceNumber)
   1.875 +	{
   1.876 +	if (!iDevSoundObserver)
   1.877 +		User::Leave(KErrNotReady);
   1.878 +
   1.879 +	if (iMode!= EMMFDevSoundStateTonePlaying)
   1.880 +		User::Leave(KErrNotSupported); //tone playing only supported in tone play state
   1.881 +
   1.882 +	ASSERT((aSequenceNumber >= 0)&&(aSequenceNumber < iFixedSequences->Count()));
   1.883 +
   1.884 +	iFixedSequence.Set(iFixedSequences->MdcaPoint(aSequenceNumber));
   1.885 +	iSequenceGen.SetSequenceData(iFixedSequence);
   1.886 +
   1.887 +	// Get audio policy
   1.888 +	iAudioPolicyPrioritySettings.iState = EMMFStatePlayToneSequence;
   1.889 +	RequestPolicy();
   1.890 +	}
   1.891 +
   1.892 +/*
   1.893 + *
   1.894 + *	Defines the duration of tone on, tone off and tone pause to be used during the
   1.895 + *	DTMF tone playback operation.
   1.896 + *
   1.897 + *	Supported only during tone playing.
   1.898 + *
   1.899 + *	@param	"TTimeIntervalMicroSeconds32& aToneOnLength"
   1.900 + *			The period over which the tone will be played. If this is set to
   1.901 + *			zero, then the tone is not played.
   1.902 + *
   1.903 + *	@param	"TTimeIntervalMicroSeconds32& aToneOffLength"
   1.904 + *			The period over which the no tone will be played.
   1.905 + *
   1.906 + *	@param	"TTimeIntervalMicroSeconds32& aPauseLength"
   1.907 + *			The period over which the tone playing will be paused.
   1.908 + *
   1.909 + */
   1.910 +void CMMFDevSoundSvrImp::SetDTMFLengths(TTimeIntervalMicroSeconds32& aToneOnLength,
   1.911 +								TTimeIntervalMicroSeconds32& aToneOffLength,
   1.912 +								TTimeIntervalMicroSeconds32& aPauseLength) 
   1.913 +	{
   1.914 +
   1.915 +	if(aToneOnLength.Int() < KMdaInfiniteDurationDTMFToneOnLength)
   1.916 +		aToneOnLength = TTimeIntervalMicroSeconds32(0);
   1.917 +	if(aToneOffLength.Int() < 0)
   1.918 +		aToneOffLength = TTimeIntervalMicroSeconds32(0);
   1.919 +	if(aPauseLength.Int() < 0)
   1.920 +		aPauseLength = TTimeIntervalMicroSeconds32(0);
   1.921 +
   1.922 +	iDTMFGen.SetToneDurations(aToneOnLength,aToneOffLength,aPauseLength);
   1.923 +	}
   1.924 +
   1.925 +/*
   1.926 + *
   1.927 + *	Defines the period over which the volume level is to rise smoothly from
   1.928 + *	nothing to the normal volume level.
   1.929 + *
   1.930 + *	@param	"TTimeIntervalMicroSeconds& aRampDuration"
   1.931 + *			The period over which the volume is to rise. A zero value causes 
   1.932 + *			the tone sample to be played at the normal level for the full
   1.933 + *			duration of the playback. A value, which is longer than the duration
   1.934 + *			of the tone sample, that the sample never reaches its normal
   1.935 + *			volume level.
   1.936 + *
   1.937 + *
   1.938 + */
   1.939 +void CMMFDevSoundSvrImp::SetVolumeRamp(const TTimeIntervalMicroSeconds& aRampDuration)
   1.940 +	{
   1.941 +	// save ramp duration for tone generator
   1.942 +	iRampDuration = aRampDuration;
   1.943 +
   1.944 +	SetDeviceVolumeRamp(iRampDuration);
   1.945 +	}
   1.946 +
   1.947 +/**
   1.948 + *	Sets volume ramp on HwDevice.
   1.949 + */
   1.950 +TInt CMMFDevSoundSvrImp::SetDeviceVolumeRamp(const TTimeIntervalMicroSeconds& aRampDuration)
   1.951 +	{
   1.952 +	TInt error = KErrNone;
   1.953 +	if (iPlayCustomInterface) 
   1.954 +		iPlayCustomInterface->SetVolumeRamp(aRampDuration);
   1.955 +	else
   1.956 +		error = KErrNotReady;
   1.957 +	return error;
   1.958 +    }
   1.959 +
   1.960 +/**
   1.961 + *	@see sounddevice.h
   1.962 + */
   1.963 +void CMMFDevSoundSvrImp::GetSupportedInputDataTypesL(RArray<TFourCC>& aSupportedDataTypes, const TMMFPrioritySettings& /*aPrioritySettings*/) const
   1.964 +	{
   1.965 +	//aPrioritySettings not used on ref DevSound
   1.966 +	//search for playing datatypes
   1.967 +	iDevSoundUtil->SeekHwDevicePluginsL(aSupportedDataTypes, EMMFStatePlaying);
   1.968 +#ifdef SYMBIAN_MULTIMEDIA_CODEC_API
   1.969 +	// append list of codec plugins
   1.970 +	iDevSoundUtil->SeekCodecPluginsL(aSupportedDataTypes, EMMFStatePlaying, ETrue);
   1.971 +#endif // SYMBIAN_MULTIMEDIA_CODEC_API
   1.972 +	}
   1.973 +
   1.974 +/**
   1.975 + *	@see sounddevice.h
   1.976 + */
   1.977 +void CMMFDevSoundSvrImp::GetSupportedOutputDataTypesL(RArray<TFourCC>& aSupportedDataTypes, const TMMFPrioritySettings& /*aPrioritySettings*/) const
   1.978 +	{
   1.979 +	//aPrioritySettings not used on ref DevSound
   1.980 +	// search for recording datatypes
   1.981 +	iDevSoundUtil->SeekHwDevicePluginsL(aSupportedDataTypes, EMMFStateRecording);
   1.982 +#ifdef SYMBIAN_MULTIMEDIA_CODEC_API
   1.983 +	// append list of codec plugins
   1.984 +	iDevSoundUtil->SeekCodecPluginsL(aSupportedDataTypes, EMMFStateRecording, ETrue);
   1.985 +#endif // SYMBIAN_MULTIMEDIA_CODEC_API
   1.986 +	}
   1.987 +	
   1.988 +TInt CMMFDevSoundSvrImp::RegisterAsClient(TUid aEventType, const TDesC8& aNotificationRegistrationData)
   1.989 +	{	
   1.990 +	return iAudioPolicyProxy->RequestResourceNotification(aEventType,aNotificationRegistrationData);
   1.991 +	}
   1.992 +	
   1.993 +TInt CMMFDevSoundSvrImp::CancelRegisterAsClient(TUid aEventType)
   1.994 +	{	
   1.995 +	return iAudioPolicyProxy->CancelRequestResourceNotification(aEventType);
   1.996 +	}
   1.997 +
   1.998 +TInt CMMFDevSoundSvrImp::GetResourceNotificationData(TUid aEventType, TDes8& aNotificationData)
   1.999 +	{	
  1.1000 +	TInt err = KErrNone;
  1.1001 +	err = iAudioPolicyProxy->IsRegisteredResourceNotification(aEventType);
  1.1002 +	if(err == KErrNone)
  1.1003 +		{
  1.1004 +		TMMFTimeIntervalMicroSecondsPckg pckg = TTimeIntervalMicroSeconds(SamplesPlayed());
  1.1005 +		aNotificationData.Copy(pckg);
  1.1006 +		}
  1.1007 +	return err;
  1.1008 +	}
  1.1009 +	
  1.1010 +TInt CMMFDevSoundSvrImp::WillResumePlay()
  1.1011 +	{
  1.1012 +	return iAudioPolicyProxy->StopNotification();
  1.1013 +	}	
  1.1014 +	
  1.1015 +TInt CMMFDevSoundSvrImp::EmptyBuffers()
  1.1016 +	{
  1.1017 +	TInt err = KErrNone;
  1.1018 +	if (iMode != EMMFStatePlaying)
  1.1019 +		{
  1.1020 +		return KErrNotSupported;
  1.1021 +		}
  1.1022 +	if (!iCMMFHwDevice)
  1.1023 +		{
  1.1024 +		return KErrNotReady;			
  1.1025 +		}	
  1.1026 +	MEmptyBuffersCustomInterface* emptybuffers = reinterpret_cast<MEmptyBuffersCustomInterface*>(iCMMFHwDevice->CustomInterface(KEmptyBuffersCustomInterfaceTypeUid));	
  1.1027 +	if (emptybuffers)
  1.1028 +    	{
  1.1029 +       	err = emptybuffers->EmptyBuffers();
  1.1030 +     	}
  1.1031 +    else
  1.1032 +		{
  1.1033 +     	err = KErrNotSupported;
  1.1034 +     	}
  1.1035 +    return err;	
  1.1036 +	}	
  1.1037 +
  1.1038 +TInt CMMFDevSoundSvrImp::GetTimePlayed(TTimeIntervalMicroSeconds& aTime)
  1.1039 +	{
  1.1040 +	TInt err = KErrNone;
  1.1041 +	TTimeIntervalMicroSeconds time(0);
  1.1042 +	if(iCMMFHwDevice)
  1.1043 +		{
  1.1044 +		if(!iTimePlayedCustomInterface)
  1.1045 +			{
  1.1046 +			iTimePlayedCustomInterface = reinterpret_cast<MTimePlayedCustomInterface*>(iCMMFHwDevice->CustomInterface(KTimePlayedCustomInterfaceTypeUid));
  1.1047 +			if(iTimePlayedCustomInterface == NULL)
  1.1048 +				{
  1.1049 +				return KErrNotSupported;
  1.1050 +				}
  1.1051 +			}
  1.1052 +		err = iTimePlayedCustomInterface->GetTimePlayed(time);
  1.1053 +	    if(err == KErrNone && time.Int64() > 0)
  1.1054 +	    	{
  1.1055 +	    	iTimePlayed = time.Int64();
  1.1056 +	    	}
  1.1057 +		}
  1.1058 +	aTime = iTimePlayed.Int64();
  1.1059 +	return err;
  1.1060 +	}
  1.1061 +
  1.1062 +/********************************************************************************
  1.1063 + *				Implementations of Non Exported public functions begins here	*
  1.1064 + ********************************************************************************/
  1.1065 +
  1.1066 +//
  1.1067 +//				Audio Policy specific implementation begins here				//
  1.1068 +//
  1.1069 +
  1.1070 +/*
  1.1071 + *
  1.1072 + *	Called by Audio Policy Server when a request to play is approved by the 
  1.1073 + *	Audio Policy Server.
  1.1074 + *
  1.1075 + *	Leaves on failure??.
  1.1076 + *
  1.1077 + */
  1.1078 +void CMMFDevSoundSvrImp::StartPlayDataL()
  1.1079 +	{
  1.1080 +	ASSERT(iMode== EMMFDevSoundStatePlaying);
  1.1081 +	if(iAudioPolicyPrioritySettings.iState == EMMFStateStopped)
  1.1082 +		{
  1.1083 +		return;
  1.1084 +		}
  1.1085 +	iHasPolicy = ETrue;
  1.1086 +
  1.1087 +	TInt error = KErrNone;
  1.1088 +
  1.1089 +	if(iCMMFHwDevice)
  1.1090 +		{
  1.1091 +		UpdatePolicyState(EMMFStatePlayData);		
  1.1092 +        // Set volume and play format values
  1.1093 +        error = SetPlayFormat(iPlayFormat);
  1.1094 +        if (error == KErrNone)
  1.1095 +			error = SetDeviceVolume(iVolume);
  1.1096 +        if (error == KErrNone)
  1.1097 +			error = SetDeviceVolumeRamp(iRampDuration);
  1.1098 +
  1.1099 +		// Initialize attribute values
  1.1100 +		iPlayedBytesCount = 0;
  1.1101 +		iTimePlayed = 0;
  1.1102 +		iLastBufferReceived = EFalse;
  1.1103 +
  1.1104 +        // Start HwDevice
  1.1105 +        if (error == KErrNone)
  1.1106 +	        error = iCMMFHwDevice->Start(EDevDecode, EDevOutFlow);
  1.1107 +		}
  1.1108 +	else
  1.1109 +		error = KErrNotReady;
  1.1110 +	
  1.1111 +	if (error != KErrNone)
  1.1112 +		{
  1.1113 +		Error(error);
  1.1114 +
  1.1115 +		}
  1.1116 +	}
  1.1117 +
  1.1118 +/*
  1.1119 + *
  1.1120 + *	Called by Audio Policy Server when a request to record is approved by the 
  1.1121 + *	Audio Policy Server.
  1.1122 + *
  1.1123 + *	Leaves on failure.
  1.1124 + *
  1.1125 + */
  1.1126 +void CMMFDevSoundSvrImp::StartRecordDataL()
  1.1127 +	{
  1.1128 +	ASSERT(iMode== EMMFDevSoundStateRecording);
  1.1129 +	if(iAudioPolicyPrioritySettings.iState == EMMFStateStopped)
  1.1130 +		{
  1.1131 +		return;
  1.1132 +		}
  1.1133 +	iHasPolicy = ETrue;
  1.1134 +
  1.1135 +	 if(iCMMFHwDevice)
  1.1136 +		{
  1.1137 +		UpdatePolicyState(EMMFStateRecordData);
  1.1138 +        TInt error = KErrNone;
  1.1139 +        error = SetRecordFormat(iRecordFormat);
  1.1140 +		if (error != KErrNone)
  1.1141 +			{
  1.1142 +			Error(error);
  1.1143 +			return;
  1.1144 +
  1.1145 +			}
  1.1146 +        error = SetDeviceRecordLevel(iGain);
  1.1147 +		if (error != KErrNone)
  1.1148 +			{
  1.1149 +			Error(error);
  1.1150 +			return;
  1.1151 +
  1.1152 +			}
  1.1153 +        error = iCMMFHwDevice->Start(EDevEncode, EDevInFlow);
  1.1154 +		if (iHwDeviceBuffer)
  1.1155 +			iHwDeviceBuffer->SetLastBuffer(EFalse);
  1.1156 +
  1.1157 +		if (error != KErrNone)
  1.1158 +			{
  1.1159 +			Error(error);
  1.1160 +			return;
  1.1161 +			}
  1.1162 +        }
  1.1163 +	else
  1.1164 +		iDevSoundObserver->RecordError(KErrNotReady);
  1.1165 +	}
  1.1166 +
  1.1167 +/*
  1.1168 + *
  1.1169 + *	Called by Audio Policy Server when a request to play tone is approved by
  1.1170 + *	the Audio Policy Server.
  1.1171 + *
  1.1172 + *	Leaves on failure.
  1.1173 + *
  1.1174 + */
  1.1175 +void CMMFDevSoundSvrImp::StartPlayToneL()
  1.1176 +	{
  1.1177 +	ASSERT(iMode == EMMFDevSoundStateTonePlaying);
  1.1178 +	if(iAudioPolicyPrioritySettings.iState == EMMFStateStopped)
  1.1179 +		{
  1.1180 +		return;
  1.1181 +		}
  1.1182 +	iHasPolicy = ETrue;
  1.1183 +	
  1.1184 +	if(iCMMFHwDevice)
  1.1185 +		{
  1.1186 +		UpdatePolicyState(EMMFStatePlayTone);
  1.1187 +        TInt error = KErrNone;
  1.1188 +        // Set volume and play format values
  1.1189 +        error = SetPlayFormat(iPlayFormat);
  1.1190 +		if (error != KErrNone)
  1.1191 +			{
  1.1192 +			Error(error);
  1.1193 +			return;
  1.1194 +
  1.1195 +			}
  1.1196 +        if (iHwDeviceID.iUid == KMmfUidHwDevicePCM16ToPCM16)
  1.1197 +            error = SetDeviceVolume(iVolume);
  1.1198 +		else
  1.1199 +			error = KErrGeneral;//hw device should always be pcm16 for tone
  1.1200 +
  1.1201 +		// turn off volume ramping - this is done in software below
  1.1202 +        if (error == KErrNone)
  1.1203 +			error = SetDeviceVolumeRamp(TTimeIntervalMicroSeconds(0));
  1.1204 +
  1.1205 +        if (error != KErrNone)
  1.1206 +            {
  1.1207 +            Error(error);
  1.1208 +            return;
  1.1209 +
  1.1210 +            }
  1.1211 +
  1.1212 +        // Initialize attribute values
  1.1213 +		iPlayedBytesCount = 0;
  1.1214 +		iTimePlayed = 0;
  1.1215 +        // Configure tone generator
  1.1216 +        iToneGen.Configure(
  1.1217 +			iPlayFormat().iRate,
  1.1218 +			iPlayFormat().iChannels,
  1.1219 +		    iRepeatCount,
  1.1220 +			I64LOW((iRepeatTrailingSilence.Int64()*iPlayFormat().iRate)/1000000),
  1.1221 +			I64LOW((iRampDuration.Int64()*iPlayFormat().iRate)/1000000)
  1.1222 +			);
  1.1223 +
  1.1224 +		iCurrentGenerator = &iToneGen;
  1.1225 +
  1.1226 +        // Start playback
  1.1227 +        DoPlayL();
  1.1228 +		}
  1.1229 +	else
  1.1230 +		iDevSoundObserver->ToneFinished(KErrNotReady);
  1.1231 +	}
  1.1232 +
  1.1233 +/*
  1.1234 + *
  1.1235 + *	Called by Audio Policy Server when a request to play a dual tone is approved by
  1.1236 + *	the Audio Policy Server.
  1.1237 + *
  1.1238 + */
  1.1239 +void CMMFDevSoundSvrImp::StartPlayDualToneL()
  1.1240 +	{
  1.1241 +	ASSERT(iMode == EMMFDevSoundStateTonePlaying);
  1.1242 +	if(iAudioPolicyPrioritySettings.iState == EMMFStateStopped)
  1.1243 +		{
  1.1244 +		return;
  1.1245 +		}
  1.1246 +	iHasPolicy = ETrue;
  1.1247 +
  1.1248 +	 if(iCMMFHwDevice)
  1.1249 +		{
  1.1250 +		UpdatePolicyState(EMMFStatePlayDualTone);
  1.1251 +        TInt error = KErrNone;
  1.1252 +        // Set volume and play format values
  1.1253 +        error = SetPlayFormat(iPlayFormat);
  1.1254 +		if (error != KErrNone)
  1.1255 +			{
  1.1256 +			Error(error);
  1.1257 +			return;
  1.1258 +			}
  1.1259 +        if (iHwDeviceID.iUid == KMmfUidHwDevicePCM16ToPCM16)
  1.1260 +            error = SetDeviceVolume(iVolume);
  1.1261 +		else 
  1.1262 +			error = KErrGeneral;//hw device should always be pcm16 for tone
  1.1263 +
  1.1264 +		// turn off volume ramping - this is done in software below
  1.1265 +        if (error == KErrNone)
  1.1266 +			error = SetDeviceVolumeRamp(TTimeIntervalMicroSeconds(0));
  1.1267 +
  1.1268 +        if (error != KErrNone)
  1.1269 +            {
  1.1270 +            Error(error);
  1.1271 +            return;
  1.1272 +
  1.1273 +            }
  1.1274 +
  1.1275 +        // Initialize attribute values
  1.1276 +		iPlayedBytesCount = 0;
  1.1277 +		iTimePlayed = 0;
  1.1278 +        // Configure dual tone generator
  1.1279 +		iDualToneGen.Configure(
  1.1280 +			iPlayFormat().iRate,
  1.1281 +			iPlayFormat().iChannels,
  1.1282 +			iRepeatCount,
  1.1283 +			I64LOW((iRepeatTrailingSilence.Int64()*iPlayFormat().iRate)/KOneMillionMicroSeconds),
  1.1284 +			I64LOW((iRampDuration.Int64()*iPlayFormat().iRate)/KOneMillionMicroSeconds)
  1.1285 +			);
  1.1286 +
  1.1287 +		iCurrentGenerator = &iDualToneGen;
  1.1288 +
  1.1289 +        // Start playback
  1.1290 +        DoPlayL();
  1.1291 +		}
  1.1292 +	else
  1.1293 +		iDevSoundObserver->ToneFinished(KErrNotReady);
  1.1294 +	}
  1.1295 +
  1.1296 +/*
  1.1297 + *
  1.1298 + *	Called by Audio Policy Server when a request to play DTMF String is approved
  1.1299 + *	by the Audio Policy Server.
  1.1300 + *
  1.1301 + *	Leaves on failure.
  1.1302 + *
  1.1303 + */
  1.1304 +void CMMFDevSoundSvrImp::StartPlayDTMFStringL()
  1.1305 +	{
  1.1306 +	ASSERT(iMode == EMMFDevSoundStateTonePlaying);
  1.1307 +	if(iAudioPolicyPrioritySettings.iState == EMMFStateStopped)
  1.1308 +		{
  1.1309 +		return;
  1.1310 +		}
  1.1311 +	iHasPolicy = ETrue;
  1.1312 +
  1.1313 +	if(iCMMFHwDevice)
  1.1314 +		{
  1.1315 +		UpdatePolicyState(EMMFStatePlayDTMFString);
  1.1316 +        TInt error = KErrNone;
  1.1317 +        // Set volume and play format values
  1.1318 +        error = SetPlayFormat(iPlayFormat);
  1.1319 +		if (error != KErrNone)
  1.1320 +            {
  1.1321 +            Error(error);
  1.1322 +            return;
  1.1323 +
  1.1324 +            }
  1.1325 +        error = SetDeviceVolume(iVolume);
  1.1326 +
  1.1327 +		// turn off volume ramping - this is done in software below
  1.1328 +        if (error == KErrNone)
  1.1329 +			error = SetDeviceVolumeRamp(TTimeIntervalMicroSeconds(0));
  1.1330 +
  1.1331 +        if (error != KErrNone)
  1.1332 +            {
  1.1333 +            Error(error);
  1.1334 +            return;
  1.1335 +            }
  1.1336 +
  1.1337 +        // Initialize attribute values
  1.1338 +		iPlayedBytesCount = 0;
  1.1339 +		iTimePlayed = 0;
  1.1340 +	    iDTMFGen.Configure(
  1.1341 +			iPlayFormat().iRate,
  1.1342 +			iPlayFormat().iChannels,
  1.1343 +		    iRepeatCount,
  1.1344 +			I64LOW((iRepeatTrailingSilence.Int64()*iPlayFormat().iRate)/1000000),
  1.1345 +		    I64LOW((iRampDuration.Int64()*iPlayFormat().iRate)/1000000)
  1.1346 +			);
  1.1347 +
  1.1348 +		iCurrentGenerator = &iDTMFGen;
  1.1349 +
  1.1350 +        // Start playback
  1.1351 +		//need to trap this as we can leave with KErrUnderflow
  1.1352 +		//if there was no data to play - the error has already
  1.1353 +		//been sent to the observer and we don't want to call RunError
  1.1354 +        TRAP(error,DoPlayL());
  1.1355 +		if ((error != KErrUnderflow)&&(error != KErrNone))
  1.1356 +			{
  1.1357 +			User::Leave(error);
  1.1358 +			}
  1.1359 +		}
  1.1360 +	else
  1.1361 +		iDevSoundObserver->ToneFinished(KErrNotReady);
  1.1362 +	}
  1.1363 +
  1.1364 +/*
  1.1365 + *
  1.1366 + *	Called by Audio Policy Server when a request to play tone sequence is
  1.1367 + *	approved by the Audio Policy Server.
  1.1368 + *
  1.1369 + *	Leaves on failure.
  1.1370 + *
  1.1371 + */
  1.1372 +void CMMFDevSoundSvrImp::StartPlayToneSequenceL()
  1.1373 +	{
  1.1374 +	ASSERT(iMode == EMMFDevSoundStateTonePlaying);
  1.1375 +	if(iAudioPolicyPrioritySettings.iState == EMMFStateStopped)
  1.1376 +		{
  1.1377 +		return;
  1.1378 +		}
  1.1379 +	iHasPolicy = ETrue;
  1.1380 +
  1.1381 +	if(iCMMFHwDevice)
  1.1382 +		{
  1.1383 +		UpdatePolicyState(EMMFStatePlayToneSequence);
  1.1384 +        TInt error = KErrNone;
  1.1385 +        // Set volume and play format values
  1.1386 +        if (iHwDeviceID.iUid == KMmfUidHwDevicePCM16ToPCM16)
  1.1387 +            error = SetPlayFormat(iPlayFormat);
  1.1388 +			else error = KErrGeneral;//hw device should always be pcm16 for tone
  1.1389 +		if (error != KErrNone)
  1.1390 +            {
  1.1391 +            Error(error);
  1.1392 +            return;
  1.1393 +            }
  1.1394 +
  1.1395 +        if (iHwDeviceID.iUid == KMmfUidHwDevicePCM16ToPCM16)
  1.1396 +            error = SetDeviceVolume(iVolume);
  1.1397 +		else 
  1.1398 +			error = KErrGeneral;//hw device should always be pcm16 for tone
  1.1399 +
  1.1400 +		// turn off volume ramping - this is done in software below
  1.1401 +        if (error == KErrNone)
  1.1402 +			error = SetDeviceVolumeRamp(TTimeIntervalMicroSeconds(0));
  1.1403 +
  1.1404 +        if (error != KErrNone)
  1.1405 +            {
  1.1406 +            Error(error);
  1.1407 +            return;
  1.1408 +            }
  1.1409 +
  1.1410 +        // Initialize attribute values
  1.1411 +		iPlayedBytesCount = 0;
  1.1412 +		iTimePlayed = 0;
  1.1413 +		iSequenceGen.Configure(
  1.1414 +			iPlayFormat().iRate,
  1.1415 +			iPlayFormat().iChannels,
  1.1416 +			iRepeatCount,
  1.1417 +			I64LOW((iRepeatTrailingSilence.Int64()*iPlayFormat().iRate)/1000000),
  1.1418 +			I64LOW((iRampDuration.Int64()*iPlayFormat().iRate)/1000000)
  1.1419 +			);
  1.1420 +
  1.1421 +		iCurrentGenerator = &iSequenceGen;
  1.1422 +
  1.1423 +        // Start playback
  1.1424 +        DoPlayL();
  1.1425 +		}
  1.1426 +	else
  1.1427 +		iDevSoundObserver->ToneFinished(KErrNotReady);
  1.1428 +	}
  1.1429 +
  1.1430 +/*
  1.1431 + *
  1.1432 + *	Called by Audio Policy Server when the current DevSound instance looses the
  1.1433 + *	policy because of another instance with a higher priority wants the device.
  1.1434 + *
  1.1435 + */
  1.1436 +void CMMFDevSoundSvrImp::SendEventToClient(const TMMFEvent& aEvent)
  1.1437 +	{
  1.1438 +	if (aEvent.iErrorCode != KErrNone)
  1.1439 +		{
  1.1440 +		iHasPolicy = EFalse;
  1.1441 +		if (iMode == EMMFDevSoundStatePlaying)
  1.1442 +			{
  1.1443 +			UpdateBytesPlayed();
  1.1444 +			iDevSoundObserver->PlayError(aEvent.iErrorCode);
  1.1445 +			UpdatePolicyState(EMMFStateStopped);
  1.1446 +			}
  1.1447 +		else if (iMode == EMMFDevSoundStateRecording)
  1.1448 +			{
  1.1449 +			iDevSoundObserver->RecordError(aEvent.iErrorCode);
  1.1450 +			UpdatePolicyState(EMMFStateStopped);
  1.1451 +			}
  1.1452 +		else if (iMode == EMMFDevSoundStateTonePlaying)
  1.1453 +			{
  1.1454 +			iDevSoundObserver->ToneFinished(aEvent.iErrorCode);
  1.1455 +			}			
  1.1456 +		iCMMFHwDevice->Stop();//unloads sound device
  1.1457 +		// Have audio Policy launch higher priority request
  1.1458 +		iAudioPolicyProxy->LaunchRequests();
  1.1459 +		}
  1.1460 +	else
  1.1461 +		{
  1.1462 +		iHasPolicy = ETrue;
  1.1463 +		iDevSoundObserver->SendEventToClient(aEvent);
  1.1464 +		}
  1.1465 +	}
  1.1466 +
  1.1467 +
  1.1468 +/**
  1.1469 + *
  1.1470 + *	Sets volume on HwDevice.
  1.1471 + *	
  1.1472 + *	@return	"TInt"
  1.1473 + *			Error value returned by HwDevice.
  1.1474 + *
  1.1475 + */
  1.1476 +TInt CMMFDevSoundSvrImp::SetDeviceVolume(TInt aVolume)
  1.1477 +	{
  1.1478 +	TInt error = KErrNone;
  1.1479 +	if (iPlayCustomInterface) 
  1.1480 +		iPlayCustomInterface->SetVolume(aVolume);
  1.1481 +	else error = KErrNotReady;
  1.1482 +	return error;
  1.1483 +    }
  1.1484 +
  1.1485 +/**
  1.1486 + *
  1.1487 + *	Sets PlayFormat on HwDevice.
  1.1488 + *	
  1.1489 + *
  1.1490 + *	@return	"TInt"
  1.1491 + *			Error value returned by HwDevice.
  1.1492 + *
  1.1493 + */
  1.1494 +TInt CMMFDevSoundSvrImp::SetPlayFormat(RMdaDevSound::TCurrentSoundFormatBuf& aPlayFormat)
  1.1495 +	{
  1.1496 +	TInt error = KErrNone;
  1.1497 +	if (iCMMFHwDevice)
  1.1498 +		{
  1.1499 +		TTaskConfig taskConfig;
  1.1500 +		taskConfig.iUid = KUidRefDevSoundTaskConfig;
  1.1501 +		taskConfig.iRate = aPlayFormat().iRate;
  1.1502 +		
  1.1503 +		if (aPlayFormat().iChannels == 1)
  1.1504 +			{
  1.1505 +			taskConfig.iStereoMode = ETaskMono;
  1.1506 +			}
  1.1507 +		else if (aPlayFormat().iChannels == 2)
  1.1508 +			{
  1.1509 +			taskConfig.iStereoMode = ETaskInterleaved;
  1.1510 +			}
  1.1511 +		else
  1.1512 +			{
  1.1513 +			return KErrArgument;
  1.1514 +			}
  1.1515 +
  1.1516 +		error = iCMMFHwDevice->SetConfig(taskConfig);
  1.1517 +		//note the iEncoding and iBufferSize are already determined by the 
  1.1518 +		//CMMFHwDevice plugin and so are not set.
  1.1519 +		}
  1.1520 +	else
  1.1521 +		{
  1.1522 +		error = KErrNotReady;
  1.1523 +		}
  1.1524 +	return error;
  1.1525 +    }
  1.1526 +
  1.1527 +
  1.1528 +/**
  1.1529 + *
  1.1530 + *	Sets RecordFormat on HwDevice.
  1.1531 + *	
  1.1532 + *
  1.1533 + *	@return	"TInt"
  1.1534 + *			Error value returned by HwDevice.
  1.1535 + *
  1.1536 + */
  1.1537 +TInt CMMFDevSoundSvrImp::SetRecordFormat(RMdaDevSound::TCurrentSoundFormatBuf& aRecordFormat)
  1.1538 +	{
  1.1539 +	TInt error = KErrNone;
  1.1540 +	if (iCMMFHwDevice)
  1.1541 +		{
  1.1542 +		TTaskConfig taskConfig;
  1.1543 +		taskConfig.iUid = KUidRefDevSoundTaskConfig;
  1.1544 +		taskConfig.iRate = aRecordFormat().iRate;
  1.1545 +
  1.1546 +		if (aRecordFormat().iChannels == 1)
  1.1547 +			{
  1.1548 +			taskConfig.iStereoMode = ETaskMono;
  1.1549 +			}
  1.1550 +		else if (aRecordFormat().iChannels == 2)
  1.1551 +			{
  1.1552 +			taskConfig.iStereoMode = ETaskInterleaved;
  1.1553 +			}
  1.1554 +		else
  1.1555 +			{
  1.1556 +			return KErrArgument;
  1.1557 +			}
  1.1558 +
  1.1559 +		error = iCMMFHwDevice->SetConfig(taskConfig);
  1.1560 +		//note the iEncoding and iBufferSize are already determined by the 
  1.1561 +		//CMMFHwDevice plugin and so are not set.
  1.1562 +		}
  1.1563 +	else
  1.1564 +		{
  1.1565 +		error = KErrNotReady;
  1.1566 +		}
  1.1567 +	return error;
  1.1568 +    }
  1.1569 +
  1.1570 +
  1.1571 +/**
  1.1572 + *
  1.1573 + *	Sets record level on HwDevice.
  1.1574 + *	
  1.1575 + *
  1.1576 + *	@return	"TInt"
  1.1577 + *			Error value returned by HwDevice.
  1.1578 + *
  1.1579 + */
  1.1580 +TInt CMMFDevSoundSvrImp::SetDeviceRecordLevel(TInt aGain)
  1.1581 +	{
  1.1582 +	TInt error = KErrNone;
  1.1583 +	if (iRecordCustomInterface) 
  1.1584 +		iRecordCustomInterface->SetGain(aGain);
  1.1585 +	else error = KErrNotReady;
  1.1586 +	return error;
  1.1587 +
  1.1588 +    }
  1.1589 +
  1.1590 +
  1.1591 +/**
  1.1592 + *
  1.1593 + *	MMMFHwDeviceObserver mixin implementation.
  1.1594 + *
  1.1595 + *	The CMMFHwDevice implementation object calls this method during decoding
  1.1596 + *	(playing), when it needs the encoded data in the buffer
  1.1597 + *	aHwDataBuffer.
  1.1598 + *
  1.1599 + *	@return	"TInt"
  1.1600 + *			Error code. KErrNone if success.
  1.1601 + *
  1.1602 + */
  1.1603 +TInt CMMFDevSoundSvrImp::FillThisHwBuffer(CMMFBuffer& aHwDataBuffer)
  1.1604 +	{
  1.1605 +	TInt err = KErrNone;
  1.1606 +    // Keep a reference to this Hw data Buffer. We need to send the 
  1.1607 +	// reference back to HwDevice implementation
  1.1608 +	iHwDeviceBuffer = static_cast<CMMFDataBuffer*> (&aHwDataBuffer);
  1.1609 +	// Set the request length, From HwDevice this comes with buffer
  1.1610 +	// length.
  1.1611 +	TInt len = iHwDeviceBuffer->Data().MaxLength();
  1.1612 +	// Ignore error. since buffer size = Buffer Length 
  1.1613 +	TRAP(err, iHwDeviceBuffer->SetRequestSizeL(len));
  1.1614 +
  1.1615 +	if (iMode== EMMFDevSoundStatePlaying) // Get Data from Observer
  1.1616 +		{
  1.1617 +		if (iLastBufferReceived)
  1.1618 +			{
  1.1619 +			iHwDeviceBuffer->Data().SetLength(0);
  1.1620 +			// Pass the buffer to the he device
  1.1621 +            err = iCMMFHwDevice->ThisHwBufferFilled(*iHwDeviceBuffer);
  1.1622 +			}
  1.1623 +		else
  1.1624 +			// Pass the buffer to the observer
  1.1625 +			iDevSoundObserver->BufferToBeFilled(&aHwDataBuffer);
  1.1626 +		}
  1.1627 +	else if (iMode == EMMFDevSoundStateTonePlaying)
  1.1628 +		{
  1.1629 +        // Hw device will call this method right after its Start was called.
  1.1630 +        // When it calls this for the first time it hasn't played one single
  1.1631 +        // buffer yet so check that.
  1.1632 +        // In this case there's no need to set the active buffer as it's already
  1.1633 +        // waiting to be played.
  1.1634 +        if (!iFirstCallFromHwDevice)
  1.1635 +            SetActiveToneBuffer();
  1.1636 +
  1.1637 +		// If there is no data in the active buffer, tone play is finished.
  1.1638 +		// DevSound just have to wait for completion event from audio device.
  1.1639 +		if (iActiveToneBuffer->Data().Length() > 0)
  1.1640 +            { 
  1.1641 +			TInt tonelen = iActiveToneBuffer->Data().Length();
  1.1642 +
  1.1643 +			// don't enter more data than can be handled by the receiving buffer
  1.1644 +			if (len >= tonelen) len = tonelen;
  1.1645 +
  1.1646 +            // Copy data from tone buffer to hw device buffer
  1.1647 +            Mem::Copy((TAny*)(iHwDeviceBuffer->Data().Ptr()), (TAny*)(iActiveToneBuffer->Data().Ptr()), len);
  1.1648 +            
  1.1649 +            iHwDeviceBuffer->Data().SetLength(len);
  1.1650 +            // Play data and try to generate next data block
  1.1651 +			err = iCMMFHwDevice->ThisHwBufferFilled(*iHwDeviceBuffer);
  1.1652 +            if (err != KErrNone)
  1.1653 +            	return err;
  1.1654 +            // Check again whether this is the first call from Hw device.
  1.1655 +            // FillFreeToneBuffer assumes the iActiveToneBuffer has already
  1.1656 +            // been played.
  1.1657 +            if (!iFirstCallFromHwDevice)
  1.1658 +                err = FillFreeToneBuffer();
  1.1659 +            else
  1.1660 +                iFirstCallFromHwDevice = EFalse;  // Reset flag
  1.1661 +
  1.1662 + 			}
  1.1663 +		else if (iFirstCallFromHwDevice)
  1.1664 +			{//we have no data in the tone buffer and thus have no 
  1.1665 +			//outstanding requests to play
  1.1666 +			err = KErrUnderflow; //simulate underrun
  1.1667 +			}
  1.1668 +		else
  1.1669 +			{
  1.1670 +			iHwDeviceBuffer->Data().SetLength(0);
  1.1671 +			iHwDeviceBuffer->SetLastBuffer(ETrue);
  1.1672 +            // Send an empty last buffer to HwDevice to get a play completion event with KErrUnderflow
  1.1673 +			err = iCMMFHwDevice->ThisHwBufferFilled(*iHwDeviceBuffer);
  1.1674 +			}
  1.1675 +	
  1.1676 +		// If there was an error filling the buffer could be corrupt data
  1.1677 +		// notify the client and stop playing.Set err to KErrNone. 
  1.1678 +		if (err != KErrNone)
  1.1679 +			{
  1.1680 +			Error(err);//Updates Bytes played informs client
  1.1681 +			err = KErrNone;
  1.1682 +			iCMMFHwDevice->Stop();//unloads sound device
  1.1683 +            }
  1.1684 +		}
  1.1685 +	else
  1.1686 +		{
  1.1687 +		err = KErrGeneral;
  1.1688 +		Error(err);
  1.1689 +		iCMMFHwDevice->Stop();//unloads sound device
  1.1690 +
  1.1691 +		}
  1.1692 +	return err;
  1.1693 +	}
  1.1694 +
  1.1695 +
  1.1696 +/**
  1.1697 + *
  1.1698 + *	MMMFHwDeviceObserver mixin implementation.
  1.1699 + *
  1.1700 + *	The CMMFHwDevice implementation object calls this method during encoding
  1.1701 + *	(recording), when it fills the buffer aHwDataBuffer with
  1.1702 + *	encoded data.
  1.1703 + *
  1.1704 + *	@return	"TInt"
  1.1705 + *			Error code. KErrNone if success.
  1.1706 + *
  1.1707 + */
  1.1708 +TInt CMMFDevSoundSvrImp::EmptyThisHwBuffer(CMMFBuffer& aHwDataBuffer)
  1.1709 +	{
  1.1710 +	TInt err = KErrNone;
  1.1711 +	if(iMode== EMMFDevSoundStateRecording)
  1.1712 +		{
  1.1713 +		// Keep a reference to this Hw data Buffer. We need to send the 
  1.1714 +		// reference back to HwDevice implementation
  1.1715 +		iHwDeviceBuffer = static_cast<CMMFDataBuffer*>(&aHwDataBuffer);
  1.1716 +
  1.1717 +		// Set the request length, From HwDevice this comes with buffer
  1.1718 +		// length. MMF will use RequestSize attribute of the buffer.
  1.1719 +		// We can avoid this by setting in HwDevice implemenation
  1.1720 +		TInt len = iHwDeviceBuffer->Data().Length();
  1.1721 +		TRAP(err, iHwDeviceBuffer->SetRequestSizeL(len));
  1.1722 +	
  1.1723 +		// if we're pausing (i.e. flushing) set the last buffer flag
  1.1724 +		// when we get an empty buffer from the logical driver
  1.1725 +		if(iPaused  && iHwDeviceBuffer->Data().Length() == 0)
  1.1726 +		{
  1.1727 +		iPaused = EFalse;
  1.1728 +
  1.1729 +		iHwDeviceBuffer->SetLastBuffer(ETrue);
  1.1730 +
  1.1731 +		iDevSoundEventHandler->CancelReceiveEvents();
  1.1732 +
  1.1733 +		}
  1.1734 +
  1.1735 +		// Send Data from Observer
  1.1736 +		iDevSoundObserver->BufferToBeEmptied(iHwDeviceBuffer);
  1.1737 +		}
  1.1738 +	else
  1.1739 +		{
  1.1740 +		err = KErrGeneral;
  1.1741 +		Error(err);
  1.1742 +		iCMMFHwDevice->Stop();//unloads sound device
  1.1743 +
  1.1744 +		}
  1.1745 +
  1.1746 +	return err;
  1.1747 +	}
  1.1748 +
  1.1749 +
  1.1750 +/**
  1.1751 + *
  1.1752 + *	MMMFHwDeviceObserver mixin implementation.
  1.1753 + *
  1.1754 + *	The CMMFHwDevice implementation object calls this method when a message from
  1.1755 + *	the hardware device implementation is received.
  1.1756 + *
  1.1757 + *	@return	"TInt"
  1.1758 + *			Error code. KErrNone if success.
  1.1759 + *
  1.1760 + */
  1.1761 +TInt CMMFDevSoundSvrImp::MsgFromHwDevice(TUid aMessageType, const TDesC8& /*aMsg*/)
  1.1762 +	{
  1.1763 +	TInt result = KErrNotSupported;
  1.1764 +	if (aMessageType.iUid == KMmfHwDeviceObserverUpdateBytesPlayed)
  1.1765 +		{//this is used by sw codec wrapper to request a bytes played update
  1.1766 +		//bytes played won't be updated in Stopped() or Error() on sw cdoec wrapper
  1.1767 +		//as the sound device is closed. Non swCodec wrapper Hw device plugins
  1.1768 +		//can get there bytes updated on Stopped() and/or Error()
  1.1769 +		UpdateBytesPlayed();
  1.1770 +		result = KErrNone;
  1.1771 +		}
  1.1772 +	return result;
  1.1773 +	}
  1.1774 +
  1.1775 +/**
  1.1776 + *
  1.1777 + *	MMMFHwDeviceObserver mixin implementation.
  1.1778 + *
  1.1779 + *	The CMMFHwDevice implementation object calls this method when the current
  1.1780 + *	encode or decode task is finished or stopped.  The policy state is updated
  1.1781 + *
  1.1782 + */
  1.1783 +void CMMFDevSoundSvrImp::Stopped()
  1.1784 +	{
  1.1785 +	//for swcodec wrap hw devices bytes played updated in MsgFromHwDevice
  1.1786 +	//but non Swcodec wrappers hw devices may do it differently
  1.1787 +	//also don't know if non Swcodec wrap hw device will call Stopped or Error first
  1.1788 +	UpdateBytesPlayed();
  1.1789 +
  1.1790 +	iLastBufferReceived = EFalse;
  1.1791 +	UpdatePolicyState(EMMFStateCompleted);
  1.1792 +	}
  1.1793 +
  1.1794 +/**
  1.1795 + *  MMMFHwDeviceObserver mixin implementation
  1.1796 + *  Processes error from hw device
  1.1797 + */
  1.1798 +void CMMFDevSoundSvrImp::Error(TInt aError)
  1.1799 +	{
  1.1800 +	if (iMode== EMMFDevSoundStatePlaying)
  1.1801 +		{
  1.1802 +		//for swcodec wrap hw devices bytes played updated in MsgFromHwDevice
  1.1803 +		//but non Swcodec wrappers hw devices may do it differently
  1.1804 +		//also don't know if non Swcodec wrap hw device will call Stopped or Error first
  1.1805 +		UpdateBytesPlayed();
  1.1806 +
  1.1807 +        iDevSoundObserver->PlayError(aError);
  1.1808 +        UpdatePolicyState(EMMFStateStopped);
  1.1809 +		}
  1.1810 +	else if (iMode== EMMFDevSoundStateRecording)
  1.1811 +		{
  1.1812 +        iDevSoundObserver->RecordError(aError);
  1.1813 +        UpdatePolicyState(EMMFStateStopped);
  1.1814 +		}
  1.1815 +	else if (iMode== EMMFDevSoundStateTonePlaying)
  1.1816 +		{
  1.1817 +        iDevSoundObserver->ToneFinished(aError);
  1.1818 +        UpdatePolicyState(EMMFStateStopped);
  1.1819 +		}
  1.1820 +	//else can't handle error
  1.1821 +	}
  1.1822 +
  1.1823 +
  1.1824 +/********************************************************************************
  1.1825 + *				Non Exported public functions ends here							*
  1.1826 + ********************************************************************************/
  1.1827 +
  1.1828 +
  1.1829 +/********************************************************************************
  1.1830 + *				Private functions begins here									*
  1.1831 + ********************************************************************************/
  1.1832 +
  1.1833 +TInt CMMFDevSoundSvrImp::InitializeFormat(RMdaDevSound::TSoundFormatsSupportedBuf& aSupportedFormat,
  1.1834 +		RMdaDevSound::TCurrentSoundFormatBuf& aFormat)
  1.1835 +	{
  1.1836 +	// Choose an encoding
  1.1837 +	TUint32 enc = aSupportedFormat().iEncodings;
  1.1838 +	// Always defaults to this
  1.1839 +	if (enc & RMdaDevSound::EMdaSoundEncoding16BitPCM)
  1.1840 +		aFormat().iEncoding = RMdaDevSound::EMdaSoundEncoding16BitPCM;
  1.1841 +	else if (enc & RMdaDevSound::EMdaSoundEncoding8BitALaw)
  1.1842 +		aFormat().iEncoding = RMdaDevSound::EMdaSoundEncoding8BitALaw;
  1.1843 +	else if (enc & RMdaDevSound::EMdaSoundEncoding8BitMuLaw)
  1.1844 +		aFormat().iEncoding = RMdaDevSound::EMdaSoundEncoding8BitMuLaw;
  1.1845 +	else if (enc & RMdaDevSound::EMdaSoundEncoding8BitPCM)
  1.1846 +		aFormat().iEncoding = RMdaDevSound::EMdaSoundEncoding8BitPCM;
  1.1847 +
  1.1848 +	// default to Monophonic playback:
  1.1849 +	aFormat().iChannels=1;
  1.1850 +
  1.1851 +	// Store the device capabilities (WINS supports from 8000 Hz to 44100 Hz)
  1.1852 +	if ((aSupportedFormat().iMinRate <= 8000) && (8000 <= aSupportedFormat().iMaxRate))
  1.1853 +		iDeviceCapabilities.iRate = EMMFSampleRate8000Hz;
  1.1854 +	if ((aSupportedFormat().iMinRate <= 11025) && (11025 <= aSupportedFormat().iMaxRate))
  1.1855 +		iDeviceCapabilities.iRate |= EMMFSampleRate11025Hz;
  1.1856 +	if ((aSupportedFormat().iMinRate <= 12000) && (12000 <= aSupportedFormat().iMaxRate))
  1.1857 +		iDeviceCapabilities.iRate |= EMMFSampleRate12000Hz;
  1.1858 +	if ((aSupportedFormat().iMinRate <= 16000) && (16000 <= aSupportedFormat().iMaxRate))
  1.1859 +		iDeviceCapabilities.iRate |= EMMFSampleRate16000Hz;
  1.1860 +	if ((aSupportedFormat().iMinRate <= 22050) && (22050 <= aSupportedFormat().iMaxRate))
  1.1861 +		iDeviceCapabilities.iRate |= EMMFSampleRate22050Hz;
  1.1862 +	if ((aSupportedFormat().iMinRate <= 24000) && (24000 <= aSupportedFormat().iMaxRate))
  1.1863 +		iDeviceCapabilities.iRate |= EMMFSampleRate24000Hz;
  1.1864 +	if ((aSupportedFormat().iMinRate <= 32000) && (32000 <= aSupportedFormat().iMaxRate))
  1.1865 +		iDeviceCapabilities.iRate |= EMMFSampleRate32000Hz;
  1.1866 +	if ((aSupportedFormat().iMinRate <= 44100) && (44100 <= aSupportedFormat().iMaxRate))
  1.1867 +		iDeviceCapabilities.iRate |= EMMFSampleRate44100Hz;
  1.1868 +	if ((aSupportedFormat().iMinRate <= 48000) && (48000 <= aSupportedFormat().iMaxRate))
  1.1869 +		iDeviceCapabilities.iRate |= EMMFSampleRate48000Hz;
  1.1870 +	if ((aSupportedFormat().iMinRate <= 64000) && (64000 <= aSupportedFormat().iMaxRate))
  1.1871 +		iDeviceCapabilities.iRate |= EMMFSampleRate64000Hz;
  1.1872 +	if ((aSupportedFormat().iMinRate <= 88200) && (88200 <= aSupportedFormat().iMaxRate))
  1.1873 +		iDeviceCapabilities.iRate |= EMMFSampleRate88200Hz;
  1.1874 +	if ((aSupportedFormat().iMinRate <= 96000) && (96000 <= aSupportedFormat().iMaxRate))
  1.1875 +		iDeviceCapabilities.iRate |= EMMFSampleRate96000Hz;
  1.1876 +
  1.1877 +	// Store the encodings supported
  1.1878 +	iDeviceCapabilities.iEncoding = 0;
  1.1879 +	if (enc & RMdaDevSound::EMdaSoundEncoding16BitPCM)
  1.1880 +		iDeviceCapabilities.iEncoding |= EMMFSoundEncoding16BitPCM;
  1.1881 +	if (enc & RMdaDevSound::EMdaSoundEncoding8BitALaw)
  1.1882 +		iDeviceCapabilities.iEncoding |= EMMFSoundEncoding8BitALaw;
  1.1883 +	if (enc & RMdaDevSound::EMdaSoundEncoding8BitMuLaw)
  1.1884 +		iDeviceCapabilities.iEncoding |= EMMFSoundEncoding8BitMuLaw;
  1.1885 +	if (enc & RMdaDevSound::EMdaSoundEncoding8BitPCM)
  1.1886 +		iDeviceCapabilities.iEncoding |= EMMFSoundEncoding8BitPCM;
  1.1887 +
  1.1888 +	// Mono and Stereo support
  1.1889 +	if (aSupportedFormat().iChannels == 2)
  1.1890 +		iDeviceCapabilities.iChannels = EMMFStereo;
  1.1891 +	iDeviceCapabilities.iChannels |= EMMFMono;
  1.1892 +
  1.1893 +	iDeviceCapabilities.iBufferSize = aSupportedFormat().iMaxBufferSize;
  1.1894 +	// Default
  1.1895 +	iDeviceConfig.iRate = EMMFSampleRate8000Hz;
  1.1896 +	iDeviceConfig.iEncoding = EMMFSoundEncoding16BitPCM;
  1.1897 +	iDeviceConfig.iChannels = EMMFMono;
  1.1898 +
  1.1899 +	return KErrNone;
  1.1900 +	}
  1.1901 +
  1.1902 +/*
  1.1903 + *
  1.1904 + *	Makes request to Policy Server (asynchronous call)
  1.1905 + *
  1.1906 + */
  1.1907 +void CMMFDevSoundSvrImp::RequestPolicy()
  1.1908 +	{
  1.1909 +	iDevSoundEventHandler->CancelReceiveEvents();
  1.1910 +	iDevSoundEventHandler->ReceiveEvents();
  1.1911 +	iAudioPolicyPrioritySettings.iCapabilities = iParent.CheckClientCapabilities();
  1.1912 +	iAudioPolicyProxy->MakeRequest(iAudioPolicyPrioritySettings);
  1.1913 +	}
  1.1914 +
  1.1915 +/*
  1.1916 + *
  1.1917 + *	Creates buffer and begin playback using the specified tone generator.
  1.1918 + *
  1.1919 + */
  1.1920 +void CMMFDevSoundSvrImp::DoPlayL()
  1.1921 +	{
  1.1922 +	// Delete any buffer from previous call and try to create maximum buffer 
  1.1923 +	// size. Double Buffer the Tone data.
  1.1924 +	if (iToneBuffer1)
  1.1925 +		{
  1.1926 +		delete iToneBuffer1; 
  1.1927 +		iToneBuffer1 = NULL; 
  1.1928 +		}
  1.1929 +	//note the tone buffer needs to be the same as the pcm16->pcm16 'null'
  1.1930 +	//hw device plugin
  1.1931 +	// Buffer size = (SampleRate * BytesPerSample * Channels) / 4
  1.1932 +	TInt useBufferOfSize = ((SamplingFrequency() * 2 * NumberOfChannels())/KDevSoundFramesPerSecond + (KDevSoundDeltaFrameSize-1)) &~ (KDevSoundDeltaFrameSize-1);
  1.1933 +	//clamp buffer to desired limits
  1.1934 +	if(useBufferOfSize < KDevSoundMinFrameSize) 
  1.1935 +		useBufferOfSize = KDevSoundMinFrameSize;
  1.1936 +	else if(useBufferOfSize > KDevSoundMaxFrameSize) 
  1.1937 +		useBufferOfSize = KDevSoundMaxFrameSize;
  1.1938 +
  1.1939 +	//clamp buffer to limits of hardware
  1.1940 +	if(useBufferOfSize < Max(iPlayFormatsSupported().iMinBufferSize, iRecordFormatsSupported().iMinBufferSize))
  1.1941 +		useBufferOfSize = Max(iPlayFormatsSupported().iMinBufferSize, iRecordFormatsSupported().iMinBufferSize);
  1.1942 +	else if(useBufferOfSize > Min(iPlayFormatsSupported().iMaxBufferSize, iRecordFormatsSupported().iMaxBufferSize))
  1.1943 +		useBufferOfSize = Min(iPlayFormatsSupported().iMaxBufferSize, iRecordFormatsSupported().iMaxBufferSize);
  1.1944 +
  1.1945 +	iToneBuffer1 = CMMFDataBuffer::NewL(useBufferOfSize);
  1.1946 +	User::LeaveIfError(iCurrentGenerator->FillBuffer(iToneBuffer1->Data()));
  1.1947 +
  1.1948 +	if (iToneBuffer2)
  1.1949 +		{
  1.1950 +		delete iToneBuffer2; 
  1.1951 +		iToneBuffer2 = NULL;
  1.1952 +		}
  1.1953 +	iToneBuffer2 = CMMFDataBuffer::NewL(useBufferOfSize);
  1.1954 +	User::LeaveIfError(iCurrentGenerator->FillBuffer(iToneBuffer2->Data()));
  1.1955 +
  1.1956 +	// Assign active buffer
  1.1957 +	iActiveToneBuffer = iToneBuffer1;
  1.1958 +
  1.1959 +	// Hw device hasn't played anything yet so don't change
  1.1960 +    // active buffer. This is checked in FillThisHwBuffer.
  1.1961 +    iFirstCallFromHwDevice = ETrue;
  1.1962 +
  1.1963 +    // Start HwDevice to play data
  1.1964 +    User::LeaveIfError(iCMMFHwDevice->Start(EDevDecode, EDevOutFlow));
  1.1965 +	
  1.1966 +	}
  1.1967 +
  1.1968 +/*
  1.1969 + *
  1.1970 + *	This method assigns the other buffer as active buffer. The tone audio 
  1.1971 + *	generator should fill data in the other buffer by now.
  1.1972 + *
  1.1973 + */
  1.1974 +void CMMFDevSoundSvrImp::SetActiveToneBuffer()
  1.1975 +	{
  1.1976 +	if (iActiveToneBuffer == iToneBuffer1)
  1.1977 +		iActiveToneBuffer = iToneBuffer2;
  1.1978 +	else if (iActiveToneBuffer == iToneBuffer2)
  1.1979 +		iActiveToneBuffer = iToneBuffer1;
  1.1980 +	}
  1.1981 +
  1.1982 +/*
  1.1983 + *
  1.1984 + *	This method fills data into the free buffer.
  1.1985 + *
  1.1986 + *	@return	"TInt"
  1.1987 + *			Error code. KErrNone if success.
  1.1988 + *
  1.1989 + */
  1.1990 +TInt CMMFDevSoundSvrImp::FillFreeToneBuffer()
  1.1991 +	{
  1.1992 +	TInt err(KErrNone);
  1.1993 +	if (iActiveToneBuffer == iToneBuffer1)
  1.1994 +		err = iCurrentGenerator->FillBuffer(iToneBuffer2->Data());
  1.1995 +	else if (iActiveToneBuffer == iToneBuffer2)
  1.1996 +		err = iCurrentGenerator->FillBuffer(iToneBuffer1->Data());
  1.1997 +	return err;
  1.1998 +	}
  1.1999 +
  1.2000 +/*
  1.2001 + *
  1.2002 + *	Updates the policy state based on Audio policy settings of this devsound instance
  1.2003 + *
  1.2004 + */
  1.2005 +TInt CMMFDevSoundSvrImp::UpdatePolicyState(TMMFAudioPolicyState aNewState)
  1.2006 +	{
  1.2007 +	iAudioPolicyPrioritySettings.iState = aNewState;
  1.2008 +	TInt error = iAudioPolicyProxy->UpdateState(iAudioPolicyPrioritySettings);
  1.2009 +	if ((error == KErrNone) && (aNewState == EMMFStateStopped))
  1.2010 +		{
  1.2011 +		iHasPolicy = EFalse;
  1.2012 +		}
  1.2013 +
  1.2014 +	return error;
  1.2015 +	}
  1.2016 +
  1.2017 +/*
  1.2018 + *
  1.2019 + *	Initializes audio device node by setting volume, and sampling rate.
  1.2020 + *
  1.2021 + *	@return	"TInt"
  1.2022 + *			Error Code. KErrNone if success.
  1.2023 + *
  1.2024 + */
  1.2025 +TInt CMMFDevSoundSvrImp::InitTask()
  1.2026 +	{
  1.2027 +	// No Implementation
  1.2028 +	return KErrNone;
  1.2029 +	}
  1.2030 +
  1.2031 +
  1.2032 +
  1.2033 +/*
  1.2034 + *
  1.2035 + *	Returns an integer representing Sampling Frequency the device is currently
  1.2036 + *	configured to.
  1.2037 + *
  1.2038 + *	@return	"TInt"
  1.2039 + *			Sampling Frequency.
  1.2040 + *
  1.2041 + */
  1.2042 +TInt CMMFDevSoundSvrImp::SamplingFrequency()
  1.2043 +	{
  1.2044 +	if(iDeviceConfig.iRate == EMMFSampleRate8000Hz)
  1.2045 +		return 8000;
  1.2046 +	else if(iDeviceConfig.iRate == EMMFSampleRate11025Hz)
  1.2047 +		return 11025;
  1.2048 +	else if(iDeviceConfig.iRate == EMMFSampleRate12000Hz)
  1.2049 +		return 12000;
  1.2050 +	else if(iDeviceConfig.iRate == EMMFSampleRate16000Hz)
  1.2051 +		return 16000;
  1.2052 +	else if(iDeviceConfig.iRate == EMMFSampleRate22050Hz)
  1.2053 +		return 22050;
  1.2054 +	else if(iDeviceConfig.iRate == EMMFSampleRate24000Hz)
  1.2055 +		return 24000;
  1.2056 +	else if(iDeviceConfig.iRate == EMMFSampleRate32000Hz)
  1.2057 +		return 32000;
  1.2058 +	else if(iDeviceConfig.iRate == EMMFSampleRate44100Hz)
  1.2059 +		return 44100;
  1.2060 +	else if(iDeviceConfig.iRate == EMMFSampleRate48000Hz)
  1.2061 +		return 48000;
  1.2062 +	else if(iDeviceConfig.iRate == EMMFSampleRate88200Hz)
  1.2063 +		return 88200;
  1.2064 +	else if(iDeviceConfig.iRate == EMMFSampleRate96000Hz)
  1.2065 +		return 96000;
  1.2066 +	else
  1.2067 +		return 8000; //default
  1.2068 +	}
  1.2069 + 
  1.2070 +/*
  1.2071 + *
  1.2072 + *	Returns an integer representing number of channels the device is currently
  1.2073 + *	configured to.
  1.2074 + *
  1.2075 + *	@return	"TInt"
  1.2076 + *			Number of audio channels 1 if mono, 2 if stereo.
  1.2077 + *
  1.2078 + */
  1.2079 +TInt CMMFDevSoundSvrImp::NumberOfChannels()
  1.2080 +	{
  1.2081 +	if(iDeviceConfig.iChannels == EMMFMono)
  1.2082 +		return 1;
  1.2083 +	else
  1.2084 +		return 2;
  1.2085 +	}
  1.2086 +
  1.2087 +/*
  1.2088 + *
  1.2089 + *	Returns an integer representing number of bytes in each audio sample
  1.2090 + *	
  1.2091 + *
  1.2092 + *	@return	"TInt"
  1.2093 + *			Number of of bytes in each audio sample.
  1.2094 + *
  1.2095 + */
  1.2096 +TInt CMMFDevSoundSvrImp::BytesPerAudioSample()
  1.2097 +	{
  1.2098 +	TInt bytes=1;
  1.2099 +	switch (iDeviceConfig.iEncoding)
  1.2100 +		{
  1.2101 +		case EMMFSoundEncoding8BitPCM:
  1.2102 +		case EMMFSoundEncoding8BitALaw:
  1.2103 +		case EMMFSoundEncoding8BitMuLaw:
  1.2104 +			{
  1.2105 +			bytes=1;
  1.2106 +			}
  1.2107 +		break;
  1.2108 +		case EMMFSoundEncoding16BitPCM:
  1.2109 +			{
  1.2110 +			bytes=2;
  1.2111 +			}
  1.2112 +		break;
  1.2113 +		}
  1.2114 +	return bytes;
  1.2115 +	}
  1.2116 +
  1.2117 +
  1.2118 +/********************************************************************************
  1.2119 + *				Private functions ends here										*
  1.2120 + ********************************************************************************/
  1.2121 +
  1.2122 +
  1.2123 +// CustomCommand* implementation:
  1.2124 +// The following come through from the parent object intact - currently it seems
  1.2125 +// easier to pass this through with an RMessage, as the result parameter (at least)
  1.2126 +// is easier to deal with that way. This might change in the future. 
  1.2127 +// [TODO - if we extended this to CMMFHwDevice, it might be easier to use some sort
  1.2128 +// of TMMFCustomCommandParamBlock throughout, which as well as the uid, in params etc
  1.2129 +// by value, also provided a virtual(?) function to set output param. Could then
  1.2130 +// use in both plat sec and original code
  1.2131 +
  1.2132 +void CMMFDevSoundSvrImp::DoSyncCustomCommandL(const RMmfIpcMessage& aMessage)
  1.2133 +	{
  1.2134 +	TInt command = aMessage.Int0();
  1.2135 +	
  1.2136 +	// we don't support any commands at the momment
  1.2137 +	User::Leave(KErrNotSupported);
  1.2138 +	}
  1.2139 +	
  1.2140 +void CMMFDevSoundSvrImp::DoSyncCustomCommandResultL(const RMmfIpcMessage& aMessage)
  1.2141 +	{
  1.2142 +	TInt command = aMessage.Int0();
  1.2143 +	
  1.2144 +	// we don't support any commands at the momment
  1.2145 +	User::Leave(KErrNotSupported);	
  1.2146 +	}
  1.2147 +	
  1.2148 +void CMMFDevSoundSvrImp::DoAsyncCustomCommandL(const RMmfIpcMessage& aMessage)
  1.2149 +	{
  1.2150 +	TInt command = aMessage.Int0();
  1.2151 +	
  1.2152 +	// we don't support any commands at the momment
  1.2153 +	User::Leave(KErrNotSupported); // this will still complete for an async message	
  1.2154 +	}
  1.2155 +	
  1.2156 +void CMMFDevSoundSvrImp::DoAsyncCustomCommandResultL(const RMmfIpcMessage& aMessage)
  1.2157 +	{
  1.2158 +	TInt command = aMessage.Int0();
  1.2159 +	
  1.2160 +	// we don't support any commands at the moment
  1.2161 +	User::Leave(KErrNotSupported); // this will still complete for an async message	
  1.2162 +	}
  1.2163 +