devsound/devsoundrefplugin/src/platsec/server/AudioServer/MmfDevSoundSessionBody.cpp
changeset 0 79dd3e2336a0
equal deleted inserted replaced
-1:000000000000 0:79dd3e2336a0
       
     1 // Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include <e32base.h>
       
    17 #ifdef SYMBIAN_MULTIMEDIA_CODEC_API
       
    18 #include <OMX_Core.h>
       
    19 #endif // SYMBIAN_MULTIMEDIA_CODEC_API
       
    20 #include "MmfDevSoundSessionBody.h"
       
    21 #include "MmfDevSoundSessionXtnd.h"
       
    22 #include "MmfDevSoundServer.h"
       
    23 #include <mdaaudiotoneplayer.h>
       
    24 #include <mmf/server/mmfdatabuffer.h>
       
    25 #include <mmffourcc.h>
       
    26 #include <mmfhwdeviceimplementationuids.hrh>
       
    27 #include <mmf/server/mmfswcodecwrappercustominterfacesuids.hrh> // KUidRefDevSoundTaskConfig & KMmfUidEmptyBuffersCustomInterface
       
    28 #include <mmf/server/mmfdevsoundcustominterfacesupport.h>
       
    29 
       
    30 const TUid KEmptyBuffersCustomInterfaceTypeUid	= {KMmfUidEmptyBuffersCustomInterface};
       
    31 
       
    32 /*
       
    33  *
       
    34  *	Default Constructor.
       
    35  *
       
    36  *	No default implementation. CMMFDevSoundProxy implements 2-phase construction.
       
    37  *
       
    38  */
       
    39 CMMFDevSoundSvrImp::CMMFDevSoundSvrImp(CMMFDevSoundSessionXtnd* aParent)
       
    40 : iParent(*aParent)
       
    41 	{
       
    42 	iMode= EMMFDevSoundStateIdle;
       
    43 	//Set reasonable default values for DTMF 
       
    44 	iDTMFGen.SetToneDurations(250000,50000,250000);
       
    45 	}
       
    46 
       
    47 /*
       
    48  *
       
    49  *	Destructor.
       
    50  *
       
    51  *	Deletes all objects and releases all resource owned by this
       
    52  *	instance.
       
    53  *
       
    54  */
       
    55 CMMFDevSoundSvrImp::~CMMFDevSoundSvrImp()
       
    56 	{
       
    57 	delete iToneBuffer1;
       
    58 	delete iToneBuffer2;
       
    59 	delete iDevSoundEventHandler; 
       
    60 	if( iAudioPolicyProxy != NULL)
       
    61 		{
       
    62 		iAudioPolicyProxy->Close(); 
       
    63 		delete iAudioPolicyProxy;
       
    64 		}
       
    65 	delete iDevSoundUtil;
       
    66 	delete iFixedSequences;
       
    67 	delete iCMMFHwDevice;
       
    68 #ifdef SYMBIAN_MULTIMEDIA_CODEC_API
       
    69 	OMX_Deinit();
       
    70 #endif // SYMBIAN_MULTIMEDIA_CODEC_API
       
    71 	}
       
    72 
       
    73 /*
       
    74  *
       
    75  *	Constructs, and returns a pointer to, a new CMMFDevSoundSvrImp object.
       
    76  *
       
    77  *	Leaves on failure.
       
    78  *
       
    79  */
       
    80 CMMFDevSoundSvrImp* CMMFDevSoundSvrImp::NewL(CMMFDevSoundSessionXtnd* aParent)
       
    81 	{
       
    82 	CMMFDevSoundSvrImp* self = new (ELeave) CMMFDevSoundSvrImp(aParent);
       
    83 	return self;
       
    84 	}
       
    85 
       
    86 /*
       
    87  *
       
    88  *	3rd phase constructor - assumes that iParent has already been set up properly
       
    89  *                          (During ConstructL() it has yet to be
       
    90  *
       
    91  */
       
    92 void CMMFDevSoundSvrImp::Construct3L(RServer2& aPolicyServerHandle)
       
    93 	{
       
    94 	// all these data properties should be NULL, but add ASSERTs to verity
       
    95 	ASSERT(iAudioPolicyProxy==NULL);
       
    96 	iAudioPolicyProxy = new (ELeave) RMMFAudioPolicyProxy();
       
    97 	ASSERT(iDevSoundEventHandler==NULL);
       
    98 	iDevSoundEventHandler = CMMFDevSoundEventHandler::NewL(iAudioPolicyProxy);
       
    99 	User::LeaveIfError(iAudioPolicyProxy->Open(aPolicyServerHandle));
       
   100 	iDevSoundEventHandler->SetDevSoundInfo(&iParent);
       
   101 
       
   102 	iDevSoundUtil = CMMFDevSoundUtility::NewL();
       
   103 	// Initialize Fixed sequence related
       
   104 	iDevSoundUtil->InitializeFixedSequenceL(&iFixedSequences);
       
   105 	
       
   106 #ifdef SYMBIAN_MULTIMEDIA_CODEC_API
       
   107 	OMX_Init();
       
   108 #endif // SYMBIAN_MULTIMEDIA_CODEC_API
       
   109 	PreInitializeL();
       
   110 	}
       
   111 
       
   112 /**
       
   113  * internal procedure to perform all initialization prior to setting the 
       
   114  * data type 4CC code
       
   115  */
       
   116 void CMMFDevSoundSvrImp::PreInitializeL()
       
   117 	{
       
   118 	// Set default values for priority settings: Note: Client must 
       
   119 	// over ride default settings by calling SetPrioirtySettings
       
   120 	iAudioPolicyPrioritySettings.iState = EMMFStateStopped;
       
   121 	iAudioPolicyPrioritySettings.iPref = EMdaPriorityPreferenceNone;
       
   122 	iAudioPolicyPrioritySettings.iPriority = 0;
       
   123 
       
   124 	// Get device capabilities and current settings from Audio Policy:
       
   125 	User::LeaveIfError(iAudioPolicyProxy->GetPlayFormatsSupported(iPlayFormatsSupported));
       
   126 	User::LeaveIfError(iAudioPolicyProxy->GetPlayFormat(iPlayFormat));
       
   127 	User::LeaveIfError(iAudioPolicyProxy->GetRecordFormatsSupported(iRecordFormatsSupported));
       
   128 	User::LeaveIfError(iAudioPolicyProxy->GetRecordFormat(iRecordFormat));
       
   129 
       
   130 	//default to play until we know we are recording
       
   131 	User::LeaveIfError(InitializeFormat(iPlayFormatsSupported, iPlayFormat));
       
   132 	}
       
   133 
       
   134 /*
       
   135  *
       
   136  *	Initializes CMMFDevSoundProxy object to play and record PCM16 raw audio data
       
   137  *	with sampling rate of 8 KHz.
       
   138  *
       
   139  *	On completion of Initialization, calls InitializeComplete() on
       
   140  *	aDevSoundObserver.
       
   141  *
       
   142  *	Leaves on failure.
       
   143  *
       
   144  *	@param	"MDevSoundObserver& aDevSoundObserver"
       
   145  *			A reference to DevSound Observer instance.
       
   146  *
       
   147  *	@param	"TMMFState aMode"
       
   148  *			Mode for which this object will be used.
       
   149  *
       
   150  */
       
   151 void CMMFDevSoundSvrImp::InitializeL(MDevSoundObserver& aDevSoundObserver, TMMFState aMode)
       
   152 
       
   153 	{
       
   154 	// if no HwDevice id specified, load default null implementation
       
   155 	TUid rawUid = {KMmfUidHwDevicePCM16ToPCM16};
       
   156 	InitializeL(aDevSoundObserver, rawUid, aMode);
       
   157 	__ASSERT_DEBUG(!(iHasPolicy&&(iMode == EMMFDevSoundStatePlaying)), Panic(TMMFDevSoundSessionPolicyNotInvalidated));
       
   158 	}
       
   159 
       
   160 /*
       
   161  *
       
   162  *	Configure CMMFDevSoundProxy object for the settings in aConfig.
       
   163  *
       
   164  *	Use this to set sampling rate, Encoding and Mono/Stereo.
       
   165  *
       
   166  *	@param	"TMMFCapabilities& aConfig"
       
   167  *			Attribute values to which CMMFDevSoundProxy object will be configured to.
       
   168  *
       
   169  *  As part of defect 20796, the iRecordFormat has been set under the iPlayFormat, 
       
   170  *  before it was not set at all.
       
   171  *
       
   172  */
       
   173 void CMMFDevSoundSvrImp::SetConfigL(const TMMFCapabilities& aConfig)
       
   174 	{
       
   175 	TUint attributeValue = aConfig.iRate;
       
   176 	// WINS supports from 8000 Hz to 96000 Hz
       
   177 	// The ToneGenerator currently supports sample rate of 8000Hz only. 
       
   178 	if(iMode == EMMFDevSoundStateTonePlaying && (attributeValue != EMMFSampleRate8000Hz ))
       
   179 		{
       
   180 		User::Leave(KErrNotSupported);
       
   181 		}
       
   182 	
       
   183 	if (attributeValue & EMMFSampleRate96000Hz) 
       
   184 		{ 
       
   185 		iPlayFormat().iRate = 96000; 
       
   186 		iRecordFormat().iRate = 96000;
       
   187 		iDeviceConfig.iRate = EMMFSampleRate96000Hz;
       
   188 		}
       
   189 	else if (attributeValue & EMMFSampleRate88200Hz) 
       
   190 		{ 
       
   191 		iPlayFormat().iRate = 88200; 
       
   192 		iRecordFormat().iRate = 88200;
       
   193 		iDeviceConfig.iRate = EMMFSampleRate88200Hz;
       
   194 		}
       
   195 	else if (attributeValue & EMMFSampleRate64000Hz) 
       
   196 		{ 
       
   197 		iPlayFormat().iRate = 64000; 
       
   198 		iRecordFormat().iRate = 64000;
       
   199 		iDeviceConfig.iRate = EMMFSampleRate64000Hz;
       
   200 		}
       
   201 	else if (attributeValue & EMMFSampleRate48000Hz) 
       
   202 		{ 
       
   203 		iPlayFormat().iRate = 48000; 
       
   204 		iRecordFormat().iRate = 48000;
       
   205 		iDeviceConfig.iRate = EMMFSampleRate48000Hz;
       
   206 		}
       
   207 	else if (attributeValue & EMMFSampleRate44100Hz) 
       
   208 		{ 
       
   209 		iPlayFormat().iRate = 44100; 
       
   210 		iRecordFormat().iRate = 44100;
       
   211 		iDeviceConfig.iRate = EMMFSampleRate44100Hz;
       
   212 		}
       
   213 	else if (attributeValue & EMMFSampleRate32000Hz) 
       
   214 		{ 
       
   215 		iPlayFormat().iRate = 32000; 
       
   216 		iRecordFormat().iRate = 32000; 
       
   217 		iDeviceConfig.iRate = EMMFSampleRate32000Hz;
       
   218 		}
       
   219 	else if (attributeValue & EMMFSampleRate24000Hz)
       
   220 		{
       
   221 		iPlayFormat().iRate = 
       
   222 		iRecordFormat().iRate = 24000;
       
   223 		iDeviceConfig.iRate = EMMFSampleRate24000Hz;
       
   224 		}
       
   225 	else if (attributeValue & EMMFSampleRate22050Hz)
       
   226 		{ 
       
   227 		iPlayFormat().iRate = 22050; 
       
   228 		iRecordFormat().iRate = 22050; 
       
   229 		iDeviceConfig.iRate = EMMFSampleRate22050Hz;
       
   230 		}
       
   231 	else if (attributeValue & EMMFSampleRate16000Hz)
       
   232 		{
       
   233 		iPlayFormat().iRate = 16000;
       
   234 		iRecordFormat().iRate = 16000; 
       
   235 		iDeviceConfig.iRate = EMMFSampleRate16000Hz;
       
   236 		}
       
   237 	else if (attributeValue & EMMFSampleRate12000Hz)
       
   238 		{
       
   239 		iPlayFormat().iRate = 
       
   240 		iRecordFormat().iRate = 12000;
       
   241 		iDeviceConfig.iRate = EMMFSampleRate12000Hz;
       
   242 		}
       
   243 	else if (attributeValue & EMMFSampleRate11025Hz)
       
   244 		{
       
   245 		iPlayFormat().iRate = 11025;
       
   246 		iRecordFormat().iRate = 11025;
       
   247 		iDeviceConfig.iRate = EMMFSampleRate11025Hz;
       
   248 		}
       
   249 	else if (attributeValue & EMMFSampleRate8000Hz)
       
   250 		{
       
   251 		iPlayFormat().iRate = 8000;
       
   252 		iRecordFormat().iRate = 8000;
       
   253 		iDeviceConfig.iRate = EMMFSampleRate8000Hz;
       
   254 		}
       
   255 	else if (attributeValue) 
       
   256 		{ //if no attribute value assume its not set
       
   257 		User::Leave(KErrNotSupported);
       
   258 		}
       
   259 
       
   260 	attributeValue = aConfig.iEncoding;
       
   261 	// Map from MMF Encoding enums to RMdaDevSound enum
       
   262 	if(attributeValue & EMMFSoundEncoding8BitPCM) 
       
   263 		{
       
   264 		iPlayFormat().iEncoding = RMdaDevSound::EMdaSoundEncoding8BitPCM;
       
   265 		iRecordFormat().iEncoding = RMdaDevSound::EMdaSoundEncoding8BitPCM;
       
   266 		iDeviceConfig.iEncoding = EMMFSoundEncoding8BitPCM;
       
   267 		}
       
   268 	else if(attributeValue & EMMFSoundEncoding8BitALaw)
       
   269 		{
       
   270 		iPlayFormat().iEncoding = RMdaDevSound::EMdaSoundEncoding8BitALaw;
       
   271 		iRecordFormat().iEncoding = RMdaDevSound::EMdaSoundEncoding8BitALaw;
       
   272 		iDeviceConfig.iEncoding = EMMFSoundEncoding8BitALaw;
       
   273 		}
       
   274 	else if(attributeValue & EMMFSoundEncoding8BitMuLaw) 
       
   275 		{
       
   276 		iPlayFormat().iEncoding = RMdaDevSound::EMdaSoundEncoding8BitMuLaw;
       
   277 		iRecordFormat().iEncoding = RMdaDevSound::EMdaSoundEncoding8BitMuLaw;
       
   278 		iDeviceConfig.iEncoding = EMMFSoundEncoding8BitMuLaw;
       
   279 		}
       
   280 	else if(attributeValue & EMMFSoundEncoding16BitPCM)
       
   281 		{
       
   282 		iPlayFormat().iEncoding = RMdaDevSound::EMdaSoundEncoding16BitPCM;
       
   283 		iRecordFormat().iEncoding = RMdaDevSound::EMdaSoundEncoding16BitPCM;
       
   284 		iDeviceConfig.iEncoding = EMMFSoundEncoding16BitPCM;
       
   285 		}
       
   286 	else if (attributeValue) 
       
   287 		{ //if no attribute value assume its not set
       
   288 		User::Leave(KErrNotSupported);
       
   289 		}
       
   290 
       
   291 	// Mono/Stereo settings
       
   292 	attributeValue = aConfig.iChannels;
       
   293 	if(iMode == EMMFDevSoundStateTonePlaying && (attributeValue != EMMFMono ))
       
   294 		{
       
   295 		User::Leave(KErrNotSupported);
       
   296 		}
       
   297 	if(attributeValue & EMMFStereo) 
       
   298 		{
       
   299 		iPlayFormat().iChannels = 2;
       
   300 		iRecordFormat().iChannels = 2;
       
   301 		iDeviceConfig.iChannels = EMMFStereo;
       
   302 		}
       
   303 	else if(attributeValue & EMMFMono)
       
   304 		{
       
   305 		iPlayFormat().iChannels = 1;
       
   306 		iRecordFormat().iChannels = 1;
       
   307 		iDeviceConfig.iChannels = EMMFMono;
       
   308 		}
       
   309 	else if (attributeValue) 
       
   310 		{ //if no attribute value assume its not set
       
   311 		User::Leave(KErrNotSupported);
       
   312 		}
       
   313 	}
       
   314 
       
   315 /*
       
   316  *
       
   317  *	Changes the current playback volume to a specified value.
       
   318  *
       
   319  *	The volume can be changed before or during playback and is effective
       
   320  *	immediately.
       
   321  *
       
   322  *	@param	"TInt aVolume"
       
   323  *			The volume setting. This can be any value from zero to the value
       
   324  *			returned by a call to CMdaAudioPlayerUtility::MaxVolume(). If the
       
   325  *			volume is not within this range, the volume is automatically set to
       
   326  *			minimum or maximum value based on the value that is being passed.
       
   327  *			Setting a zero value mutes the sound. Setting the maximum value
       
   328  *			results in the loudest possible sound.
       
   329  *
       
   330  */
       
   331 void CMMFDevSoundSvrImp::SetVolume(TInt aVolume)
       
   332 	{
       
   333 
       
   334 	// Check and make sure that the volume is in valid range
       
   335 	if (aVolume < 0)
       
   336 		aVolume = 0;
       
   337 
       
   338 	if (aVolume > MaxVolume())
       
   339 		aVolume = MaxVolume();
       
   340 
       
   341 	iVolume = aVolume;
       
   342 
       
   343 	SetDeviceVolume(iVolume);
       
   344 	}
       
   345 
       
   346 /*
       
   347  *
       
   348  *	Changes the current recording gain to a specified value.
       
   349  *
       
   350  *	The gain can be changed before or during recording and is effective
       
   351  *	immediately.
       
   352  *
       
   353  *	@param	"TInt aGain"
       
   354  *			The volume setting. This can be any value from zero to the value
       
   355  *			returned by a call to CMdaAudioPlayerUtility::MaxVolume(). If the
       
   356  *			volume is not within this range, the gain is automatically set to
       
   357  *			minimum or maximum value based on the value that is being passed.
       
   358  *			Setting a zero value mutes the sound. Setting the maximum value
       
   359  *			results in the loudest possible sound.
       
   360  *
       
   361  */
       
   362 void CMMFDevSoundSvrImp::SetGain(TInt aGain)
       
   363 	{
       
   364 	// make sure it falls with the correct range
       
   365 	TInt maxGain = iRecordFormatsSupported().iMaxVolume;
       
   366 	if (aGain > maxGain)
       
   367 		aGain = maxGain;
       
   368 	else if (aGain < 0)
       
   369 		aGain = 0;
       
   370 	iGain = aGain;
       
   371 	SetDeviceRecordLevel(iGain);
       
   372 	}
       
   373 
       
   374 /*
       
   375  *
       
   376  *	Sets the speaker balance for playing.
       
   377  *
       
   378  *	The speaker balance can be changed before or during playback and is
       
   379  *	effective immediately.
       
   380  *
       
   381  *	@param	"TInt& aLeftPercentage"
       
   382  *			On return contains left speaker volume perecentage. This can be any
       
   383  *			value from zero to 100. Setting a zero value mutes the sound on left
       
   384  *			speaker.
       
   385  *
       
   386  *	@param	"TInt& aRightPercentage"
       
   387  *			On return contains right speaker volume perecentage. This can be any
       
   388  *			value from zero to 100. Setting a zero value mutes the sound on
       
   389  *			right speaker.
       
   390  *
       
   391  */
       
   392 void CMMFDevSoundSvrImp::SetPlayBalanceL(TInt aLeftPercentage, TInt aRightPercentage)
       
   393 	{
       
   394 	if (aLeftPercentage < 0)
       
   395 		aLeftPercentage = 0;
       
   396 	else if (aLeftPercentage > 100)
       
   397 		aLeftPercentage = 100;
       
   398 	if (aRightPercentage < 0)
       
   399 		aRightPercentage = 0;
       
   400 	else if (aRightPercentage > 100)
       
   401 		aRightPercentage = 100;
       
   402 	iLeftPlayBalance = aLeftPercentage;
       
   403 	iRightPlayBalance = aRightPercentage;
       
   404 	}
       
   405 
       
   406 /*
       
   407  *
       
   408  *	Sets the microphone gain balance for recording.
       
   409  *
       
   410  *	The microphone gain balance can be changed before or during recording and
       
   411  *	is effective immediately.
       
   412  *
       
   413  *	@param	"TInt aLeftPercentage"
       
   414  *			Left microphone gain precentage. This can be any value from zero to
       
   415  *			100. Setting a zero value mutes the gain on left microphone.
       
   416  *
       
   417  *	@param	"TInt aRightPercentage"
       
   418  *			Right microphone gain precentage. This can be any value from zero to
       
   419  *			100. Setting a zero value mutes the gain on right microphone.
       
   420  *
       
   421  */
       
   422 void CMMFDevSoundSvrImp::SetRecordBalanceL(TInt aLeftPercentage, TInt aRightPercentage)
       
   423 	{
       
   424 	if (aLeftPercentage < 0)
       
   425 		aLeftPercentage = 0;
       
   426 	else if (aLeftPercentage > 100)
       
   427 		aLeftPercentage = 100;
       
   428 	if (aRightPercentage < 0)
       
   429 		aRightPercentage = 0;
       
   430 	else if (aRightPercentage > 100)
       
   431 		aRightPercentage = 100;
       
   432 	iLeftRecordBalance = aLeftPercentage;
       
   433 	iRightRecordBalance = aRightPercentage;
       
   434 	}
       
   435 
       
   436 /*
       
   437  *
       
   438  *	Initializes audio device and start play process. This method queries and
       
   439  *	acquires the audio policy before initializing audio device. If there was an
       
   440  *	error during policy initialization, PlayError() method will be called on
       
   441  *	the observer with error code KErrAccessDenied, otherwise BufferToBeFilled()
       
   442  *	method will be called with a buffer reference. After reading data into the
       
   443  *	buffer reference passed, the client should call PlayData() to play data.
       
   444  *
       
   445  *	The amount of data that can be played is specified in
       
   446  *	CMMFBuffer::RequestSize(). Any data that is read into buffer beyond this
       
   447  *	size will be ignored.
       
   448  *
       
   449  *	Leaves on failure.
       
   450  *
       
   451  */
       
   452 void CMMFDevSoundSvrImp::PlayInitL()
       
   453 	{
       
   454 	if (!iDevSoundObserver)
       
   455 		User::Leave(KErrNotReady);
       
   456 
       
   457 	if (iAudioPolicyPrioritySettings.iState == EMMFStatePlayData)
       
   458 		{
       
   459 		// If policy has not been obtaing then ignore the request.
       
   460 		// If it has then do a stop and start action on HW device
       
   461 		// without informing policy.
       
   462 		
       
   463 		if (iHasPolicy)
       
   464 			{
       
   465 			if (iCMMFHwDevice)
       
   466 				{
       
   467 				TInt err = iCMMFHwDevice->Stop();
       
   468 				if (err == KErrNone)
       
   469 					{
       
   470 					err = iCMMFHwDevice->Start(EDevDecode, EDevOutFlow);
       
   471 					}
       
   472 				
       
   473 				if (err != KErrNone)
       
   474 					{
       
   475 					Error(err);
       
   476 					}
       
   477 				}
       
   478 			}
       
   479 		return;
       
   480 		}
       
   481 
       
   482 	// Get audio policy
       
   483 	iAudioPolicyPrioritySettings.iState = EMMFStatePlayData;
       
   484 	RequestPolicy();
       
   485 	}
       
   486 
       
   487 /*
       
   488  *
       
   489  *	Initializes audio device and start record process. 
       
   490  *  This method:
       
   491  *  1. Queries and acquires the audio policy before initializing audio device. 
       
   492  *     If there was an error during policy initialization, RecordError() method will 
       
   493  *     be called on the observer with error code KErrAccessDenied, otherwise BufferToBeEmptied()
       
   494  *	   method will be called with a buffer reference. This buffer contains recorded
       
   495  *	   or encoded data. After processing data in the buffer reference passed, the
       
   496  *	   client should call RecordData() to continue recording process.
       
   497  *
       
   498  *  2. Checks if the requesting client process has a UserEnvironment capability.
       
   499  *     If it does not, the audio device will not be initialized and an error 
       
   500  *     code KErrAccessDenied will be sent to the client.
       
   501  *
       
   502  *	The amount of data that is available is specified in
       
   503  *	CMMFBuffer::RequestSize().
       
   504  *
       
   505  *	Leaves on failure.
       
   506  *
       
   507  */
       
   508 void CMMFDevSoundSvrImp::RecordInitL(const RMmfIpcMessage& aMessage)
       
   509 	{
       
   510 	if (!iDevSoundObserver)
       
   511 		User::Leave(KErrNotReady);
       
   512 	
       
   513 	// Checkes if the client has the UserEnvironment capability
       
   514 	if (!aMessage.HasCapability(ECapabilityUserEnvironment))
       
   515 		{
       
   516 		User::Leave(KErrPermissionDenied);
       
   517 		}
       
   518 
       
   519 	if (iAudioPolicyPrioritySettings.iState == EMMFStateRecordData)
       
   520 		{
       
   521 		if (iHasPolicy)
       
   522 			{
       
   523 			if (iCMMFHwDevice)
       
   524 				{
       
   525 				TInt err = iCMMFHwDevice->Stop();
       
   526 				if (err == KErrNone)
       
   527 					{
       
   528 					err = iCMMFHwDevice->Start(EDevDecode, EDevOutFlow);
       
   529 					}
       
   530 				
       
   531 				if (err != KErrNone)
       
   532 					{
       
   533 					Error(err);
       
   534 					}
       
   535 				
       
   536 				if (iHwDeviceBuffer)
       
   537 					{
       
   538 					iHwDeviceBuffer->SetLastBuffer(EFalse);
       
   539 					}
       
   540 				}
       
   541 			}
       
   542 		
       
   543 		return;
       
   544 		}
       
   545 
       
   546 	// Get audio policy
       
   547 	iAudioPolicyPrioritySettings.iState = EMMFStateRecordData;
       
   548 	RequestPolicy();
       
   549 	}
       
   550 
       
   551 /*
       
   552  *
       
   553  *	Plays data in the buffer at the current volume. The client should fill
       
   554  *	the buffer with audio data before calling this method. The Observer gets
       
   555  *	reference to buffer along with callback BufferToBeFilled(). When playing of
       
   556  *	the audio sample is complete, successfully or otherwise, the method
       
   557  *	PlayError() on observer is called.
       
   558  *
       
   559  */
       
   560 TBool CMMFDevSoundSvrImp::PlayData(const RMmfIpcMessage& aMessage)
       
   561 	{
       
   562 	ASSERT(iDevSoundObserver);
       
   563 
       
   564 	if (iAudioPolicyPrioritySettings.iState == EMMFStateStopped)
       
   565 		{
       
   566 		// Initialisation has been successful but an error (possibly underflow) has occurred
       
   567 		// which the controller has yet to respond to and that has changed the state to stopped.
       
   568 		// Allow the call to complete and processing to continue...  
       
   569 		return ETrue;
       
   570 		}
       
   571 
       
   572 	if((iAudioPolicyPrioritySettings.iState != EMMFStatePlayData) && (iAudioPolicyPrioritySettings.iState != EMMFStatePaused))
       
   573 		{
       
   574 		PanicClient(aMessage, EMMFDevSoundPlayDataWithoutInitialize);
       
   575 		return EFalse;
       
   576 		}
       
   577 	if (iMode== EMMFDevSoundStateIdle)
       
   578 		{
       
   579 		return ETrue;
       
   580 		}
       
   581 	TInt error = KErrNone;
       
   582     if(iCMMFHwDevice)
       
   583 	    {
       
   584 		if (iPaused)
       
   585 			{
       
   586 			iPaused = EFalse;
       
   587 			//note PlayData does not leave or return an error code so the Start() fails we cannot
       
   588 			//report the error back at this point
       
   589 			error = iCMMFHwDevice->Start(EDevDecode, EDevOutFlow);//restart hw device after pause
       
   590 			}
       
   591 	   else if ((iMode == EMMFDevSoundStatePlaying) && iHasPolicy)
       
   592 		    {
       
   593 		    TInt len = iHwDeviceBuffer->Data().Length();
       
   594 		    if (iHwDeviceBuffer->LastBuffer())
       
   595 		    	{
       
   596 		    	iLastBufferReceived = ETrue;
       
   597 		    	}
       
   598 			// Pass the data buffer to HwDevice
       
   599 			error = iCMMFHwDevice->ThisHwBufferFilled(*iHwDeviceBuffer);
       
   600             }
       
   601 		}
       
   602 	if (error != KErrNone)
       
   603 		{
       
   604 		Error(error);
       
   605 		if(iCMMFHwDevice)
       
   606 			{
       
   607 			iCMMFHwDevice->Stop();	
       
   608 			}
       
   609 
       
   610 		}
       
   611 	return ETrue;
       
   612 	}
       
   613  
       
   614 /*
       
   615  *
       
   616  *	Stops the ongoing operation (Play, Record, TonePlay, Convert)
       
   617  *
       
   618  */
       
   619 void CMMFDevSoundSvrImp::Stop()
       
   620 	{
       
   621 	iPaused = EFalse;
       
   622 
       
   623 	if (!iHasPolicy)
       
   624 		{
       
   625 		UpdatePolicyState(EMMFStateStopped);
       
   626 		return;
       
   627 		}
       
   628 
       
   629 	 // Stop the hw device first - this unloads sound drivers
       
   630     if (iCMMFHwDevice)
       
   631     	{
       
   632 		iCMMFHwDevice->Stop();
       
   633 		}
       
   634 
       
   635 	iDevSoundEventHandler->CancelReceiveEvents();
       
   636 
       
   637 	UpdatePolicyState(EMMFStateStopped);
       
   638 	__ASSERT_DEBUG(!(iHasPolicy&&(iMode == EMMFDevSoundStatePlaying)), Panic(TMMFDevSoundSessionPolicyNotInvalidated)); 
       
   639 	}
       
   640 
       
   641 /*
       
   642  *
       
   643  *	Temporarily Stops the ongoing operation (Play, Record, TonePlay, Convert)
       
   644  *
       
   645  */
       
   646 void CMMFDevSoundSvrImp::Pause()
       
   647 	{
       
   648 	iPaused = ETrue;
       
   649 
       
   650 	if (!iHasPolicy)
       
   651 		{
       
   652 		return;
       
   653 		}
       
   654 
       
   655 	// Pause the HW device first
       
   656 	if (iCMMFHwDevice)
       
   657 		{
       
   658 		iCMMFHwDevice->Pause();
       
   659 		}
       
   660 	}
       
   661 
       
   662 /*
       
   663  *
       
   664  *	Returns the sample recorded so far.
       
   665  *
       
   666  *	@return "TInt"
       
   667  *			Returns the samples recorded.
       
   668  *
       
   669  */
       
   670 TInt CMMFDevSoundSvrImp::SamplesRecorded()
       
   671 	{
       
   672 	TInt samples = 0;
       
   673 	
       
   674 	if(iRecordCustomInterface)
       
   675 		{
       
   676 		samples = iRecordCustomInterface->BytesRecorded();
       
   677 		if(NumberOfChannels() > 1)
       
   678 			{
       
   679 			samples /= NumberOfChannels();
       
   680 			}
       
   681 		if(BytesPerAudioSample() > 1)
       
   682 			{
       
   683 			samples /= BytesPerAudioSample();
       
   684 			}
       
   685 		}
       
   686 
       
   687 	return samples;
       
   688 	}
       
   689 
       
   690 /*
       
   691  *
       
   692  *	Returns the sample played so far.
       
   693  *
       
   694  *	@return "TInt"
       
   695  *			Returns the samples recorded.
       
   696  *
       
   697  */
       
   698 TInt CMMFDevSoundSvrImp::SamplesPlayed()
       
   699 	{
       
   700 	TInt samples = 0;
       
   701 	if(iPlayCustomInterface)
       
   702 		{
       
   703 		TUint bytesPlayed = iPlayCustomInterface->BytesPlayed();
       
   704 		if (bytesPlayed)
       
   705 			iPlayedBytesCount = bytesPlayed;
       
   706 
       
   707 		samples = iPlayedBytesCount;
       
   708 		if(NumberOfChannels() > 1)
       
   709 			samples /= NumberOfChannels();
       
   710 
       
   711 		if(BytesPerAudioSample() > 1)
       
   712 			samples /= BytesPerAudioSample();
       
   713 		}
       
   714 	//note always pcm16 becuase the iPlayedBytesCount originates from 
       
   715 	//RMdaDevSound which is always pcm16
       
   716 	return samples; //each sample is 2 bytes
       
   717 	}
       
   718 
       
   719 
       
   720 /*
       
   721  *
       
   722  *	Initializes audio device and start playing tone. Tone is played with
       
   723  *	frequency and for duration specified.
       
   724  *
       
   725  *	Leaves on failure.
       
   726  *
       
   727  *	@param	"TInt aFrequency"
       
   728  *			Frequency at with the tone will be played.
       
   729  *
       
   730  *	@param	"TTimeIntervalMicroSeconds& aDuration"
       
   731  *			The period over which the tone will be played. A zero value causes
       
   732  *			the no tone to be played (Verify this with test app).
       
   733  *
       
   734  */
       
   735 void CMMFDevSoundSvrImp::PlayToneL(TInt aFrequency, const TTimeIntervalMicroSeconds& aDuration)
       
   736 	{
       
   737 	if (iMode != EMMFDevSoundStateTonePlaying)
       
   738 		{
       
   739 		User::Leave(KErrNotSupported); //tone playing only supported in tone play state
       
   740 		}
       
   741 
       
   742 	// Check whether frequency and duration is valid or not
       
   743 	TInt64 zeroInt64(0);
       
   744 	if ((aFrequency<0) || (aDuration.Int64() < zeroInt64))
       
   745 		{
       
   746 		User::Leave(KErrArgument);
       
   747 		}
       
   748 
       
   749 	if (!iDevSoundObserver)
       
   750 		{
       
   751 		User::Leave(KErrNotReady);
       
   752 		}
       
   753 
       
   754 	iToneGen.SetFrequencyAndDuration(aFrequency,aDuration);
       
   755 
       
   756 	// Get audio policy
       
   757 	iAudioPolicyPrioritySettings.iState = EMMFStatePlayTone;
       
   758 	RequestPolicy();
       
   759 	}
       
   760 
       
   761 /*
       
   762  *	Initializes audio device and start playing a dual tone. 
       
   763  *  The tone consists of two sine waves of different frequencies summed together
       
   764  *  Dual Tone is played with specified frequencies and for specified duration.
       
   765  *
       
   766  *	@param	"aFrequencyOne"
       
   767  *			First frequency of dual tone
       
   768  *
       
   769  *	@param	"aFrequencyTwo"
       
   770  *			Second frequency of dual tone
       
   771  *
       
   772  *	@param	"aDuration"
       
   773  *			The period over which the tone will be played. A zero value causes
       
   774  *			the no tone to be played (Verify this with test app).
       
   775  */
       
   776 void CMMFDevSoundSvrImp::PlayDualToneL(TInt aFrequencyOne, TInt aFrequencyTwo, const TTimeIntervalMicroSeconds& aDuration)
       
   777 	{
       
   778 	if (!iDevSoundObserver)
       
   779 		{
       
   780 		User::Leave(KErrNotReady);
       
   781 		}
       
   782 	
       
   783 	// Check whether frequencies and duration are valid or not
       
   784 	TInt64 zeroInt64(0);
       
   785 	if ((aFrequencyOne<0) || (aFrequencyTwo<0) || (aDuration.Int64() < zeroInt64))
       
   786 		{
       
   787 		iDevSoundObserver->ToneFinished(KErrArgument);
       
   788 		return;
       
   789 		}
       
   790 
       
   791 
       
   792 	iDualToneGen.SetFrequencyAndDuration(aFrequencyOne, aFrequencyTwo, aDuration);
       
   793 
       
   794 	// Get audio policy
       
   795 	iAudioPolicyPrioritySettings.iState = EMMFStatePlayDualTone;
       
   796 	RequestPolicy();
       
   797 	}
       
   798 
       
   799 /*
       
   800  *
       
   801  *	Initializes audio device and start playing DTMF string aDTMFString.
       
   802  *
       
   803  *	Leaves on failure.
       
   804  *
       
   805  *	@param	"TDesC& aDTMFString"
       
   806  *			DTMF sequence in a descriptor.
       
   807  *
       
   808  */
       
   809 void CMMFDevSoundSvrImp::PlayDTMFStringL(const TDesC& aDTMFString)
       
   810 	{
       
   811 	if (!iDevSoundObserver)
       
   812 		User::Leave(KErrNotReady);
       
   813 
       
   814 	if (iMode!= EMMFDevSoundStateTonePlaying)
       
   815 		User::Leave(KErrNotSupported); //tone playing only supported in tone play state
       
   816 
       
   817 	iDTMFGen.SetString(aDTMFString);
       
   818 
       
   819 	// Get audio policy
       
   820 	iAudioPolicyPrioritySettings.iState = EMMFStatePlayDTMFString;
       
   821 	RequestPolicy();
       
   822 	}
       
   823 
       
   824 /*
       
   825  *
       
   826  *	Initializes audio device and start playing tone sequence.
       
   827  *
       
   828  *	Leaves on failure.
       
   829  *
       
   830  *	@param	"TDesC8& aData"
       
   831  *			Tone sequence in a descriptor.
       
   832  *
       
   833  */
       
   834 void CMMFDevSoundSvrImp::PlayToneSequenceL(const TDesC8& aData)
       
   835 	{
       
   836 	if (!iDevSoundObserver)
       
   837 		User::Leave(KErrNotReady);
       
   838 
       
   839 	if (iMode!= EMMFDevSoundStateTonePlaying)
       
   840 		User::Leave(KErrNotSupported); //tone playing only supported in tone play state
       
   841 
       
   842 	// Check whether the sequence is valid or not
       
   843 	if (!iDevSoundUtil->RecognizeSequence(aData))
       
   844 		User::Leave(KErrCorrupt);
       
   845 
       
   846 	iSequenceGen.SetSequenceData(aData);
       
   847 
       
   848 	// Get audio policy
       
   849 	iAudioPolicyPrioritySettings.iState = EMMFStatePlayToneSequence;
       
   850 	RequestPolicy();
       
   851 	}
       
   852 
       
   853 /*
       
   854  *
       
   855  *	Initializes audio device and start playing the specified pre-defined tone
       
   856  *	sequence.
       
   857  *
       
   858  *	Leaves on failure.
       
   859  *
       
   860  *	@param	"TInt aSequenceNumber"
       
   861  *			The index identifying the specific pre-defined tone sequence. Index
       
   862  *			values are relative to zero.
       
   863  *			This can be any value from zero to the value returned by a call to
       
   864  *			FixedSequenceCount() - 1.
       
   865  *			The function raises a panic if sequence number is not within this
       
   866  *			range.
       
   867  *
       
   868  *	@see	FixesSequenceCount()
       
   869  *
       
   870  */
       
   871 void CMMFDevSoundSvrImp::PlayFixedSequenceL(TInt aSequenceNumber)
       
   872 	{
       
   873 	if (!iDevSoundObserver)
       
   874 		User::Leave(KErrNotReady);
       
   875 
       
   876 	if (iMode!= EMMFDevSoundStateTonePlaying)
       
   877 		User::Leave(KErrNotSupported); //tone playing only supported in tone play state
       
   878 
       
   879 	ASSERT((aSequenceNumber >= 0)&&(aSequenceNumber < iFixedSequences->Count()));
       
   880 
       
   881 	iFixedSequence.Set(iFixedSequences->MdcaPoint(aSequenceNumber));
       
   882 	iSequenceGen.SetSequenceData(iFixedSequence);
       
   883 
       
   884 	// Get audio policy
       
   885 	iAudioPolicyPrioritySettings.iState = EMMFStatePlayToneSequence;
       
   886 	RequestPolicy();
       
   887 	}
       
   888 
       
   889 /*
       
   890  *
       
   891  *	Defines the duration of tone on, tone off and tone pause to be used during the
       
   892  *	DTMF tone playback operation.
       
   893  *
       
   894  *	Supported only during tone playing.
       
   895  *
       
   896  *	@param	"TTimeIntervalMicroSeconds32& aToneOnLength"
       
   897  *			The period over which the tone will be played. If this is set to
       
   898  *			zero, then the tone is not played.
       
   899  *
       
   900  *	@param	"TTimeIntervalMicroSeconds32& aToneOffLength"
       
   901  *			The period over which the no tone will be played.
       
   902  *
       
   903  *	@param	"TTimeIntervalMicroSeconds32& aPauseLength"
       
   904  *			The period over which the tone playing will be paused.
       
   905  *
       
   906  */
       
   907 void CMMFDevSoundSvrImp::SetDTMFLengths(TTimeIntervalMicroSeconds32& aToneOnLength,
       
   908 								TTimeIntervalMicroSeconds32& aToneOffLength,
       
   909 								TTimeIntervalMicroSeconds32& aPauseLength) 
       
   910 	{
       
   911 
       
   912 	if(aToneOnLength.Int() < KMdaInfiniteDurationDTMFToneOnLength)
       
   913 		aToneOnLength = TTimeIntervalMicroSeconds32(0);
       
   914 	if(aToneOffLength.Int() < 0)
       
   915 		aToneOffLength = TTimeIntervalMicroSeconds32(0);
       
   916 	if(aPauseLength.Int() < 0)
       
   917 		aPauseLength = TTimeIntervalMicroSeconds32(0);
       
   918 
       
   919 	iDTMFGen.SetToneDurations(aToneOnLength,aToneOffLength,aPauseLength);
       
   920 	}
       
   921 
       
   922 /*
       
   923  *
       
   924  *	Defines the period over which the volume level is to rise smoothly from
       
   925  *	nothing to the normal volume level.
       
   926  *
       
   927  *	@param	"TTimeIntervalMicroSeconds& aRampDuration"
       
   928  *			The period over which the volume is to rise. A zero value causes 
       
   929  *			the tone sample to be played at the normal level for the full
       
   930  *			duration of the playback. A value, which is longer than the duration
       
   931  *			of the tone sample, that the sample never reaches its normal
       
   932  *			volume level.
       
   933  *
       
   934  *
       
   935  */
       
   936 void CMMFDevSoundSvrImp::SetVolumeRamp(const TTimeIntervalMicroSeconds& aRampDuration)
       
   937 	{
       
   938 	// save ramp duration for tone generator
       
   939 	iRampDuration = aRampDuration;
       
   940 
       
   941 	SetDeviceVolumeRamp(iRampDuration);
       
   942 	}
       
   943 
       
   944 /**
       
   945  *	Sets volume ramp on HwDevice.
       
   946  */
       
   947 TInt CMMFDevSoundSvrImp::SetDeviceVolumeRamp(const TTimeIntervalMicroSeconds& aRampDuration)
       
   948 	{
       
   949 	TInt error = KErrNone;
       
   950 	if (iPlayCustomInterface) 
       
   951 		iPlayCustomInterface->SetVolumeRamp(aRampDuration);
       
   952 	else
       
   953 		error = KErrNotReady;
       
   954 	return error;
       
   955     }
       
   956 
       
   957 /**
       
   958  *	@see sounddevice.h
       
   959  */
       
   960 void CMMFDevSoundSvrImp::GetSupportedInputDataTypesL(RArray<TFourCC>& aSupportedDataTypes, const TMMFPrioritySettings& /*aPrioritySettings*/) const
       
   961 	{
       
   962 	//aPrioritySettings not used on ref DevSound
       
   963 	//search for playing datatypes
       
   964 	iDevSoundUtil->SeekHwDevicePluginsL(aSupportedDataTypes, EMMFStatePlaying);
       
   965 #ifdef SYMBIAN_MULTIMEDIA_CODEC_API
       
   966 	// append list of codec plugins
       
   967 	iDevSoundUtil->SeekCodecPluginsL(aSupportedDataTypes, EMMFStatePlaying, ETrue);
       
   968 #endif // SYMBIAN_MULTIMEDIA_CODEC_API
       
   969 	}
       
   970 
       
   971 /**
       
   972  *	@see sounddevice.h
       
   973  */
       
   974 void CMMFDevSoundSvrImp::GetSupportedOutputDataTypesL(RArray<TFourCC>& aSupportedDataTypes, const TMMFPrioritySettings& /*aPrioritySettings*/) const
       
   975 	{
       
   976 	//aPrioritySettings not used on ref DevSound
       
   977 	// search for recording datatypes
       
   978 	iDevSoundUtil->SeekHwDevicePluginsL(aSupportedDataTypes, EMMFStateRecording);
       
   979 #ifdef SYMBIAN_MULTIMEDIA_CODEC_API
       
   980 	// append list of codec plugins
       
   981 	iDevSoundUtil->SeekCodecPluginsL(aSupportedDataTypes, EMMFStateRecording, ETrue);
       
   982 #endif // SYMBIAN_MULTIMEDIA_CODEC_API
       
   983 	}
       
   984 	
       
   985 TInt CMMFDevSoundSvrImp::RegisterAsClient(TUid aEventType, const TDesC8& aNotificationRegistrationData)
       
   986 	{	
       
   987 	return iAudioPolicyProxy->RequestResourceNotification(aEventType,aNotificationRegistrationData);
       
   988 	}
       
   989 	
       
   990 TInt CMMFDevSoundSvrImp::CancelRegisterAsClient(TUid aEventType)
       
   991 	{	
       
   992 	return iAudioPolicyProxy->CancelRequestResourceNotification(aEventType);
       
   993 	}
       
   994 
       
   995 TInt CMMFDevSoundSvrImp::GetResourceNotificationData(TUid aEventType, TDes8& aNotificationData)
       
   996 	{	
       
   997 	TInt err = KErrNone;
       
   998 	err = iAudioPolicyProxy->IsRegisteredResourceNotification(aEventType);
       
   999 	if(err == KErrNone)
       
  1000 		{
       
  1001 		TMMFTimeIntervalMicroSecondsPckg pckg = TTimeIntervalMicroSeconds(SamplesPlayed());
       
  1002 		aNotificationData.Copy(pckg);
       
  1003 		}
       
  1004 	return err;
       
  1005 	}
       
  1006 	
       
  1007 TInt CMMFDevSoundSvrImp::WillResumePlay()
       
  1008 	{
       
  1009 	return iAudioPolicyProxy->StopNotification();
       
  1010 	}	
       
  1011 	
       
  1012 TInt CMMFDevSoundSvrImp::EmptyBuffers()
       
  1013 	{
       
  1014 	TInt err = KErrNone;
       
  1015 	if (iMode != EMMFStatePlaying)
       
  1016 		{
       
  1017 		return KErrNotSupported;
       
  1018 		}
       
  1019 	if (!iCMMFHwDevice)
       
  1020 		{
       
  1021 		return KErrNotReady;			
       
  1022 		}	
       
  1023 	MEmptyBuffersCustomInterface* emptybuffers = reinterpret_cast<MEmptyBuffersCustomInterface*>(iCMMFHwDevice->CustomInterface(KEmptyBuffersCustomInterfaceTypeUid));	
       
  1024 	if (emptybuffers)
       
  1025     	{
       
  1026        	err = emptybuffers->EmptyBuffers();
       
  1027      	}
       
  1028     else
       
  1029 		{
       
  1030      	err = KErrNotSupported;
       
  1031      	}
       
  1032     return err;	
       
  1033 	}	
       
  1034 
       
  1035 TInt CMMFDevSoundSvrImp::GetTimePlayed(TTimeIntervalMicroSeconds& aTime)
       
  1036 	{
       
  1037 	TInt err = KErrNone;
       
  1038 	TTimeIntervalMicroSeconds time(0);
       
  1039 	if(iCMMFHwDevice)
       
  1040 		{
       
  1041 		if(!iTimePlayedCustomInterface)
       
  1042 			{
       
  1043 			iTimePlayedCustomInterface = reinterpret_cast<MTimePlayedCustomInterface*>(iCMMFHwDevice->CustomInterface(KTimePlayedCustomInterfaceTypeUid));
       
  1044 			if(iTimePlayedCustomInterface == NULL)
       
  1045 				{
       
  1046 				return KErrNotSupported;
       
  1047 				}
       
  1048 			}
       
  1049 		err = iTimePlayedCustomInterface->GetTimePlayed(time);
       
  1050 	    if(err == KErrNone && time.Int64() > 0)
       
  1051 	    	{
       
  1052 	    	iTimePlayed = time.Int64();
       
  1053 	    	}
       
  1054 		}
       
  1055 	aTime = iTimePlayed.Int64();
       
  1056 	return err;
       
  1057 	}
       
  1058 
       
  1059 /********************************************************************************
       
  1060  *				Implementations of Non Exported public functions begins here	*
       
  1061  ********************************************************************************/
       
  1062 
       
  1063 //
       
  1064 //				Audio Policy specific implementation begins here				//
       
  1065 //
       
  1066 
       
  1067 /*
       
  1068  *
       
  1069  *	Called by Audio Policy Server when a request to play is approved by the 
       
  1070  *	Audio Policy Server.
       
  1071  *
       
  1072  *	Leaves on failure??.
       
  1073  *
       
  1074  */
       
  1075 void CMMFDevSoundSvrImp::StartPlayDataL()
       
  1076 	{
       
  1077 	ASSERT(iMode== EMMFDevSoundStatePlaying);
       
  1078 	if(iAudioPolicyPrioritySettings.iState == EMMFStateStopped)
       
  1079 		{
       
  1080 		return;
       
  1081 		}
       
  1082 	iHasPolicy = ETrue;
       
  1083 
       
  1084 	TInt error = KErrNone;
       
  1085 
       
  1086 	if(iCMMFHwDevice)
       
  1087 		{
       
  1088 		UpdatePolicyState(EMMFStatePlayData);		
       
  1089         // Set volume and play format values
       
  1090         error = SetPlayFormat(iPlayFormat);
       
  1091         if (error == KErrNone)
       
  1092 			error = SetDeviceVolume(iVolume);
       
  1093         if (error == KErrNone)
       
  1094 			error = SetDeviceVolumeRamp(iRampDuration);
       
  1095 
       
  1096 		// Initialize attribute values
       
  1097 		iPlayedBytesCount = 0;
       
  1098 		iTimePlayed = 0;
       
  1099 		iLastBufferReceived = EFalse;
       
  1100 
       
  1101         // Start HwDevice
       
  1102         if (error == KErrNone)
       
  1103 	        error = iCMMFHwDevice->Start(EDevDecode, EDevOutFlow);
       
  1104 		}
       
  1105 	else
       
  1106 		error = KErrNotReady;
       
  1107 	
       
  1108 	if (error != KErrNone)
       
  1109 		{
       
  1110 		Error(error);
       
  1111 
       
  1112 		}
       
  1113 	}
       
  1114 
       
  1115 /*
       
  1116  *
       
  1117  *	Called by Audio Policy Server when a request to record is approved by the 
       
  1118  *	Audio Policy Server.
       
  1119  *
       
  1120  *	Leaves on failure.
       
  1121  *
       
  1122  */
       
  1123 void CMMFDevSoundSvrImp::StartRecordDataL()
       
  1124 	{
       
  1125 	ASSERT(iMode== EMMFDevSoundStateRecording);
       
  1126 	if(iAudioPolicyPrioritySettings.iState == EMMFStateStopped)
       
  1127 		{
       
  1128 		return;
       
  1129 		}
       
  1130 	iHasPolicy = ETrue;
       
  1131 
       
  1132 	 if(iCMMFHwDevice)
       
  1133 		{
       
  1134 		UpdatePolicyState(EMMFStateRecordData);
       
  1135         TInt error = KErrNone;
       
  1136         error = SetRecordFormat(iRecordFormat);
       
  1137 		if (error != KErrNone)
       
  1138 			{
       
  1139 			Error(error);
       
  1140 			return;
       
  1141 
       
  1142 			}
       
  1143         error = SetDeviceRecordLevel(iGain);
       
  1144 		if (error != KErrNone)
       
  1145 			{
       
  1146 			Error(error);
       
  1147 			return;
       
  1148 
       
  1149 			}
       
  1150         error = iCMMFHwDevice->Start(EDevEncode, EDevInFlow);
       
  1151 		if (iHwDeviceBuffer)
       
  1152 			iHwDeviceBuffer->SetLastBuffer(EFalse);
       
  1153 
       
  1154 		if (error != KErrNone)
       
  1155 			{
       
  1156 			Error(error);
       
  1157 			return;
       
  1158 			}
       
  1159         }
       
  1160 	else
       
  1161 		iDevSoundObserver->RecordError(KErrNotReady);
       
  1162 	}
       
  1163 
       
  1164 /*
       
  1165  *
       
  1166  *	Called by Audio Policy Server when a request to play tone is approved by
       
  1167  *	the Audio Policy Server.
       
  1168  *
       
  1169  *	Leaves on failure.
       
  1170  *
       
  1171  */
       
  1172 void CMMFDevSoundSvrImp::StartPlayToneL()
       
  1173 	{
       
  1174 	ASSERT(iMode == EMMFDevSoundStateTonePlaying);
       
  1175 	if(iAudioPolicyPrioritySettings.iState == EMMFStateStopped)
       
  1176 		{
       
  1177 		return;
       
  1178 		}
       
  1179 	iHasPolicy = ETrue;
       
  1180 	
       
  1181 	if(iCMMFHwDevice)
       
  1182 		{
       
  1183 		UpdatePolicyState(EMMFStatePlayTone);
       
  1184         TInt error = KErrNone;
       
  1185         // Set volume and play format values
       
  1186         error = SetPlayFormat(iPlayFormat);
       
  1187 		if (error != KErrNone)
       
  1188 			{
       
  1189 			Error(error);
       
  1190 			return;
       
  1191 
       
  1192 			}
       
  1193         if (iHwDeviceID.iUid == KMmfUidHwDevicePCM16ToPCM16)
       
  1194             error = SetDeviceVolume(iVolume);
       
  1195 		else
       
  1196 			error = KErrGeneral;//hw device should always be pcm16 for tone
       
  1197 
       
  1198 		// turn off volume ramping - this is done in software below
       
  1199         if (error == KErrNone)
       
  1200 			error = SetDeviceVolumeRamp(TTimeIntervalMicroSeconds(0));
       
  1201 
       
  1202         if (error != KErrNone)
       
  1203             {
       
  1204             Error(error);
       
  1205             return;
       
  1206 
       
  1207             }
       
  1208 
       
  1209         // Initialize attribute values
       
  1210 		iPlayedBytesCount = 0;
       
  1211 		iTimePlayed = 0;
       
  1212         // Configure tone generator
       
  1213         iToneGen.Configure(
       
  1214 			iPlayFormat().iRate,
       
  1215 			iPlayFormat().iChannels,
       
  1216 		    iRepeatCount,
       
  1217 			I64LOW((iRepeatTrailingSilence.Int64()*iPlayFormat().iRate)/1000000),
       
  1218 			I64LOW((iRampDuration.Int64()*iPlayFormat().iRate)/1000000)
       
  1219 			);
       
  1220 
       
  1221 		iCurrentGenerator = &iToneGen;
       
  1222 
       
  1223         // Start playback
       
  1224         DoPlayL();
       
  1225 		}
       
  1226 	else
       
  1227 		iDevSoundObserver->ToneFinished(KErrNotReady);
       
  1228 	}
       
  1229 
       
  1230 /*
       
  1231  *
       
  1232  *	Called by Audio Policy Server when a request to play a dual tone is approved by
       
  1233  *	the Audio Policy Server.
       
  1234  *
       
  1235  */
       
  1236 void CMMFDevSoundSvrImp::StartPlayDualToneL()
       
  1237 	{
       
  1238 	ASSERT(iMode == EMMFDevSoundStateTonePlaying);
       
  1239 	if(iAudioPolicyPrioritySettings.iState == EMMFStateStopped)
       
  1240 		{
       
  1241 		return;
       
  1242 		}
       
  1243 	iHasPolicy = ETrue;
       
  1244 
       
  1245 	 if(iCMMFHwDevice)
       
  1246 		{
       
  1247 		UpdatePolicyState(EMMFStatePlayDualTone);
       
  1248         TInt error = KErrNone;
       
  1249         // Set volume and play format values
       
  1250         error = SetPlayFormat(iPlayFormat);
       
  1251 		if (error != KErrNone)
       
  1252 			{
       
  1253 			Error(error);
       
  1254 			return;
       
  1255 			}
       
  1256         if (iHwDeviceID.iUid == KMmfUidHwDevicePCM16ToPCM16)
       
  1257             error = SetDeviceVolume(iVolume);
       
  1258 		else 
       
  1259 			error = KErrGeneral;//hw device should always be pcm16 for tone
       
  1260 
       
  1261 		// turn off volume ramping - this is done in software below
       
  1262         if (error == KErrNone)
       
  1263 			error = SetDeviceVolumeRamp(TTimeIntervalMicroSeconds(0));
       
  1264 
       
  1265         if (error != KErrNone)
       
  1266             {
       
  1267             Error(error);
       
  1268             return;
       
  1269 
       
  1270             }
       
  1271 
       
  1272         // Initialize attribute values
       
  1273 		iPlayedBytesCount = 0;
       
  1274 		iTimePlayed = 0;
       
  1275         // Configure dual tone generator
       
  1276 		iDualToneGen.Configure(
       
  1277 			iPlayFormat().iRate,
       
  1278 			iPlayFormat().iChannels,
       
  1279 			iRepeatCount,
       
  1280 			I64LOW((iRepeatTrailingSilence.Int64()*iPlayFormat().iRate)/KOneMillionMicroSeconds),
       
  1281 			I64LOW((iRampDuration.Int64()*iPlayFormat().iRate)/KOneMillionMicroSeconds)
       
  1282 			);
       
  1283 
       
  1284 		iCurrentGenerator = &iDualToneGen;
       
  1285 
       
  1286         // Start playback
       
  1287         DoPlayL();
       
  1288 		}
       
  1289 	else
       
  1290 		iDevSoundObserver->ToneFinished(KErrNotReady);
       
  1291 	}
       
  1292 
       
  1293 /*
       
  1294  *
       
  1295  *	Called by Audio Policy Server when a request to play DTMF String is approved
       
  1296  *	by the Audio Policy Server.
       
  1297  *
       
  1298  *	Leaves on failure.
       
  1299  *
       
  1300  */
       
  1301 void CMMFDevSoundSvrImp::StartPlayDTMFStringL()
       
  1302 	{
       
  1303 	ASSERT(iMode == EMMFDevSoundStateTonePlaying);
       
  1304 	if(iAudioPolicyPrioritySettings.iState == EMMFStateStopped)
       
  1305 		{
       
  1306 		return;
       
  1307 		}
       
  1308 	iHasPolicy = ETrue;
       
  1309 
       
  1310 	if(iCMMFHwDevice)
       
  1311 		{
       
  1312 		UpdatePolicyState(EMMFStatePlayDTMFString);
       
  1313         TInt error = KErrNone;
       
  1314         // Set volume and play format values
       
  1315         error = SetPlayFormat(iPlayFormat);
       
  1316 		if (error != KErrNone)
       
  1317             {
       
  1318             Error(error);
       
  1319             return;
       
  1320 
       
  1321             }
       
  1322         error = SetDeviceVolume(iVolume);
       
  1323 
       
  1324 		// turn off volume ramping - this is done in software below
       
  1325         if (error == KErrNone)
       
  1326 			error = SetDeviceVolumeRamp(TTimeIntervalMicroSeconds(0));
       
  1327 
       
  1328         if (error != KErrNone)
       
  1329             {
       
  1330             Error(error);
       
  1331             return;
       
  1332             }
       
  1333 
       
  1334         // Initialize attribute values
       
  1335 		iPlayedBytesCount = 0;
       
  1336 		iTimePlayed = 0;
       
  1337 	    iDTMFGen.Configure(
       
  1338 			iPlayFormat().iRate,
       
  1339 			iPlayFormat().iChannels,
       
  1340 		    iRepeatCount,
       
  1341 			I64LOW((iRepeatTrailingSilence.Int64()*iPlayFormat().iRate)/1000000),
       
  1342 		    I64LOW((iRampDuration.Int64()*iPlayFormat().iRate)/1000000)
       
  1343 			);
       
  1344 
       
  1345 		iCurrentGenerator = &iDTMFGen;
       
  1346 
       
  1347         // Start playback
       
  1348 		//need to trap this as we can leave with KErrUnderflow
       
  1349 		//if there was no data to play - the error has already
       
  1350 		//been sent to the observer and we don't want to call RunError
       
  1351         TRAP(error,DoPlayL());
       
  1352 		if ((error != KErrUnderflow)&&(error != KErrNone))
       
  1353 			{
       
  1354 			User::Leave(error);
       
  1355 			}
       
  1356 		}
       
  1357 	else
       
  1358 		iDevSoundObserver->ToneFinished(KErrNotReady);
       
  1359 	}
       
  1360 
       
  1361 /*
       
  1362  *
       
  1363  *	Called by Audio Policy Server when a request to play tone sequence is
       
  1364  *	approved by the Audio Policy Server.
       
  1365  *
       
  1366  *	Leaves on failure.
       
  1367  *
       
  1368  */
       
  1369 void CMMFDevSoundSvrImp::StartPlayToneSequenceL()
       
  1370 	{
       
  1371 	ASSERT(iMode == EMMFDevSoundStateTonePlaying);
       
  1372 	if(iAudioPolicyPrioritySettings.iState == EMMFStateStopped)
       
  1373 		{
       
  1374 		return;
       
  1375 		}
       
  1376 	iHasPolicy = ETrue;
       
  1377 
       
  1378 	if(iCMMFHwDevice)
       
  1379 		{
       
  1380 		UpdatePolicyState(EMMFStatePlayToneSequence);
       
  1381         TInt error = KErrNone;
       
  1382         // Set volume and play format values
       
  1383         if (iHwDeviceID.iUid == KMmfUidHwDevicePCM16ToPCM16)
       
  1384             error = SetPlayFormat(iPlayFormat);
       
  1385 			else error = KErrGeneral;//hw device should always be pcm16 for tone
       
  1386 		if (error != KErrNone)
       
  1387             {
       
  1388             Error(error);
       
  1389             return;
       
  1390             }
       
  1391 
       
  1392         if (iHwDeviceID.iUid == KMmfUidHwDevicePCM16ToPCM16)
       
  1393             error = SetDeviceVolume(iVolume);
       
  1394 		else 
       
  1395 			error = KErrGeneral;//hw device should always be pcm16 for tone
       
  1396 
       
  1397 		// turn off volume ramping - this is done in software below
       
  1398         if (error == KErrNone)
       
  1399 			error = SetDeviceVolumeRamp(TTimeIntervalMicroSeconds(0));
       
  1400 
       
  1401         if (error != KErrNone)
       
  1402             {
       
  1403             Error(error);
       
  1404             return;
       
  1405             }
       
  1406 
       
  1407         // Initialize attribute values
       
  1408 		iPlayedBytesCount = 0;
       
  1409 		iTimePlayed = 0;
       
  1410 		iSequenceGen.Configure(
       
  1411 			iPlayFormat().iRate,
       
  1412 			iPlayFormat().iChannels,
       
  1413 			iRepeatCount,
       
  1414 			I64LOW((iRepeatTrailingSilence.Int64()*iPlayFormat().iRate)/1000000),
       
  1415 			I64LOW((iRampDuration.Int64()*iPlayFormat().iRate)/1000000)
       
  1416 			);
       
  1417 
       
  1418 		iCurrentGenerator = &iSequenceGen;
       
  1419 
       
  1420         // Start playback
       
  1421         DoPlayL();
       
  1422 		}
       
  1423 	else
       
  1424 		iDevSoundObserver->ToneFinished(KErrNotReady);
       
  1425 	}
       
  1426 
       
  1427 /*
       
  1428  *
       
  1429  *	Called by Audio Policy Server when the current DevSound instance looses the
       
  1430  *	policy because of another instance with a higher priority wants the device.
       
  1431  *
       
  1432  */
       
  1433 void CMMFDevSoundSvrImp::SendEventToClient(const TMMFEvent& aEvent)
       
  1434 	{
       
  1435 	if (aEvent.iErrorCode != KErrNone)
       
  1436 		{
       
  1437 		iHasPolicy = EFalse;
       
  1438 		if (iMode == EMMFDevSoundStatePlaying)
       
  1439 			{
       
  1440 			UpdateBytesPlayed();
       
  1441 			iDevSoundObserver->PlayError(aEvent.iErrorCode);
       
  1442 			UpdatePolicyState(EMMFStateStopped);
       
  1443 			}
       
  1444 		else if (iMode == EMMFDevSoundStateRecording)
       
  1445 			{
       
  1446 			iDevSoundObserver->RecordError(aEvent.iErrorCode);
       
  1447 			UpdatePolicyState(EMMFStateStopped);
       
  1448 			}
       
  1449 		else if (iMode == EMMFDevSoundStateTonePlaying)
       
  1450 			{
       
  1451 			iDevSoundObserver->ToneFinished(aEvent.iErrorCode);
       
  1452 			}			
       
  1453 		iCMMFHwDevice->Stop();//unloads sound device
       
  1454 		// Have audio Policy launch higher priority request
       
  1455 		iAudioPolicyProxy->LaunchRequests();
       
  1456 		}
       
  1457 	else
       
  1458 		{
       
  1459 		iHasPolicy = ETrue;
       
  1460 		iDevSoundObserver->SendEventToClient(aEvent);
       
  1461 		}
       
  1462 	}
       
  1463 
       
  1464 
       
  1465 /**
       
  1466  *
       
  1467  *	Sets volume on HwDevice.
       
  1468  *	
       
  1469  *	@return	"TInt"
       
  1470  *			Error value returned by HwDevice.
       
  1471  *
       
  1472  */
       
  1473 TInt CMMFDevSoundSvrImp::SetDeviceVolume(TInt aVolume)
       
  1474 	{
       
  1475 	TInt error = KErrNone;
       
  1476 	if (iPlayCustomInterface) 
       
  1477 		iPlayCustomInterface->SetVolume(aVolume);
       
  1478 	else error = KErrNotReady;
       
  1479 	return error;
       
  1480     }
       
  1481 
       
  1482 /**
       
  1483  *
       
  1484  *	Sets PlayFormat on HwDevice.
       
  1485  *	
       
  1486  *
       
  1487  *	@return	"TInt"
       
  1488  *			Error value returned by HwDevice.
       
  1489  *
       
  1490  */
       
  1491 TInt CMMFDevSoundSvrImp::SetPlayFormat(RMdaDevSound::TCurrentSoundFormatBuf& aPlayFormat)
       
  1492 	{
       
  1493 	TInt error = KErrNone;
       
  1494 	if (iCMMFHwDevice)
       
  1495 		{
       
  1496 		TTaskConfig taskConfig;
       
  1497 		taskConfig.iUid = KUidRefDevSoundTaskConfig;
       
  1498 		taskConfig.iRate = aPlayFormat().iRate;
       
  1499 		
       
  1500 		if (aPlayFormat().iChannels == 1)
       
  1501 			{
       
  1502 			taskConfig.iStereoMode = ETaskMono;
       
  1503 			}
       
  1504 		else if (aPlayFormat().iChannels == 2)
       
  1505 			{
       
  1506 			taskConfig.iStereoMode = ETaskInterleaved;
       
  1507 			}
       
  1508 		else
       
  1509 			{
       
  1510 			return KErrArgument;
       
  1511 			}
       
  1512 
       
  1513 		error = iCMMFHwDevice->SetConfig(taskConfig);
       
  1514 		//note the iEncoding and iBufferSize are already determined by the 
       
  1515 		//CMMFHwDevice plugin and so are not set.
       
  1516 		}
       
  1517 	else
       
  1518 		{
       
  1519 		error = KErrNotReady;
       
  1520 		}
       
  1521 	return error;
       
  1522     }
       
  1523 
       
  1524 
       
  1525 /**
       
  1526  *
       
  1527  *	Sets RecordFormat on HwDevice.
       
  1528  *	
       
  1529  *
       
  1530  *	@return	"TInt"
       
  1531  *			Error value returned by HwDevice.
       
  1532  *
       
  1533  */
       
  1534 TInt CMMFDevSoundSvrImp::SetRecordFormat(RMdaDevSound::TCurrentSoundFormatBuf& aRecordFormat)
       
  1535 	{
       
  1536 	TInt error = KErrNone;
       
  1537 	if (iCMMFHwDevice)
       
  1538 		{
       
  1539 		TTaskConfig taskConfig;
       
  1540 		taskConfig.iUid = KUidRefDevSoundTaskConfig;
       
  1541 		taskConfig.iRate = aRecordFormat().iRate;
       
  1542 
       
  1543 		if (aRecordFormat().iChannels == 1)
       
  1544 			{
       
  1545 			taskConfig.iStereoMode = ETaskMono;
       
  1546 			}
       
  1547 		else if (aRecordFormat().iChannels == 2)
       
  1548 			{
       
  1549 			taskConfig.iStereoMode = ETaskInterleaved;
       
  1550 			}
       
  1551 		else
       
  1552 			{
       
  1553 			return KErrArgument;
       
  1554 			}
       
  1555 
       
  1556 		error = iCMMFHwDevice->SetConfig(taskConfig);
       
  1557 		//note the iEncoding and iBufferSize are already determined by the 
       
  1558 		//CMMFHwDevice plugin and so are not set.
       
  1559 		}
       
  1560 	else
       
  1561 		{
       
  1562 		error = KErrNotReady;
       
  1563 		}
       
  1564 	return error;
       
  1565     }
       
  1566 
       
  1567 
       
  1568 /**
       
  1569  *
       
  1570  *	Sets record level on HwDevice.
       
  1571  *	
       
  1572  *
       
  1573  *	@return	"TInt"
       
  1574  *			Error value returned by HwDevice.
       
  1575  *
       
  1576  */
       
  1577 TInt CMMFDevSoundSvrImp::SetDeviceRecordLevel(TInt aGain)
       
  1578 	{
       
  1579 	TInt error = KErrNone;
       
  1580 	if (iRecordCustomInterface) 
       
  1581 		iRecordCustomInterface->SetGain(aGain);
       
  1582 	else error = KErrNotReady;
       
  1583 	return error;
       
  1584 
       
  1585     }
       
  1586 
       
  1587 
       
  1588 /**
       
  1589  *
       
  1590  *	MMMFHwDeviceObserver mixin implementation.
       
  1591  *
       
  1592  *	The CMMFHwDevice implementation object calls this method during decoding
       
  1593  *	(playing), when it needs the encoded data in the buffer
       
  1594  *	aHwDataBuffer.
       
  1595  *
       
  1596  *	@return	"TInt"
       
  1597  *			Error code. KErrNone if success.
       
  1598  *
       
  1599  */
       
  1600 TInt CMMFDevSoundSvrImp::FillThisHwBuffer(CMMFBuffer& aHwDataBuffer)
       
  1601 	{
       
  1602 	TInt err = KErrNone;
       
  1603     // Keep a reference to this Hw data Buffer. We need to send the 
       
  1604 	// reference back to HwDevice implementation
       
  1605 	iHwDeviceBuffer = static_cast<CMMFDataBuffer*> (&aHwDataBuffer);
       
  1606 	// Set the request length, From HwDevice this comes with buffer
       
  1607 	// length.
       
  1608 	TInt len = iHwDeviceBuffer->Data().MaxLength();
       
  1609 	// Ignore error. since buffer size = Buffer Length 
       
  1610 	TRAP(err, iHwDeviceBuffer->SetRequestSizeL(len));
       
  1611 
       
  1612 	if (iMode== EMMFDevSoundStatePlaying) // Get Data from Observer
       
  1613 		{
       
  1614 		if (iLastBufferReceived)
       
  1615 			{
       
  1616 			iHwDeviceBuffer->Data().SetLength(0);
       
  1617 			// Pass the buffer to the he device
       
  1618             err = iCMMFHwDevice->ThisHwBufferFilled(*iHwDeviceBuffer);
       
  1619 			}
       
  1620 		else
       
  1621 			// Pass the buffer to the observer
       
  1622 			iDevSoundObserver->BufferToBeFilled(&aHwDataBuffer);
       
  1623 		}
       
  1624 	else if (iMode == EMMFDevSoundStateTonePlaying)
       
  1625 		{
       
  1626         // Hw device will call this method right after its Start was called.
       
  1627         // When it calls this for the first time it hasn't played one single
       
  1628         // buffer yet so check that.
       
  1629         // In this case there's no need to set the active buffer as it's already
       
  1630         // waiting to be played.
       
  1631         if (!iFirstCallFromHwDevice)
       
  1632             SetActiveToneBuffer();
       
  1633 
       
  1634 		// If there is no data in the active buffer, tone play is finished.
       
  1635 		// DevSound just have to wait for completion event from audio device.
       
  1636 		if (iActiveToneBuffer->Data().Length() > 0)
       
  1637             { 
       
  1638 			TInt tonelen = iActiveToneBuffer->Data().Length();
       
  1639 
       
  1640 			// don't enter more data than can be handled by the receiving buffer
       
  1641 			if (len >= tonelen) len = tonelen;
       
  1642 
       
  1643             // Copy data from tone buffer to hw device buffer
       
  1644             Mem::Copy((TAny*)(iHwDeviceBuffer->Data().Ptr()), (TAny*)(iActiveToneBuffer->Data().Ptr()), len);
       
  1645             
       
  1646             iHwDeviceBuffer->Data().SetLength(len);
       
  1647             // Play data and try to generate next data block
       
  1648 			err = iCMMFHwDevice->ThisHwBufferFilled(*iHwDeviceBuffer);
       
  1649             if (err != KErrNone)
       
  1650             	return err;
       
  1651             // Check again whether this is the first call from Hw device.
       
  1652             // FillFreeToneBuffer assumes the iActiveToneBuffer has already
       
  1653             // been played.
       
  1654             if (!iFirstCallFromHwDevice)
       
  1655                 err = FillFreeToneBuffer();
       
  1656             else
       
  1657                 iFirstCallFromHwDevice = EFalse;  // Reset flag
       
  1658 
       
  1659  			}
       
  1660 		else if (iFirstCallFromHwDevice)
       
  1661 			{//we have no data in the tone buffer and thus have no 
       
  1662 			//outstanding requests to play
       
  1663 			err = KErrUnderflow; //simulate underrun
       
  1664 			}
       
  1665 		else
       
  1666 			{
       
  1667 			iHwDeviceBuffer->Data().SetLength(0);
       
  1668 			iHwDeviceBuffer->SetLastBuffer(ETrue);
       
  1669             // Send an empty last buffer to HwDevice to get a play completion event with KErrUnderflow
       
  1670 			err = iCMMFHwDevice->ThisHwBufferFilled(*iHwDeviceBuffer);
       
  1671 			}
       
  1672 	
       
  1673 		// If there was an error filling the buffer could be corrupt data
       
  1674 		// notify the client and stop playing.Set err to KErrNone. 
       
  1675 		if (err != KErrNone)
       
  1676 			{
       
  1677 			Error(err);//Updates Bytes played informs client
       
  1678 			err = KErrNone;
       
  1679 			iCMMFHwDevice->Stop();//unloads sound device
       
  1680             }
       
  1681 		}
       
  1682 	else
       
  1683 		{
       
  1684 		err = KErrGeneral;
       
  1685 		Error(err);
       
  1686 		iCMMFHwDevice->Stop();//unloads sound device
       
  1687 
       
  1688 		}
       
  1689 	return err;
       
  1690 	}
       
  1691 
       
  1692 
       
  1693 /**
       
  1694  *
       
  1695  *	MMMFHwDeviceObserver mixin implementation.
       
  1696  *
       
  1697  *	The CMMFHwDevice implementation object calls this method during encoding
       
  1698  *	(recording), when it fills the buffer aHwDataBuffer with
       
  1699  *	encoded data.
       
  1700  *
       
  1701  *	@return	"TInt"
       
  1702  *			Error code. KErrNone if success.
       
  1703  *
       
  1704  */
       
  1705 TInt CMMFDevSoundSvrImp::EmptyThisHwBuffer(CMMFBuffer& aHwDataBuffer)
       
  1706 	{
       
  1707 	TInt err = KErrNone;
       
  1708 	if(iMode== EMMFDevSoundStateRecording)
       
  1709 		{
       
  1710 		// Keep a reference to this Hw data Buffer. We need to send the 
       
  1711 		// reference back to HwDevice implementation
       
  1712 		iHwDeviceBuffer = static_cast<CMMFDataBuffer*>(&aHwDataBuffer);
       
  1713 
       
  1714 		// Set the request length, From HwDevice this comes with buffer
       
  1715 		// length. MMF will use RequestSize attribute of the buffer.
       
  1716 		// We can avoid this by setting in HwDevice implemenation
       
  1717 		TInt len = iHwDeviceBuffer->Data().Length();
       
  1718 		TRAP(err, iHwDeviceBuffer->SetRequestSizeL(len));
       
  1719 	
       
  1720 		// if we're pausing (i.e. flushing) set the last buffer flag
       
  1721 		// when we get an empty buffer from the logical driver
       
  1722 		if(iPaused  && iHwDeviceBuffer->Data().Length() == 0)
       
  1723 		{
       
  1724 		iPaused = EFalse;
       
  1725 
       
  1726 		iHwDeviceBuffer->SetLastBuffer(ETrue);
       
  1727 
       
  1728 		iDevSoundEventHandler->CancelReceiveEvents();
       
  1729 
       
  1730 		}
       
  1731 
       
  1732 		// Send Data from Observer
       
  1733 		iDevSoundObserver->BufferToBeEmptied(iHwDeviceBuffer);
       
  1734 		}
       
  1735 	else
       
  1736 		{
       
  1737 		err = KErrGeneral;
       
  1738 		Error(err);
       
  1739 		iCMMFHwDevice->Stop();//unloads sound device
       
  1740 
       
  1741 		}
       
  1742 
       
  1743 	return err;
       
  1744 	}
       
  1745 
       
  1746 
       
  1747 /**
       
  1748  *
       
  1749  *	MMMFHwDeviceObserver mixin implementation.
       
  1750  *
       
  1751  *	The CMMFHwDevice implementation object calls this method when a message from
       
  1752  *	the hardware device implementation is received.
       
  1753  *
       
  1754  *	@return	"TInt"
       
  1755  *			Error code. KErrNone if success.
       
  1756  *
       
  1757  */
       
  1758 TInt CMMFDevSoundSvrImp::MsgFromHwDevice(TUid aMessageType, const TDesC8& /*aMsg*/)
       
  1759 	{
       
  1760 	TInt result = KErrNotSupported;
       
  1761 	if (aMessageType.iUid == KMmfHwDeviceObserverUpdateBytesPlayed)
       
  1762 		{//this is used by sw codec wrapper to request a bytes played update
       
  1763 		//bytes played won't be updated in Stopped() or Error() on sw cdoec wrapper
       
  1764 		//as the sound device is closed. Non swCodec wrapper Hw device plugins
       
  1765 		//can get there bytes updated on Stopped() and/or Error()
       
  1766 		UpdateBytesPlayed();
       
  1767 		result = KErrNone;
       
  1768 		}
       
  1769 	return result;
       
  1770 	}
       
  1771 
       
  1772 /**
       
  1773  *
       
  1774  *	MMMFHwDeviceObserver mixin implementation.
       
  1775  *
       
  1776  *	The CMMFHwDevice implementation object calls this method when the current
       
  1777  *	encode or decode task is finished or stopped.  The policy state is updated
       
  1778  *
       
  1779  */
       
  1780 void CMMFDevSoundSvrImp::Stopped()
       
  1781 	{
       
  1782 	//for swcodec wrap hw devices bytes played updated in MsgFromHwDevice
       
  1783 	//but non Swcodec wrappers hw devices may do it differently
       
  1784 	//also don't know if non Swcodec wrap hw device will call Stopped or Error first
       
  1785 	UpdateBytesPlayed();
       
  1786 
       
  1787 	iLastBufferReceived = EFalse;
       
  1788 	UpdatePolicyState(EMMFStateCompleted);
       
  1789 	}
       
  1790 
       
  1791 /**
       
  1792  *  MMMFHwDeviceObserver mixin implementation
       
  1793  *  Processes error from hw device
       
  1794  */
       
  1795 void CMMFDevSoundSvrImp::Error(TInt aError)
       
  1796 	{
       
  1797 	if (iMode== EMMFDevSoundStatePlaying)
       
  1798 		{
       
  1799 		//for swcodec wrap hw devices bytes played updated in MsgFromHwDevice
       
  1800 		//but non Swcodec wrappers hw devices may do it differently
       
  1801 		//also don't know if non Swcodec wrap hw device will call Stopped or Error first
       
  1802 		UpdateBytesPlayed();
       
  1803 
       
  1804         iDevSoundObserver->PlayError(aError);
       
  1805         UpdatePolicyState(EMMFStateStopped);
       
  1806 		}
       
  1807 	else if (iMode== EMMFDevSoundStateRecording)
       
  1808 		{
       
  1809         iDevSoundObserver->RecordError(aError);
       
  1810         UpdatePolicyState(EMMFStateStopped);
       
  1811 		}
       
  1812 	else if (iMode== EMMFDevSoundStateTonePlaying)
       
  1813 		{
       
  1814         iDevSoundObserver->ToneFinished(aError);
       
  1815         UpdatePolicyState(EMMFStateStopped);
       
  1816 		}
       
  1817 	//else can't handle error
       
  1818 	}
       
  1819 
       
  1820 
       
  1821 /********************************************************************************
       
  1822  *				Non Exported public functions ends here							*
       
  1823  ********************************************************************************/
       
  1824 
       
  1825 
       
  1826 /********************************************************************************
       
  1827  *				Private functions begins here									*
       
  1828  ********************************************************************************/
       
  1829 
       
  1830 TInt CMMFDevSoundSvrImp::InitializeFormat(RMdaDevSound::TSoundFormatsSupportedBuf& aSupportedFormat,
       
  1831 		RMdaDevSound::TCurrentSoundFormatBuf& aFormat)
       
  1832 	{
       
  1833 	// Choose an encoding
       
  1834 	TUint32 enc = aSupportedFormat().iEncodings;
       
  1835 	// Always defaults to this
       
  1836 	if (enc & RMdaDevSound::EMdaSoundEncoding16BitPCM)
       
  1837 		aFormat().iEncoding = RMdaDevSound::EMdaSoundEncoding16BitPCM;
       
  1838 	else if (enc & RMdaDevSound::EMdaSoundEncoding8BitALaw)
       
  1839 		aFormat().iEncoding = RMdaDevSound::EMdaSoundEncoding8BitALaw;
       
  1840 	else if (enc & RMdaDevSound::EMdaSoundEncoding8BitMuLaw)
       
  1841 		aFormat().iEncoding = RMdaDevSound::EMdaSoundEncoding8BitMuLaw;
       
  1842 	else if (enc & RMdaDevSound::EMdaSoundEncoding8BitPCM)
       
  1843 		aFormat().iEncoding = RMdaDevSound::EMdaSoundEncoding8BitPCM;
       
  1844 
       
  1845 	// default to Monophonic playback:
       
  1846 	aFormat().iChannels=1;
       
  1847 
       
  1848 	// Store the device capabilities (WINS supports from 8000 Hz to 44100 Hz)
       
  1849 	if ((aSupportedFormat().iMinRate <= 8000) && (8000 <= aSupportedFormat().iMaxRate))
       
  1850 		iDeviceCapabilities.iRate = EMMFSampleRate8000Hz;
       
  1851 	if ((aSupportedFormat().iMinRate <= 11025) && (11025 <= aSupportedFormat().iMaxRate))
       
  1852 		iDeviceCapabilities.iRate |= EMMFSampleRate11025Hz;
       
  1853 	if ((aSupportedFormat().iMinRate <= 12000) && (12000 <= aSupportedFormat().iMaxRate))
       
  1854 		iDeviceCapabilities.iRate |= EMMFSampleRate12000Hz;
       
  1855 	if ((aSupportedFormat().iMinRate <= 16000) && (16000 <= aSupportedFormat().iMaxRate))
       
  1856 		iDeviceCapabilities.iRate |= EMMFSampleRate16000Hz;
       
  1857 	if ((aSupportedFormat().iMinRate <= 22050) && (22050 <= aSupportedFormat().iMaxRate))
       
  1858 		iDeviceCapabilities.iRate |= EMMFSampleRate22050Hz;
       
  1859 	if ((aSupportedFormat().iMinRate <= 24000) && (24000 <= aSupportedFormat().iMaxRate))
       
  1860 		iDeviceCapabilities.iRate |= EMMFSampleRate24000Hz;
       
  1861 	if ((aSupportedFormat().iMinRate <= 32000) && (32000 <= aSupportedFormat().iMaxRate))
       
  1862 		iDeviceCapabilities.iRate |= EMMFSampleRate32000Hz;
       
  1863 	if ((aSupportedFormat().iMinRate <= 44100) && (44100 <= aSupportedFormat().iMaxRate))
       
  1864 		iDeviceCapabilities.iRate |= EMMFSampleRate44100Hz;
       
  1865 	if ((aSupportedFormat().iMinRate <= 48000) && (48000 <= aSupportedFormat().iMaxRate))
       
  1866 		iDeviceCapabilities.iRate |= EMMFSampleRate48000Hz;
       
  1867 	if ((aSupportedFormat().iMinRate <= 64000) && (64000 <= aSupportedFormat().iMaxRate))
       
  1868 		iDeviceCapabilities.iRate |= EMMFSampleRate64000Hz;
       
  1869 	if ((aSupportedFormat().iMinRate <= 88200) && (88200 <= aSupportedFormat().iMaxRate))
       
  1870 		iDeviceCapabilities.iRate |= EMMFSampleRate88200Hz;
       
  1871 	if ((aSupportedFormat().iMinRate <= 96000) && (96000 <= aSupportedFormat().iMaxRate))
       
  1872 		iDeviceCapabilities.iRate |= EMMFSampleRate96000Hz;
       
  1873 
       
  1874 	// Store the encodings supported
       
  1875 	iDeviceCapabilities.iEncoding = 0;
       
  1876 	if (enc & RMdaDevSound::EMdaSoundEncoding16BitPCM)
       
  1877 		iDeviceCapabilities.iEncoding |= EMMFSoundEncoding16BitPCM;
       
  1878 	if (enc & RMdaDevSound::EMdaSoundEncoding8BitALaw)
       
  1879 		iDeviceCapabilities.iEncoding |= EMMFSoundEncoding8BitALaw;
       
  1880 	if (enc & RMdaDevSound::EMdaSoundEncoding8BitMuLaw)
       
  1881 		iDeviceCapabilities.iEncoding |= EMMFSoundEncoding8BitMuLaw;
       
  1882 	if (enc & RMdaDevSound::EMdaSoundEncoding8BitPCM)
       
  1883 		iDeviceCapabilities.iEncoding |= EMMFSoundEncoding8BitPCM;
       
  1884 
       
  1885 	// Mono and Stereo support
       
  1886 	if (aSupportedFormat().iChannels == 2)
       
  1887 		iDeviceCapabilities.iChannels = EMMFStereo;
       
  1888 	iDeviceCapabilities.iChannels |= EMMFMono;
       
  1889 
       
  1890 	iDeviceCapabilities.iBufferSize = aSupportedFormat().iMaxBufferSize;
       
  1891 	// Default
       
  1892 	iDeviceConfig.iRate = EMMFSampleRate8000Hz;
       
  1893 	iDeviceConfig.iEncoding = EMMFSoundEncoding16BitPCM;
       
  1894 	iDeviceConfig.iChannels = EMMFMono;
       
  1895 
       
  1896 	return KErrNone;
       
  1897 	}
       
  1898 
       
  1899 /*
       
  1900  *
       
  1901  *	Makes request to Policy Server (asynchronous call)
       
  1902  *
       
  1903  */
       
  1904 void CMMFDevSoundSvrImp::RequestPolicy()
       
  1905 	{
       
  1906 	iDevSoundEventHandler->CancelReceiveEvents();
       
  1907 	iDevSoundEventHandler->ReceiveEvents();
       
  1908 	iAudioPolicyPrioritySettings.iCapabilities = iParent.CheckClientCapabilities();
       
  1909 	iAudioPolicyProxy->MakeRequest(iAudioPolicyPrioritySettings);
       
  1910 	}
       
  1911 
       
  1912 /*
       
  1913  *
       
  1914  *	Creates buffer and begin playback using the specified tone generator.
       
  1915  *
       
  1916  */
       
  1917 void CMMFDevSoundSvrImp::DoPlayL()
       
  1918 	{
       
  1919 	// Delete any buffer from previous call and try to create maximum buffer 
       
  1920 	// size. Double Buffer the Tone data.
       
  1921 	if (iToneBuffer1)
       
  1922 		{
       
  1923 		delete iToneBuffer1; 
       
  1924 		iToneBuffer1 = NULL; 
       
  1925 		}
       
  1926 	//note the tone buffer needs to be the same as the pcm16->pcm16 'null'
       
  1927 	//hw device plugin
       
  1928 	// Buffer size = (SampleRate * BytesPerSample * Channels) / 4
       
  1929 	TInt useBufferOfSize = ((SamplingFrequency() * 2 * NumberOfChannels())/KDevSoundFramesPerSecond + (KDevSoundDeltaFrameSize-1)) &~ (KDevSoundDeltaFrameSize-1);
       
  1930 	//clamp buffer to desired limits
       
  1931 	if(useBufferOfSize < KDevSoundMinFrameSize) 
       
  1932 		useBufferOfSize = KDevSoundMinFrameSize;
       
  1933 	else if(useBufferOfSize > KDevSoundMaxFrameSize) 
       
  1934 		useBufferOfSize = KDevSoundMaxFrameSize;
       
  1935 
       
  1936 	//clamp buffer to limits of hardware
       
  1937 	if(useBufferOfSize < Max(iPlayFormatsSupported().iMinBufferSize, iRecordFormatsSupported().iMinBufferSize))
       
  1938 		useBufferOfSize = Max(iPlayFormatsSupported().iMinBufferSize, iRecordFormatsSupported().iMinBufferSize);
       
  1939 	else if(useBufferOfSize > Min(iPlayFormatsSupported().iMaxBufferSize, iRecordFormatsSupported().iMaxBufferSize))
       
  1940 		useBufferOfSize = Min(iPlayFormatsSupported().iMaxBufferSize, iRecordFormatsSupported().iMaxBufferSize);
       
  1941 
       
  1942 	iToneBuffer1 = CMMFDataBuffer::NewL(useBufferOfSize);
       
  1943 	User::LeaveIfError(iCurrentGenerator->FillBuffer(iToneBuffer1->Data()));
       
  1944 
       
  1945 	if (iToneBuffer2)
       
  1946 		{
       
  1947 		delete iToneBuffer2; 
       
  1948 		iToneBuffer2 = NULL;
       
  1949 		}
       
  1950 	iToneBuffer2 = CMMFDataBuffer::NewL(useBufferOfSize);
       
  1951 	User::LeaveIfError(iCurrentGenerator->FillBuffer(iToneBuffer2->Data()));
       
  1952 
       
  1953 	// Assign active buffer
       
  1954 	iActiveToneBuffer = iToneBuffer1;
       
  1955 
       
  1956 	// Hw device hasn't played anything yet so don't change
       
  1957     // active buffer. This is checked in FillThisHwBuffer.
       
  1958     iFirstCallFromHwDevice = ETrue;
       
  1959 
       
  1960     // Start HwDevice to play data
       
  1961     User::LeaveIfError(iCMMFHwDevice->Start(EDevDecode, EDevOutFlow));
       
  1962 	
       
  1963 	}
       
  1964 
       
  1965 /*
       
  1966  *
       
  1967  *	This method assigns the other buffer as active buffer. The tone audio 
       
  1968  *	generator should fill data in the other buffer by now.
       
  1969  *
       
  1970  */
       
  1971 void CMMFDevSoundSvrImp::SetActiveToneBuffer()
       
  1972 	{
       
  1973 	if (iActiveToneBuffer == iToneBuffer1)
       
  1974 		iActiveToneBuffer = iToneBuffer2;
       
  1975 	else if (iActiveToneBuffer == iToneBuffer2)
       
  1976 		iActiveToneBuffer = iToneBuffer1;
       
  1977 	}
       
  1978 
       
  1979 /*
       
  1980  *
       
  1981  *	This method fills data into the free buffer.
       
  1982  *
       
  1983  *	@return	"TInt"
       
  1984  *			Error code. KErrNone if success.
       
  1985  *
       
  1986  */
       
  1987 TInt CMMFDevSoundSvrImp::FillFreeToneBuffer()
       
  1988 	{
       
  1989 	TInt err(KErrNone);
       
  1990 	if (iActiveToneBuffer == iToneBuffer1)
       
  1991 		err = iCurrentGenerator->FillBuffer(iToneBuffer2->Data());
       
  1992 	else if (iActiveToneBuffer == iToneBuffer2)
       
  1993 		err = iCurrentGenerator->FillBuffer(iToneBuffer1->Data());
       
  1994 	return err;
       
  1995 	}
       
  1996 
       
  1997 /*
       
  1998  *
       
  1999  *	Updates the policy state based on Audio policy settings of this devsound instance
       
  2000  *
       
  2001  */
       
  2002 TInt CMMFDevSoundSvrImp::UpdatePolicyState(TMMFAudioPolicyState aNewState)
       
  2003 	{
       
  2004 	iAudioPolicyPrioritySettings.iState = aNewState;
       
  2005 	TInt error = iAudioPolicyProxy->UpdateState(iAudioPolicyPrioritySettings);
       
  2006 	if ((error == KErrNone) && (aNewState == EMMFStateStopped))
       
  2007 		{
       
  2008 		iHasPolicy = EFalse;
       
  2009 		}
       
  2010 
       
  2011 	return error;
       
  2012 	}
       
  2013 
       
  2014 /*
       
  2015  *
       
  2016  *	Initializes audio device node by setting volume, and sampling rate.
       
  2017  *
       
  2018  *	@return	"TInt"
       
  2019  *			Error Code. KErrNone if success.
       
  2020  *
       
  2021  */
       
  2022 TInt CMMFDevSoundSvrImp::InitTask()
       
  2023 	{
       
  2024 	// No Implementation
       
  2025 	return KErrNone;
       
  2026 	}
       
  2027 
       
  2028 
       
  2029 
       
  2030 /*
       
  2031  *
       
  2032  *	Returns an integer representing Sampling Frequency the device is currently
       
  2033  *	configured to.
       
  2034  *
       
  2035  *	@return	"TInt"
       
  2036  *			Sampling Frequency.
       
  2037  *
       
  2038  */
       
  2039 TInt CMMFDevSoundSvrImp::SamplingFrequency()
       
  2040 	{
       
  2041 	if(iDeviceConfig.iRate == EMMFSampleRate8000Hz)
       
  2042 		return 8000;
       
  2043 	else if(iDeviceConfig.iRate == EMMFSampleRate11025Hz)
       
  2044 		return 11025;
       
  2045 	else if(iDeviceConfig.iRate == EMMFSampleRate12000Hz)
       
  2046 		return 12000;
       
  2047 	else if(iDeviceConfig.iRate == EMMFSampleRate16000Hz)
       
  2048 		return 16000;
       
  2049 	else if(iDeviceConfig.iRate == EMMFSampleRate22050Hz)
       
  2050 		return 22050;
       
  2051 	else if(iDeviceConfig.iRate == EMMFSampleRate24000Hz)
       
  2052 		return 24000;
       
  2053 	else if(iDeviceConfig.iRate == EMMFSampleRate32000Hz)
       
  2054 		return 32000;
       
  2055 	else if(iDeviceConfig.iRate == EMMFSampleRate44100Hz)
       
  2056 		return 44100;
       
  2057 	else if(iDeviceConfig.iRate == EMMFSampleRate48000Hz)
       
  2058 		return 48000;
       
  2059 	else if(iDeviceConfig.iRate == EMMFSampleRate88200Hz)
       
  2060 		return 88200;
       
  2061 	else if(iDeviceConfig.iRate == EMMFSampleRate96000Hz)
       
  2062 		return 96000;
       
  2063 	else
       
  2064 		return 8000; //default
       
  2065 	}
       
  2066  
       
  2067 /*
       
  2068  *
       
  2069  *	Returns an integer representing number of channels the device is currently
       
  2070  *	configured to.
       
  2071  *
       
  2072  *	@return	"TInt"
       
  2073  *			Number of audio channels 1 if mono, 2 if stereo.
       
  2074  *
       
  2075  */
       
  2076 TInt CMMFDevSoundSvrImp::NumberOfChannels()
       
  2077 	{
       
  2078 	if(iDeviceConfig.iChannels == EMMFMono)
       
  2079 		return 1;
       
  2080 	else
       
  2081 		return 2;
       
  2082 	}
       
  2083 
       
  2084 /*
       
  2085  *
       
  2086  *	Returns an integer representing number of bytes in each audio sample
       
  2087  *	
       
  2088  *
       
  2089  *	@return	"TInt"
       
  2090  *			Number of of bytes in each audio sample.
       
  2091  *
       
  2092  */
       
  2093 TInt CMMFDevSoundSvrImp::BytesPerAudioSample()
       
  2094 	{
       
  2095 	TInt bytes=1;
       
  2096 	switch (iDeviceConfig.iEncoding)
       
  2097 		{
       
  2098 		case EMMFSoundEncoding8BitPCM:
       
  2099 		case EMMFSoundEncoding8BitALaw:
       
  2100 		case EMMFSoundEncoding8BitMuLaw:
       
  2101 			{
       
  2102 			bytes=1;
       
  2103 			}
       
  2104 		break;
       
  2105 		case EMMFSoundEncoding16BitPCM:
       
  2106 			{
       
  2107 			bytes=2;
       
  2108 			}
       
  2109 		break;
       
  2110 		}
       
  2111 	return bytes;
       
  2112 	}
       
  2113 
       
  2114 
       
  2115 /********************************************************************************
       
  2116  *				Private functions ends here										*
       
  2117  ********************************************************************************/
       
  2118 
       
  2119 
       
  2120 // CustomCommand* implementation:
       
  2121 // The following come through from the parent object intact - currently it seems
       
  2122 // easier to pass this through with an RMessage, as the result parameter (at least)
       
  2123 // is easier to deal with that way. This might change in the future. 
       
  2124 // [TODO - if we extended this to CMMFHwDevice, it might be easier to use some sort
       
  2125 // of TMMFCustomCommandParamBlock throughout, which as well as the uid, in params etc
       
  2126 // by value, also provided a virtual(?) function to set output param. Could then
       
  2127 // use in both plat sec and original code
       
  2128 
       
  2129 void CMMFDevSoundSvrImp::DoSyncCustomCommandL(const RMmfIpcMessage& aMessage)
       
  2130 	{
       
  2131 	TInt command = aMessage.Int0();
       
  2132 	
       
  2133 	// we don't support any commands at the momment
       
  2134 	User::Leave(KErrNotSupported);
       
  2135 	}
       
  2136 	
       
  2137 void CMMFDevSoundSvrImp::DoSyncCustomCommandResultL(const RMmfIpcMessage& aMessage)
       
  2138 	{
       
  2139 	TInt command = aMessage.Int0();
       
  2140 	
       
  2141 	// we don't support any commands at the momment
       
  2142 	User::Leave(KErrNotSupported);	
       
  2143 	}
       
  2144 	
       
  2145 void CMMFDevSoundSvrImp::DoAsyncCustomCommandL(const RMmfIpcMessage& aMessage)
       
  2146 	{
       
  2147 	TInt command = aMessage.Int0();
       
  2148 	
       
  2149 	// we don't support any commands at the momment
       
  2150 	User::Leave(KErrNotSupported); // this will still complete for an async message	
       
  2151 	}
       
  2152 	
       
  2153 void CMMFDevSoundSvrImp::DoAsyncCustomCommandResultL(const RMmfIpcMessage& aMessage)
       
  2154 	{
       
  2155 	TInt command = aMessage.Int0();
       
  2156 	
       
  2157 	// we don't support any commands at the moment
       
  2158 	User::Leave(KErrNotSupported); // this will still complete for an async message	
       
  2159 	}
       
  2160