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