os/mm/devsound/sounddevbt/PlatSec/src/Server/AudioServer/MmfBtDevSoundSessionBody.cpp
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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
17 #include "MmfBtDevSoundSessionBody.h"
18 #include "MmfBtDevSoundSessionXtnd.h"
20 #include <mdaaudiotoneplayer.h>
21 #include <mmf/server/mmfdatabuffer.h>
22 #include <mmffourcc.h>
23 #include <mmfbthwdeviceimplementationuids.hrh>
24 #include <mmfbtswcodecwrappercustominterfacesuids.hrh> // KUidBtRefDevSoundTaskConfig
28 * AO to handle RSD initialisation
31 CRoutingSoundDeviceHandler* CRoutingSoundDeviceHandler::NewL(MDevSoundObserver* aObserver)
33 CRoutingSoundDeviceHandler* self = new(ELeave) CRoutingSoundDeviceHandler(aObserver);
34 CleanupStack::PushL(self);
36 CleanupStack::Pop(self);
40 CRoutingSoundDeviceHandler::~CRoutingSoundDeviceHandler()
45 void CRoutingSoundDeviceHandler::RunL()
47 TInt err = iStatus.Int();
50 iObserver->InitializeComplete(err);
54 void CRoutingSoundDeviceHandler::DoCancel()
58 iObserver->InitializeComplete(KErrCancel);
62 CRoutingSoundDeviceHandler::CRoutingSoundDeviceHandler(MDevSoundObserver* aObserver) :
63 CActive(EPriorityStandard),
66 CActiveScheduler::Add(this);
69 void CRoutingSoundDeviceHandler::ConstructL()
73 void CRoutingSoundDeviceHandler::Start()
83 * Default Constructor.
85 * No default implementation. CMMFDevSoundProxy implements 2-phase construction.
88 CMMFDevSoundSvrImp::CMMFDevSoundSvrImp(CMMFDevSoundSessionXtnd* aParent)
92 //Set reasonable default values for DTMF
93 iDTMFGen.SetToneDurations(250000,50000,250000);
100 * Deletes all objects and releases all resource owned by this
104 CMMFDevSoundSvrImp::~CMMFDevSoundSvrImp()
109 delete iDevSoundEventHandler;
110 if( iAudioPolicyProxy != NULL)
112 iAudioPolicyProxy->Close();
113 delete iAudioPolicyProxy;
115 delete iDevSoundUtil;
116 delete iFixedSequences;
117 delete iCMMFHwDevice;
122 * Constructs, and returns a pointer to, a new CMMFDevSoundSvrImp object.
127 CMMFDevSoundSvrImp* CMMFDevSoundSvrImp::NewL(CMMFDevSoundSessionXtnd* aParent)
129 CMMFDevSoundSvrImp* self = new (ELeave) CMMFDevSoundSvrImp(aParent);
135 * 3rd phase constructor - assumes that iParent has already been set up properly
136 * (During ConstructL() it has yet to be
139 void CMMFDevSoundSvrImp::Construct3L(RServer2& aPolicyServerHandle)
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);
149 iDevSoundUtil = CMMFDevSoundUtility::NewL();
150 // Initialize Fixed sequence related
151 iDevSoundUtil->InitializeFixedSequenceL(&iFixedSequences);
153 // Add RSD handler construction here.
154 iRSDHandler = CRoutingSoundDeviceHandler::NewL(&iParent);
160 * internal procedure to perform all initialization prior to setting the
163 void CMMFDevSoundSvrImp::PreInitializeL()
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;
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);
177 //default to play until we know we are recording
178 User::LeaveIfError(InitializeFormat(iPlayFormatsSupported, iPlayFormat));
183 * Initializes CMMFDevSoundProxy object to play and record PCM16 raw audio data
184 * with sampling rate of 8 KHz.
186 * On completion of Initialization, calls InitializeComplete() on
191 * @param "MDevSoundObserver& aDevSoundObserver"
192 * A reference to DevSound Observer instance.
194 * @param "TMMFState aMode"
195 * Mode for which this object will be used.
198 void CMMFDevSoundSvrImp::InitializeL(MDevSoundObserver& aDevSoundObserver, TMMFState aMode)
201 // if no HwDevice id specified, load default null implementation
202 TUid rawUid = {KMmfUidBtHwDevicePCM16ToPCM16};
203 InitializeL(aDevSoundObserver, rawUid, aMode);
208 * Configure CMMFDevSoundProxy object for the settings in aConfig.
210 * Use this to set sampling rate, Encoding and Mono/Stereo.
212 * @param "TMMFCapabilities& aConfig"
213 * Attribute values to which CMMFDevSoundProxy object will be configured to.
215 * As part of defect 20796, the iRecordFormat has been set under the iPlayFormat,
216 * before it was not set at all.
219 void CMMFDevSoundSvrImp::SetConfigL(const TMMFCapabilities& aConfig)
221 TUint attributeValue = aConfig.iRate;
222 // WINS supports from 8000 Hz to 96000 Hz
223 if (attributeValue & EMMFSampleRate96000Hz)
225 iPlayFormat().iRate = 96000;
226 iRecordFormat().iRate = 96000;
227 iDeviceConfig.iRate = EMMFSampleRate96000Hz;
229 else if (attributeValue & EMMFSampleRate88200Hz)
231 iPlayFormat().iRate = 88200;
232 iRecordFormat().iRate = 88200;
233 iDeviceConfig.iRate = EMMFSampleRate88200Hz;
235 else if (attributeValue & EMMFSampleRate64000Hz)
237 iPlayFormat().iRate = 64000;
238 iRecordFormat().iRate = 64000;
239 iDeviceConfig.iRate = EMMFSampleRate64000Hz;
241 else if (attributeValue & EMMFSampleRate48000Hz)
243 iPlayFormat().iRate = 48000;
244 iRecordFormat().iRate = 48000;
245 iDeviceConfig.iRate = EMMFSampleRate48000Hz;
247 else if (attributeValue & EMMFSampleRate44100Hz)
249 iPlayFormat().iRate = 44100;
250 iRecordFormat().iRate = 44100;
251 iDeviceConfig.iRate = EMMFSampleRate44100Hz;
253 else if (attributeValue & EMMFSampleRate32000Hz)
255 iPlayFormat().iRate = 32000;
256 iRecordFormat().iRate = 32000;
257 iDeviceConfig.iRate = EMMFSampleRate32000Hz;
259 else if (attributeValue & EMMFSampleRate24000Hz)
261 iPlayFormat().iRate =
262 iRecordFormat().iRate = 24000;
263 iDeviceConfig.iRate = EMMFSampleRate24000Hz;
265 else if (attributeValue & EMMFSampleRate22050Hz)
267 iPlayFormat().iRate = 22050;
268 iRecordFormat().iRate = 22050;
269 iDeviceConfig.iRate = EMMFSampleRate22050Hz;
271 else if (attributeValue & EMMFSampleRate16000Hz)
273 iPlayFormat().iRate = 16000;
274 iRecordFormat().iRate = 16000;
275 iDeviceConfig.iRate = EMMFSampleRate16000Hz;
277 else if (attributeValue & EMMFSampleRate12000Hz)
279 iPlayFormat().iRate =
280 iRecordFormat().iRate = 12000;
281 iDeviceConfig.iRate = EMMFSampleRate12000Hz;
283 else if (attributeValue & EMMFSampleRate11025Hz)
285 iPlayFormat().iRate = 11025;
286 iRecordFormat().iRate = 11025;
287 iDeviceConfig.iRate = EMMFSampleRate11025Hz;
289 else if (attributeValue & EMMFSampleRate8000Hz)
291 iPlayFormat().iRate = 8000;
292 iRecordFormat().iRate = 8000;
293 iDeviceConfig.iRate = EMMFSampleRate8000Hz;
295 else if (attributeValue)
296 { //if no attribute value assume its not set
297 User::Leave(KErrNotSupported);
300 attributeValue = aConfig.iEncoding;
301 // Map from MMF Encoding enums to RMdaDevSound enum
302 if(attributeValue & EMMFSoundEncoding8BitPCM)
304 iPlayFormat().iEncoding = RMdaDevSound::EMdaSoundEncoding8BitPCM;
305 iRecordFormat().iEncoding = RMdaDevSound::EMdaSoundEncoding8BitPCM;
306 iDeviceConfig.iEncoding = EMMFSoundEncoding8BitPCM;
308 else if(attributeValue & EMMFSoundEncoding8BitALaw)
310 iPlayFormat().iEncoding = RMdaDevSound::EMdaSoundEncoding8BitALaw;
311 iRecordFormat().iEncoding = RMdaDevSound::EMdaSoundEncoding8BitALaw;
312 iDeviceConfig.iEncoding = EMMFSoundEncoding8BitALaw;
314 else if(attributeValue & EMMFSoundEncoding8BitMuLaw)
316 iPlayFormat().iEncoding = RMdaDevSound::EMdaSoundEncoding8BitMuLaw;
317 iRecordFormat().iEncoding = RMdaDevSound::EMdaSoundEncoding8BitMuLaw;
318 iDeviceConfig.iEncoding = EMMFSoundEncoding8BitMuLaw;
320 else if(attributeValue & EMMFSoundEncoding16BitPCM)
322 iPlayFormat().iEncoding = RMdaDevSound::EMdaSoundEncoding16BitPCM;
323 iRecordFormat().iEncoding = RMdaDevSound::EMdaSoundEncoding16BitPCM;
324 iDeviceConfig.iEncoding = EMMFSoundEncoding16BitPCM;
326 else if (attributeValue)
327 { //if no attribute value assume its not set
328 User::Leave(KErrNotSupported);
331 // Mono/Stereo settings
332 attributeValue = aConfig.iChannels;
333 if(attributeValue & EMMFStereo)
335 iPlayFormat().iChannels = 2;
336 iRecordFormat().iChannels = 2;
337 iDeviceConfig.iChannels = EMMFStereo;
339 else if(attributeValue & EMMFMono)
341 iPlayFormat().iChannels = 1;
342 iRecordFormat().iChannels = 1;
343 iDeviceConfig.iChannels = EMMFMono;
345 else if (attributeValue)
346 { //if no attribute value assume its not set
347 User::Leave(KErrNotSupported);
353 * Changes the current playback volume to a specified value.
355 * The volume can be changed before or during playback and is effective
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.
367 void CMMFDevSoundSvrImp::SetVolume(TInt aVolume)
370 // Check and make sure that the volume is in valid range
374 if (aVolume > MaxVolume())
375 aVolume = MaxVolume();
379 SetDeviceVolume(iVolume);
384 * Changes the current recording gain to a specified value.
386 * The gain can be changed before or during recording and is effective
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.
398 void CMMFDevSoundSvrImp::SetGain(TInt aGain)
400 // make sure it falls with the correct range
401 TInt maxGain = iRecordFormatsSupported().iMaxVolume;
407 SetDeviceRecordLevel(iGain);
412 * Sets the speaker balance for playing.
414 * The speaker balance can be changed before or during playback and is
415 * effective immediately.
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
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
428 void CMMFDevSoundSvrImp::SetPlayBalanceL(TInt aLeftPercentage, TInt aRightPercentage)
430 if (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;
444 * Sets the microphone gain balance for recording.
446 * The microphone gain balance can be changed before or during recording and
447 * is effective immediately.
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.
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.
458 void CMMFDevSoundSvrImp::SetRecordBalanceL(TInt aLeftPercentage, TInt aRightPercentage)
460 if (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;
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.
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.
488 void CMMFDevSoundSvrImp::PlayInitL()
490 if (!iDevSoundObserver)
491 User::Leave(KErrNotReady);
494 iAudioPolicyPrioritySettings.iState = EMMFStatePlayData;
500 * Initializes audio device and start record process.
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.
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.
513 * The amount of data that is available is specified in
514 * CMMFBuffer::RequestSize().
519 void CMMFDevSoundSvrImp::RecordInitL(const RMmfIpcMessage& aMessage)
521 if (!iDevSoundObserver)
522 User::Leave(KErrNotReady);
524 // Checkes if the client has the UserEnvironment capability
525 if (!aMessage.HasCapability(ECapabilityUserEnvironment))
527 User::Leave(KErrPermissionDenied);
531 iAudioPolicyPrioritySettings.iState = EMMFStateRecordData;
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.
544 void CMMFDevSoundSvrImp::PlayData()
546 ASSERT(iDevSoundObserver);
548 if (iMode== EMMFStateIdle)
551 TInt error = KErrNone;
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
562 else if(iMode== EMMFStatePlaying)
564 TInt len = iHwDeviceBuffer->Data().Length();
565 iPlayedBytesCount += len;
566 if (iHwDeviceBuffer->LastBuffer())
567 iLastBufferReceived = ETrue;
570 if (iMode== EMMFStatePlaying)
571 // Pass the data buffer to HwDevice
572 error = iCMMFHwDevice->ThisHwBufferFilled(*iHwDeviceBuffer);
575 if (error != KErrNone)
576 iDevSoundObserver->PlayError(error);
581 * Stops the ongoing operation (Play, Record, TonePlay, Convert)
584 void CMMFDevSoundSvrImp::Stop()
588 if (iMode== EMMFStateIdle)
591 // Stop the hw device first - this unloads sound drivers
593 iCMMFHwDevice->Stop();
595 iDevSoundEventHandler->CancelReceiveEvents();
597 iAudioPolicyPrioritySettings.iState = EMMFStateStopped;
603 * Temporarily Stops the ongoing operation (Play, Record, TonePlay, Convert)
606 void CMMFDevSoundSvrImp::Pause()
610 if (iMode== EMMFStateIdle)
613 // Pause the HW device first
615 iCMMFHwDevice->Pause();
617 // defer policy update until buffers have been flushed
618 if ((iMode == EMMFStatePlaying) || (iMode == EMMFStateTonePlaying))
620 iDevSoundEventHandler->CancelReceiveEvents();
622 iAudioPolicyPrioritySettings.iState = EMMFStatePaused;
629 * Returns the sample recorded so far.
632 * Returns the samples recorded.
635 TInt CMMFDevSoundSvrImp::SamplesRecorded()
639 if(iRecordCustomInterface)
641 samples = iRecordCustomInterface->BytesRecorded();
642 if(NumberOfChannels() > 1)
644 samples /= NumberOfChannels();
646 if(BytesPerAudioSample() > 1)
648 samples /= BytesPerAudioSample();
657 * Returns the sample played so far.
660 * Returns the samples recorded.
663 TInt CMMFDevSoundSvrImp::SamplesPlayed()
666 if(iPlayCustomInterface)
668 TUint bytesPlayed = iPlayCustomInterface->BytesPlayed();
670 iPlayedBytesCount = bytesPlayed;
672 samples = iPlayedBytesCount;
673 if(NumberOfChannels() > 1)
674 samples /= NumberOfChannels();
676 if(BytesPerAudioSample() > 1)
677 samples /= BytesPerAudioSample();
679 //note always pcm16 becuase the iPlayedBytesCount originates from
680 //RMdaDevSound which is always pcm16
681 return samples; //each sample is 2 bytes
687 * Initializes audio device and start playing tone. Tone is played with
688 * frequency and for duration specified.
692 * @param "TInt aFrequency"
693 * Frequency at with the tone will be played.
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).
700 void CMMFDevSoundSvrImp::PlayToneL(TInt aFrequency, const TTimeIntervalMicroSeconds& aDuration)
702 if (iMode!= EMMFStateTonePlaying)
703 User::Leave(KErrNotSupported); //tone playing only supported in tone play state
705 // Check whether frequency and duration is valid or not
707 if ((aFrequency<0) || (aDuration.Int64() < zeroInt64))
708 User::Leave(KErrArgument);
710 if (!iDevSoundObserver)
711 User::Leave(KErrNotReady);
713 iToneGen.SetFrequencyAndDuration(aFrequency,aDuration);
716 iAudioPolicyPrioritySettings.iState = EMMFStatePlayTone;
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.
725 * @param "aFrequencyOne"
726 * First frequency of dual tone
728 * @param "aFrequencyTwo"
729 * Second frequency of dual tone
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).
735 void CMMFDevSoundSvrImp::PlayDualToneL(TInt aFrequencyOne, TInt aFrequencyTwo, const TTimeIntervalMicroSeconds& aDuration)
738 // Check whether frequencies and duration are valid or not
740 if ((aFrequencyOne<0) || (aFrequencyTwo<0) || (aDuration.Int64() < zeroInt64))
741 User::Leave(KErrArgument);
743 if (!iDevSoundObserver)
744 User::Leave(KErrNotReady);
746 iDualToneGen.SetFrequencyAndDuration(aFrequencyOne, aFrequencyTwo, aDuration);
749 iAudioPolicyPrioritySettings.iState = EMMFStatePlayDualTone;
755 * Initializes audio device and start playing DTMF string aDTMFString.
759 * @param "TDesC& aDTMFString"
760 * DTMF sequence in a descriptor.
763 void CMMFDevSoundSvrImp::PlayDTMFStringL(const TDesC& aDTMFString)
765 if (!iDevSoundObserver)
766 User::Leave(KErrNotReady);
768 if (iMode!= EMMFStateTonePlaying)
769 User::Leave(KErrNotSupported); //tone playing only supported in tone play state
771 iDTMFGen.SetString(aDTMFString);
774 iAudioPolicyPrioritySettings.iState = EMMFStatePlayDTMFString;
780 * Initializes audio device and start playing tone sequence.
784 * @param "TDesC8& aData"
785 * Tone sequence in a descriptor.
788 void CMMFDevSoundSvrImp::PlayToneSequenceL(const TDesC8& aData)
790 if (!iDevSoundObserver)
791 User::Leave(KErrNotReady);
793 if (iMode!= EMMFStateTonePlaying)
794 User::Leave(KErrNotSupported); //tone playing only supported in tone play state
796 // Check whether the sequence is valid or not
797 if (!iDevSoundUtil->RecognizeSequence(aData))
798 User::Leave(KErrCorrupt);
800 iSequenceGen.SetSequenceData(aData);
803 iAudioPolicyPrioritySettings.iState = EMMFStatePlayToneSequence;
809 * Initializes audio device and start playing the specified pre-defined tone
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
823 void CMMFDevSoundSvrImp::PlayFixedSequenceL(TInt aSequenceNumber)
825 if (!iDevSoundObserver)
826 User::Leave(KErrNotReady);
828 if (iMode!= EMMFStateTonePlaying)
829 User::Leave(KErrNotSupported); //tone playing only supported in tone play state
831 ASSERT((aSequenceNumber >= 0)&&(aSequenceNumber < iFixedSequences->Count()));
833 iFixedSequence.Set(iFixedSequences->MdcaPoint(aSequenceNumber));
834 iSequenceGen.SetSequenceData(iFixedSequence);
837 iAudioPolicyPrioritySettings.iState = EMMFStatePlayToneSequence;
843 * Defines the duration of tone on, tone off and tone pause to be used during the
844 * DTMF tone playback operation.
846 * Supported only during tone playing.
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.
852 * @param "TTimeIntervalMicroSeconds32& aToneOffLength"
853 * The period over which the no tone will be played.
855 * @param "TTimeIntervalMicroSeconds32& aPauseLength"
856 * The period over which the tone playing will be paused.
859 void CMMFDevSoundSvrImp::SetDTMFLengths(TTimeIntervalMicroSeconds32& aToneOnLength,
860 TTimeIntervalMicroSeconds32& aToneOffLength,
861 TTimeIntervalMicroSeconds32& aPauseLength)
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);
871 iDTMFGen.SetToneDurations(aToneOnLength,aToneOffLength,aPauseLength);
876 * Defines the period over which the volume level is to rise smoothly from
877 * nothing to the normal volume level.
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
888 void CMMFDevSoundSvrImp::SetVolumeRamp(const TTimeIntervalMicroSeconds& aRampDuration)
890 // save ramp duration for tone generator
891 iRampDuration = aRampDuration;
893 SetDeviceVolumeRamp(iRampDuration);
897 * Sets volume ramp on HwDevice.
899 TInt CMMFDevSoundSvrImp::SetDeviceVolumeRamp(const TTimeIntervalMicroSeconds& aRampDuration)
901 TInt error = KErrNone;
902 if (iPlayCustomInterface)
903 iPlayCustomInterface->SetVolumeRamp(aRampDuration);
905 error = KErrNotReady;
912 void CMMFDevSoundSvrImp::GetSupportedInputDataTypesL(RArray<TFourCC>& aSupportedDataTypes, const TMMFPrioritySettings& /*aPrioritySettings*/) const
914 //aPrioritySettings not used on ref DevSound
915 //search for playing datatypes
916 iDevSoundUtil->SeekHwDevicePluginsL(aSupportedDataTypes, EMMFStatePlaying);
922 void CMMFDevSoundSvrImp::GetSupportedOutputDataTypesL(RArray<TFourCC>& aSupportedDataTypes, const TMMFPrioritySettings& /*aPrioritySettings*/) const
924 //aPrioritySettings not used on ref DevSound
925 // search for recording datatypes
926 iDevSoundUtil->SeekHwDevicePluginsL(aSupportedDataTypes, EMMFStateRecording);
929 TInt CMMFDevSoundSvrImp::RegisterAsClient(TUid aEventType, const TDesC8& aNotificationRegistrationData)
931 return iAudioPolicyProxy->RequestResourceNotification(aEventType,aNotificationRegistrationData);
934 TInt CMMFDevSoundSvrImp::CancelRegisterAsClient(TUid aEventType)
936 return iAudioPolicyProxy->CancelRequestResourceNotification(aEventType);
939 TInt CMMFDevSoundSvrImp::GetResourceNotificationData(TUid aEventType, TDes8& aNotificationData)
942 err = iAudioPolicyProxy->IsRegisteredResourceNotification(aEventType);
945 aNotificationData.Num(SamplesPlayed());
950 TInt CMMFDevSoundSvrImp::WillResumePlay()
952 return iAudioPolicyProxy->StopNotification();
955 /********************************************************************************
956 * Implementations of Non Exported public functions begins here *
957 ********************************************************************************/
960 // Audio Policy specific implementation begins here //
965 * Called by Audio Policy Server when a request to play is approved by the
966 * Audio Policy Server.
968 * Leaves on failure??.
971 void CMMFDevSoundSvrImp::StartPlayDataL()
973 ASSERT(iMode== EMMFStatePlaying);
975 TInt error = KErrNone;
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);
986 // Initialize attribute values
987 iPlayedBytesCount = 0;
988 iLastBufferReceived = EFalse;
991 if (error == KErrNone)
992 error = iCMMFHwDevice->Start(EDevDecode, EDevOutFlow);
995 error = KErrNotReady;
997 if (error != KErrNone)
998 iDevSoundObserver->PlayError(error);
1003 * Called by Audio Policy Server when a request to record is approved by the
1004 * Audio Policy Server.
1006 * Leaves on failure.
1009 void CMMFDevSoundSvrImp::StartRecordDataL()
1011 ASSERT(iMode== EMMFStateRecording);
1015 TInt error = KErrNone;
1016 error = SetRecordFormat(iRecordFormat);
1017 if (error != KErrNone)
1019 iDevSoundObserver->RecordError(error);
1022 error = SetDeviceRecordLevel(iGain);
1023 if (error != KErrNone)
1025 iDevSoundObserver->RecordError(error);
1029 // Initialize attribute values
1030 iRecordedBytesCount = 0;
1032 error = iCMMFHwDevice->Start(EDevEncode, EDevInFlow);
1033 if (iHwDeviceBuffer)
1034 iHwDeviceBuffer->SetLastBuffer(EFalse);
1036 if (error != KErrNone)
1038 iDevSoundObserver->RecordError(error);
1043 iDevSoundObserver->RecordError(KErrNotReady);
1048 * Called by Audio Policy Server when a request to play tone is approved by
1049 * the Audio Policy Server.
1051 * Leaves on failure.
1054 void CMMFDevSoundSvrImp::StartPlayToneL()
1056 ASSERT(iMode== EMMFStateTonePlaying);
1060 TInt error = KErrNone;
1061 // Set volume and play format values
1062 error = SetPlayFormat(iPlayFormat);
1063 if (error != KErrNone)
1065 iDevSoundObserver->ToneFinished(error);
1068 if (iHwDeviceID.iUid == KMmfUidBtHwDevicePCM16ToPCM16)
1069 error = SetDeviceVolume(iVolume);
1071 error = KErrGeneral;//hw device should always be pcm16 for tone
1073 // turn off volume ramping - this is done in software below
1074 if (error == KErrNone)
1075 error = SetDeviceVolumeRamp(TTimeIntervalMicroSeconds(0));
1077 if (error != KErrNone)
1079 iDevSoundObserver->ToneFinished(error);
1083 // Initialize attribute values
1084 iPlayedBytesCount = 0;
1086 // Configure tone generator
1088 iPlayFormat().iRate,
1089 iPlayFormat().iChannels,
1091 I64LOW((iRepeatTrailingSilence.Int64()*iPlayFormat().iRate)/1000000),
1092 I64LOW((iRampDuration.Int64()*iPlayFormat().iRate)/1000000)
1095 iCurrentGenerator = &iToneGen;
1102 iDevSoundObserver->ToneFinished(KErrNotReady);
1107 * Called by Audio Policy Server when a request to play a dual tone is approved by
1108 * the Audio Policy Server.
1111 void CMMFDevSoundSvrImp::StartPlayDualToneL()
1113 ASSERT(iMode== EMMFStateTonePlaying);
1117 TInt error = KErrNone;
1118 // Set volume and play format values
1119 error = SetPlayFormat(iPlayFormat);
1120 if (error != KErrNone)
1122 iDevSoundObserver->ToneFinished(error);
1125 if (iHwDeviceID.iUid == KMmfUidBtHwDevicePCM16ToPCM16)
1126 error = SetDeviceVolume(iVolume);
1128 error = KErrGeneral;//hw device should always be pcm16 for tone
1130 // turn off volume ramping - this is done in software below
1131 if (error == KErrNone)
1132 error = SetDeviceVolumeRamp(TTimeIntervalMicroSeconds(0));
1134 if (error != KErrNone)
1136 iDevSoundObserver->ToneFinished(error);
1140 // Initialize attribute values
1141 iPlayedBytesCount = 0;
1143 // Configure dual tone generator
1144 iDualToneGen.Configure(
1145 iPlayFormat().iRate,
1146 iPlayFormat().iChannels,
1148 I64LOW((iRepeatTrailingSilence.Int64()*iPlayFormat().iRate)/KOneMillionMicroSeconds),
1149 I64LOW((iRampDuration.Int64()*iPlayFormat().iRate)/KOneMillionMicroSeconds)
1152 iCurrentGenerator = &iDualToneGen;
1158 iDevSoundObserver->ToneFinished(KErrNotReady);
1163 * Called by Audio Policy Server when a request to play DTMF String is approved
1164 * by the Audio Policy Server.
1166 * Leaves on failure.
1169 void CMMFDevSoundSvrImp::StartPlayDTMFStringL()
1172 ASSERT(iMode== EMMFStateTonePlaying);
1176 TInt error = KErrNone;
1177 // Set volume and play format values
1178 error = SetPlayFormat(iPlayFormat);
1179 if (error != KErrNone)
1181 iDevSoundObserver->ToneFinished(error);
1184 error = SetDeviceVolume(iVolume);
1186 // turn off volume ramping - this is done in software below
1187 if (error == KErrNone)
1188 error = SetDeviceVolumeRamp(TTimeIntervalMicroSeconds(0));
1190 if (error != KErrNone)
1192 iDevSoundObserver->ToneFinished(error);
1196 // Initialize attribute values
1197 iPlayedBytesCount = 0;
1200 iPlayFormat().iRate,
1201 iPlayFormat().iChannels,
1203 I64LOW((iRepeatTrailingSilence.Int64()*iPlayFormat().iRate)/1000000),
1204 I64LOW((iRampDuration.Int64()*iPlayFormat().iRate)/1000000)
1207 iCurrentGenerator = &iDTMFGen;
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))
1220 iDevSoundObserver->ToneFinished(KErrNotReady);
1225 * Called by Audio Policy Server when a request to play tone sequence is
1226 * approved by the Audio Policy Server.
1228 * Leaves on failure.
1231 void CMMFDevSoundSvrImp::StartPlayToneSequenceL()
1233 ASSERT(iMode== EMMFStateTonePlaying);
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)
1244 iDevSoundObserver->ToneFinished(error);
1248 if (iHwDeviceID.iUid == KMmfUidBtHwDevicePCM16ToPCM16)
1249 error = SetDeviceVolume(iVolume);
1251 error = KErrGeneral;//hw device should always be pcm16 for tone
1253 // turn off volume ramping - this is done in software below
1254 if (error == KErrNone)
1255 error = SetDeviceVolumeRamp(TTimeIntervalMicroSeconds(0));
1257 if (error != KErrNone)
1259 iDevSoundObserver->ToneFinished(error);
1263 // Initialize attribute values
1264 iPlayedBytesCount = 0;
1266 iSequenceGen.Configure(
1267 iPlayFormat().iRate,
1268 iPlayFormat().iChannels,
1270 I64LOW((iRepeatTrailingSilence.Int64()*iPlayFormat().iRate)/1000000),
1271 I64LOW((iRampDuration.Int64()*iPlayFormat().iRate)/1000000)
1274 iCurrentGenerator = &iSequenceGen;
1280 iDevSoundObserver->ToneFinished(KErrNotReady);
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.
1289 void CMMFDevSoundSvrImp::SendEventToClient(const TMMFEvent& aEvent)
1293 case EMMFStatePlaying:
1294 case EMMFStateTonePlaying:
1295 case EMMFStatePlayToneSequence:
1296 case EMMFStateRecording:
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();
1307 iMode = EMMFStatePlaying;
1308 iDevSoundObserver->SendEventToClient(aEvent);
1314 // Have audio Policy launch higher priority request:
1320 * Sets volume on HwDevice.
1323 * Error value returned by HwDevice.
1326 TInt CMMFDevSoundSvrImp::SetDeviceVolume(TInt aVolume)
1328 TInt error = KErrNone;
1329 if (iPlayCustomInterface)
1330 iPlayCustomInterface->SetVolume(aVolume);
1331 else error = KErrNotReady;
1337 * Sets PlayFormat on HwDevice.
1341 * Error value returned by HwDevice.
1344 TInt CMMFDevSoundSvrImp::SetPlayFormat(RMdaDevSound::TCurrentSoundFormatBuf& aPlayFormat)
1346 TInt error = KErrNone;
1349 TTaskConfig taskConfig;
1350 taskConfig.iUid = KUidBtRefDevSoundTaskConfig;
1351 taskConfig.iRate = aPlayFormat().iRate;
1353 if (aPlayFormat().iChannels == 1)
1355 taskConfig.iStereoMode = ETaskMono;
1357 else if (aPlayFormat().iChannels == 2)
1359 taskConfig.iStereoMode = ETaskInterleaved;
1363 return KErrArgument;
1366 error = iCMMFHwDevice->SetConfig(taskConfig);
1367 //note the iEncoding and iBufferSize are already determined by the
1368 //CMMFHwDevice plugin and so are not set.
1372 error = KErrNotReady;
1380 * Sets RecordFormat on HwDevice.
1384 * Error value returned by HwDevice.
1387 TInt CMMFDevSoundSvrImp::SetRecordFormat(RMdaDevSound::TCurrentSoundFormatBuf& aRecordFormat)
1389 TInt error = KErrNone;
1392 TTaskConfig taskConfig;
1393 taskConfig.iUid = KUidBtRefDevSoundTaskConfig;
1394 taskConfig.iRate = aRecordFormat().iRate;
1396 if (aRecordFormat().iChannels == 1)
1398 taskConfig.iStereoMode = ETaskMono;
1400 else if (aRecordFormat().iChannels == 2)
1402 taskConfig.iStereoMode = ETaskInterleaved;
1406 return KErrArgument;
1409 error = iCMMFHwDevice->SetConfig(taskConfig);
1410 //note the iEncoding and iBufferSize are already determined by the
1411 //CMMFHwDevice plugin and so are not set.
1415 error = KErrNotReady;
1423 * Sets record level on HwDevice.
1427 * Error value returned by HwDevice.
1430 TInt CMMFDevSoundSvrImp::SetDeviceRecordLevel(TInt aGain)
1432 TInt error = KErrNone;
1433 if (iRecordCustomInterface)
1434 iRecordCustomInterface->SetGain(aGain);
1435 else error = KErrNotReady;
1443 * MMMFHwDeviceObserver mixin implementation.
1445 * The CMMFHwDevice implementation object calls this method during decoding
1446 * (playing), when it needs the encoded data in the buffer
1450 * Error code. KErrNone if success.
1453 TInt CMMFDevSoundSvrImp::FillThisHwBuffer(CMMFBuffer& aHwDataBuffer)
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
1461 TInt len = iHwDeviceBuffer->Data().MaxLength();
1462 // Ignore error. since buffer size = Buffer Length
1463 TRAP(err, iHwDeviceBuffer->SetRequestSizeL(len));
1465 if (iMode== EMMFStatePlaying) // Get Data from Observer
1467 if (iLastBufferReceived)
1469 iHwDeviceBuffer->Data().SetLength(0);
1470 // Pass the buffer to the he device
1471 err = iCMMFHwDevice->ThisHwBufferFilled(*iHwDeviceBuffer);
1474 // Pass the buffer to the observer
1475 iDevSoundObserver->BufferToBeFilled(&aHwDataBuffer);
1477 else if (iMode== EMMFStateTonePlaying)
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();
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)
1491 TInt tonelen = iActiveToneBuffer->Data().Length();
1493 // don't enter more data than can be handled by the receiving buffer
1494 if (len >= tonelen) len = tonelen;
1496 // Copy data from tone buffer to hw device buffer
1497 Mem::Copy((TAny*)(iHwDeviceBuffer->Data().Ptr()), (TAny*)(iActiveToneBuffer->Data().Ptr()), len);
1499 iHwDeviceBuffer->Data().SetLength(len);
1500 // Play data and try to generate next data block
1501 err = iCMMFHwDevice->ThisHwBufferFilled(*iHwDeviceBuffer);
1502 if (err != KErrNone)
1504 // Check again whether this is the first call from Hw device.
1505 // FillFreeToneBuffer assumes the iActiveToneBuffer has already
1507 if (!iFirstCallFromHwDevice)
1508 err = FillFreeToneBuffer();
1510 iFirstCallFromHwDevice = EFalse; // Reset flag
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
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)
1524 Error(err);//Updates Bytes played informs client
1526 iCMMFHwDevice->Stop();//unloads sound device
1527 Stopped();//Updates policy
1533 iDevSoundObserver->PlayError(KErrGeneral);
1541 * MMMFHwDeviceObserver mixin implementation.
1543 * The CMMFHwDevice implementation object calls this method during encoding
1544 * (recording), when it fills the buffer aHwDataBuffer with
1548 * Error code. KErrNone if success.
1551 TInt CMMFDevSoundSvrImp::EmptyThisHwBuffer(CMMFBuffer& aHwDataBuffer)
1553 TInt err = KErrNone;
1554 if(iMode== EMMFStateRecording)
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);
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));
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)
1573 iHwDeviceBuffer->SetLastBuffer(ETrue);
1575 iDevSoundEventHandler->CancelReceiveEvents();
1577 iAudioPolicyPrioritySettings.iState = EMMFStateStopped;
1578 UpdatePolicyState();
1581 // Send Data from Observer
1582 iDevSoundObserver->BufferToBeEmptied(iHwDeviceBuffer);
1587 iDevSoundObserver->RecordError(KErrGeneral);
1596 * MMMFHwDeviceObserver mixin implementation.
1598 * The CMMFHwDevice implementation object calls this method when a message from
1599 * the hardware device implementation is received.
1602 * Error code. KErrNone if success.
1605 TInt CMMFDevSoundSvrImp::MsgFromHwDevice(TUid aMessageType, const TDesC8& /*aMsg*/)
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();
1621 * MMMFHwDeviceObserver mixin implementation.
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
1627 void CMMFDevSoundSvrImp::Stopped()
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();
1634 iLastBufferReceived = EFalse;
1635 iAudioPolicyPrioritySettings.iState = EMMFStateCompleted;
1636 UpdatePolicyState();
1640 * MMMFHwDeviceObserver mixin implementation
1641 * Processes error from hw device
1643 void CMMFDevSoundSvrImp::Error(TInt aError)
1645 if (iMode== EMMFStatePlaying)
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();
1652 iDevSoundObserver->PlayError(aError);
1653 iAudioPolicyPrioritySettings.iState = EMMFStateStopped;
1654 UpdatePolicyState();
1656 else if (iMode== EMMFStateRecording)
1658 iDevSoundObserver->RecordError(aError);
1660 else if (iMode== EMMFStateTonePlaying)
1662 iDevSoundObserver->ToneFinished(aError);
1664 //else can't handle error
1668 /********************************************************************************
1669 * Non Exported public functions ends here *
1670 ********************************************************************************/
1673 /********************************************************************************
1674 * Private functions begins here *
1675 ********************************************************************************/
1677 TInt CMMFDevSoundSvrImp::InitializeFormat(RMdaDevSound::TSoundFormatsSupportedBuf& aSupportedFormat,
1678 RMdaDevSound::TCurrentSoundFormatBuf& aFormat)
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;
1692 // default to Monophonic playback:
1693 aFormat().iChannels=1;
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;
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;
1732 // Mono and Stereo support
1733 if (aSupportedFormat().iChannels == 2)
1734 iDeviceCapabilities.iChannels = EMMFStereo;
1735 iDeviceCapabilities.iChannels |= EMMFMono;
1737 iDeviceCapabilities.iBufferSize = aSupportedFormat().iMaxBufferSize;
1739 iDeviceConfig.iRate = EMMFSampleRate8000Hz;
1740 iDeviceConfig.iEncoding = EMMFSoundEncoding16BitPCM;
1741 iDeviceConfig.iChannels = EMMFMono;
1748 * Makes request to Policy Server (asynchronous call)
1751 void CMMFDevSoundSvrImp::RequestPolicy()
1753 iDevSoundEventHandler->CancelReceiveEvents();
1754 iDevSoundEventHandler->ReceiveEvents();
1755 iAudioPolicyPrioritySettings.iCapabilities = iParent.CheckClientCapabilities();
1756 iAudioPolicyProxy->MakeRequest(iAudioPolicyPrioritySettings);
1761 * Creates buffer and begin playback using the specified tone generator.
1764 void CMMFDevSoundSvrImp::DoPlayL()
1766 // Delete any buffer from previous call and try to create maximum buffer
1767 // size. Double Buffer the Tone data.
1770 delete iToneBuffer1;
1771 iToneBuffer1 = NULL;
1773 //note the tone buffer needs to be the same as the pcm16->pcm16 'null'
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;
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);
1789 iToneBuffer1 = CMMFDataBuffer::NewL(useBufferOfSize);
1790 User::LeaveIfError(iCurrentGenerator->FillBuffer(iToneBuffer1->Data()));
1794 delete iToneBuffer2;
1795 iToneBuffer2 = NULL;
1797 iToneBuffer2 = CMMFDataBuffer::NewL(useBufferOfSize);
1798 User::LeaveIfError(iCurrentGenerator->FillBuffer(iToneBuffer2->Data()));
1800 // Assign active buffer
1801 iActiveToneBuffer = iToneBuffer1;
1803 // Hw device hasn't played anything yet so don't change
1804 // active buffer. This is checked in FillThisHwBuffer.
1805 iFirstCallFromHwDevice = ETrue;
1807 // Start HwDevice to play data
1808 User::LeaveIfError(iCMMFHwDevice->Start(EDevDecode, EDevOutFlow));
1814 * This method assigns the other buffer as active buffer. The tone audio
1815 * generator should fill data in the other buffer by now.
1818 void CMMFDevSoundSvrImp::SetActiveToneBuffer()
1820 if (iActiveToneBuffer == iToneBuffer1)
1821 iActiveToneBuffer = iToneBuffer2;
1822 else if (iActiveToneBuffer == iToneBuffer2)
1823 iActiveToneBuffer = iToneBuffer1;
1828 * This method fills data into the free buffer.
1831 * Error code. KErrNone if success.
1834 TInt CMMFDevSoundSvrImp::FillFreeToneBuffer()
1837 if (iActiveToneBuffer == iToneBuffer1)
1838 err = iCurrentGenerator->FillBuffer(iToneBuffer2->Data());
1839 else if (iActiveToneBuffer == iToneBuffer2)
1840 err = iCurrentGenerator->FillBuffer(iToneBuffer1->Data());
1846 * Updates the policy state based on Audio policy settings of this devsound instance
1849 TInt CMMFDevSoundSvrImp::UpdatePolicyState()
1851 TInt error = iAudioPolicyProxy->UpdateState(iAudioPolicyPrioritySettings);
1857 * Initializes audio device node by setting volume, and sampling rate.
1860 * Error Code. KErrNone if success.
1863 TInt CMMFDevSoundSvrImp::InitTask()
1865 // No Implementation
1873 * Returns an integer representing Sampling Frequency the device is currently
1877 * Sampling Frequency.
1880 TInt CMMFDevSoundSvrImp::SamplingFrequency()
1882 if(iDeviceConfig.iRate == EMMFSampleRate8000Hz)
1884 else if(iDeviceConfig.iRate == EMMFSampleRate11025Hz)
1886 else if(iDeviceConfig.iRate == EMMFSampleRate12000Hz)
1888 else if(iDeviceConfig.iRate == EMMFSampleRate16000Hz)
1890 else if(iDeviceConfig.iRate == EMMFSampleRate22050Hz)
1892 else if(iDeviceConfig.iRate == EMMFSampleRate24000Hz)
1894 else if(iDeviceConfig.iRate == EMMFSampleRate32000Hz)
1896 else if(iDeviceConfig.iRate == EMMFSampleRate44100Hz)
1898 else if(iDeviceConfig.iRate == EMMFSampleRate48000Hz)
1900 else if(iDeviceConfig.iRate == EMMFSampleRate88200Hz)
1902 else if(iDeviceConfig.iRate == EMMFSampleRate96000Hz)
1905 return 8000; //default
1910 * Returns an integer representing number of channels the device is currently
1914 * Number of audio channels 1 if mono, 2 if stereo.
1917 TInt CMMFDevSoundSvrImp::NumberOfChannels()
1919 if(iDeviceConfig.iChannels == EMMFMono)
1927 * Returns an integer representing number of bytes in each audio sample
1931 * Number of of bytes in each audio sample.
1934 TInt CMMFDevSoundSvrImp::BytesPerAudioSample()
1937 switch (iDeviceConfig.iEncoding)
1939 case EMMFSoundEncoding8BitPCM:
1940 case EMMFSoundEncoding8BitALaw:
1941 case EMMFSoundEncoding8BitMuLaw:
1946 case EMMFSoundEncoding16BitPCM:
1956 /********************************************************************************
1957 * Private functions ends here *
1958 ********************************************************************************/