Update contrib.
1 // Copyright (c) 2006-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.
18 #include "cdevaudiocontrol.h"
20 #include <a3f/audioprocessingunittypeuids.h>
21 #include <mmf/server/mmfswcodecwrappercustominterfacesuids.hrh>
22 #include <a3f/maudiocontext.h>
23 #include <a3f/maudiostream.h>
24 #include <a3f/maudiocodec.h>
25 #include <a3f/maudiogaincontrol.h>
28 const TInt KMicroSecondsInSecond = 1000000;
29 const TInt KDefaultBufferSize = 4096;
31 const TUint KMaxCallbacksExpected = 2;
32 const TUint KDefaultSampleRate = 8000;
33 const TUid KDefaultMode = {KA3FModeMonoValue};
35 class TSampleRateTableEntry
38 TInt iSampleRateValue;
39 TMMFSampleRate iSampleRate;
42 const TSampleRateTableEntry KRateTableLookup[] = {
43 { 8000, EMMFSampleRate8000Hz },
44 { 11025, EMMFSampleRate11025Hz },
45 { 12000, EMMFSampleRate12000Hz },
46 { 16000, EMMFSampleRate16000Hz },
47 { 22050, EMMFSampleRate22050Hz },
48 { 24000, EMMFSampleRate24000Hz },
49 { 32000, EMMFSampleRate32000Hz },
50 { 44100, EMMFSampleRate44100Hz },
51 { 48000, EMMFSampleRate48000Hz },
52 { 64000, EMMFSampleRate64000Hz },
53 { 88200, EMMFSampleRate88200Hz },
54 { 96000, EMMFSampleRate96000Hz },
56 const TInt KMaxSampleRateIndex = 11; // must agree with length of table
58 class TAudioModeTableEntry
61 TMMFMonoStereo iAudioModeValue;
65 const TAudioModeTableEntry KModeTableLookup[] = {
66 { EMMFMono, {KA3FModeMonoValue} },
67 { EMMFStereo, {KA3FModeStereoNonInterleavedValue} },
70 const TInt KMaxModeIndex = 1; // must agree with length of table
72 // ---------------------------------------------------------------------------
73 // Default constructor
74 // ---------------------------------------------------------------------------
76 CDevAudioControl::CDevAudioControl()
79 DP_CONTEXT(CDevAudioControl::CDevAudioControl *CD1*, CtxDevSound, DPLOCAL);
82 // Local cache default values
83 iCurrentSampleRate = KDefaultSampleRate;
84 iCurrentMode = KDefaultMode;
85 iOutstandingCallbacks = KMaxCallbacksExpected; //by default we expect 2 callbacks for capabilities.
86 iCallbackFromAdaptor = KCallbackNone;
92 void CDevAudioControl::ConstructL(CDevAudio* aDevAudio, MDevSoundAdaptationObserver& aDevSoundObserver)
95 DP_CONTEXT(CDevAudioControl::ConstructL *CD1*, CtxDevSound, DPLOCAL);
97 iDevAudio = aDevAudio;
98 iAdaptationObserver = &aDevSoundObserver;
100 iObserverRegistered = EFalse;
102 TAudioChannelGain left;
103 TAudioChannelGain right;
105 left.iLocation = TAudioChannelGain::ELeft;
106 right.iLocation = TAudioChannelGain::ERight;
108 User::LeaveIfError(iChannelGains.Append(left)); // assumed element 0 in rest of code
109 User::LeaveIfError(iChannelGains.Append(right)); // assumed element 1 in rest of code
111 // Note this could be delayed now (volume is internal to adaptor until later in cycle)
112 // Needed to allow CMMFDevSound::MaxVolume and similar calls before CMMFDevSound::InitializeL
113 TAny* interface(NULL);
114 interface = iDevAudio->iGainControl->Interface(KUidAudioGainControl);
115 iGainControl = static_cast<MAudioGainControl*>(interface);
119 // ---------------------------------------------------------------------------
121 // ---------------------------------------------------------------------------
123 CDevAudioControl::~CDevAudioControl()
125 DP_CONTEXT(CDevAudioControl::~CDevAudioControl *CD1*, CtxDevSound, DPLOCAL);
127 iChannelGains.Close();
128 iSupportedRates.Close();
129 iSupportedModes.Close();
133 // -----------------------------------------------------------------------------
136 TInt CDevAudioControl::CacheAudioCodecIf()
138 DP_CONTEXT(CDevAudioControl::CacheAudioCodecIf *CD1*, CtxDevSound, DPLOCAL);
140 if (iDevAudio->iAudioCodec==NULL)
142 DP0_RET(KErrNotReady,"%d");
145 if (iAudioCodecIf==NULL)
147 MAudioCodec* codecInterface = static_cast<MAudioCodec*>(iDevAudio->iAudioCodec->Interface(KUidAudioCodec));
148 __ASSERT_ALWAYS (codecInterface, CDevAudioControl::Panic(EAudioCodecIsNull));
149 iAudioCodecIf = codecInterface;
155 // -----------------------------------------------------------------------------
156 // CDevAudioControl::Initialize
157 // -----------------------------------------------------------------------------
159 TInt CDevAudioControl::Initialize(TUid /*aFormat*/)
161 DP_CONTEXT(CDevAudioControl::Initialize *CD1*, CtxDevSound, DPLOCAL);
164 iObserverRegistered = EFalse;
165 DP0_RET(KErrNone,"%d");
168 // -----------------------------------------------------------------------------
169 // CDevAudioControl::Uninitialize
170 // -----------------------------------------------------------------------------
172 TInt CDevAudioControl::Uninitialize()
174 DP_CONTEXT(CDevAudioControl::Uninitialize *CD1*, CtxDevSound, DPLOCAL);
177 // Remove pUnits only allowed when stream is uninitialized
178 TInt err = iDevAudio->iAudioStream->Uninitialize();
182 err = iDevAudio->CommitAudioContext();
186 iDevAudio->iActiveState = EDevSoundAdaptorUninitialising;
192 // -----------------------------------------------------------------------------
193 // CDevAudioControl::Unload
194 // -----------------------------------------------------------------------------
196 TInt CDevAudioControl::Unload()
198 DP_CONTEXT(CDevAudioControl::Unload *CD1*, CtxDevSound, DPLOCAL);
201 TInt err = iDevAudio->iAudioStream->Unload();
204 err = iDevAudio->CommitAudioContext();
208 iDevAudio->iActiveState = EDevSoundAdaptorUnloading;
214 // -----------------------------------------------------------------------------
215 // CDevAudioControl::GetCapabilities
216 // -----------------------------------------------------------------------------
218 TInt CDevAudioControl::GetCapabilities(TMMFCapabilities& aCap)
220 DP_CONTEXT(CDevAudioControl::GetCapabilities *CD1*, CtxDevSound, DPLOCAL);
222 // At this phase of CAP, we only care about current codec capabilities.
223 // This will be supported as soon as the A3F API changes to support this are ready
226 if (iDevAudio->iActiveState != EDevSoundAdaptorCreated_Uninitialised)
228 err = CacheAudioCodecIf();
236 err = iAudioCodecIf->GetSupportedModes(iSupportedModes);
239 aCap.iChannels = GetModes(iSupportedModes);
240 err = iAudioCodecIf->GetSupportedSamplesRates(iSupportedRates);
244 aCap.iRate = GetSampleRates(iSupportedRates);
248 //If was a problem getting sampleRates we donīt expect callbacks and return
249 iOutstandingCallbacks = 0;
255 //If was a problem getting modes we donīt expect callbacks and return
256 iOutstandingCallbacks = 0;
267 // -----------------------------------------------------------------------------
268 // CDevAudioControl::GetConfig
269 // -----------------------------------------------------------------------------
271 TInt CDevAudioControl::GetConfig(TMMFCapabilities& aConfig)
273 DP_CONTEXT(CDevAudioControl::GetConfig *CD1*, CtxDevSound, DPLOCAL);
277 //TODO add a return error code if the sample rate or the channels are not found
278 //We need to transform the local values to a supported value for the client
279 aConfig.iRate = static_cast<TMMFSampleRate>(GetSampleRate(iCurrentSampleRate));
280 aConfig.iChannels = static_cast<TMMFMonoStereo>(GetMode(iCurrentMode));
281 aConfig.iBufferSize = KDefaultBufferSize;
283 DP2(DLINFO, "rate 0x%x, channels 0x%x", aConfig.iRate, aConfig.iChannels);
288 // -----------------------------------------------------------------------------
289 // CDevAudioControl::SetConfig
290 // -----------------------------------------------------------------------------
292 TInt CDevAudioControl::SetConfig(const TMMFCapabilities& aConfig)
294 DP_CONTEXT(CDevAudioControl::SetConfig *CD1*, CtxDevSound, DPLOCAL);
297 // TODO need to ensure if iChannels or iSampleRate is outside known values, then
298 // the code handles that gracefully and returns the appropriate error code
301 TUid mode = KNullUid;
302 //Reset the desired values
303 iDesiredSampleRate = 0;
304 iDesiredMode = KNullUid;
306 err = ResolveMode(aConfig.iChannels, mode);
312 err = ResolveSampleRate(aConfig.iRate, iDesiredSampleRate);
318 // At this phase of CAP, we only care about codec, which checks config against
319 // its own capabilities. Verification against stream specific capabilities
320 // should be added later on.
322 err = CacheAudioCodecIf();
328 err = iAudioCodecIf->SetSampleRate(iDesiredSampleRate);
333 err = iAudioCodecIf->SetMode(mode);
338 err = iDevAudio->CommitAudioContext();
348 // -----------------------------------------------------------------------------
349 // CDevAudioControl::ProcessInit
350 // -----------------------------------------------------------------------------
352 TInt CDevAudioControl::ProcessInit()
354 DP_CONTEXT(CDevAudioControl::ProcessInit *CD1*, CtxDevSound, DPLOCAL);
357 DP0_RET(KErrNone,"%d");
360 // -----------------------------------------------------------------------------
361 // CDevAudioControl::ProcessData
362 // -----------------------------------------------------------------------------
364 void CDevAudioControl::ProcessData()
366 DP_CONTEXT(CDevAudioControl::ProcessData *CD1*, CtxDevSound, DPLOCAL);
372 // -----------------------------------------------------------------------------
373 // CDevAudioControl::GetSamples
374 // -----------------------------------------------------------------------------
376 TInt CDevAudioControl::GetSamples()
378 DP_CONTEXT(CDevAudioControl::GetSamples *CD1*, CtxDevSound, DPLOCAL);
381 TInt samplesplayed(0);
383 TTimeIntervalMicroSeconds timeProcessed(0);
384 err = iDevAudio->iAudioStream->GetStreamTime(timeProcessed);
386 DP1(DLINFO,"CDevAudioControl::GetSamples iCurrentSampleRate %d",iCurrentSampleRate);
390 samplesplayed = (timeProcessed.Int64() * iCurrentSampleRate + KMicroSecondsInSecond/2) / TInt64(KMicroSecondsInSecond);
392 //TODO manage the error
394 DP0_RET(samplesplayed, "%d");
397 // -----------------------------------------------------------------------------
398 // CDevAudioControl::Stop
399 // -----------------------------------------------------------------------------
401 TInt CDevAudioControl::Stop()
403 DP_CONTEXT(CDevAudioControl::Stop *CD1*, CtxDevSound, DPLOCAL);
406 DP0_RET(KErrNone, "%d");
409 // -----------------------------------------------------------------------------
410 // CDevAudioControl::Pause
411 // -----------------------------------------------------------------------------
413 TInt CDevAudioControl::Pause()
415 DP_CONTEXT(CDevAudioControl::Pause *CD1*, CtxDevSound, DPLOCAL);
418 DP0_RET(KErrNone, "%d");
421 // -----------------------------------------------------------------------------
422 // CDevAudioControl::CustomInterface
423 // -----------------------------------------------------------------------------
425 TAny* CDevAudioControl::CustomInterface(TUid aInterfaceId)
427 DP_CONTEXT(CDevAudioControl::CustomInterface *CD1*, CtxDevSound, DPLOCAL);
431 if(iDevAudio->iAudioStream)
433 TAny* ptr = iDevAudio->iAudioStream->Interface(KUidExtensionInferface);
436 MCustomInterfaceSupport* ciSupport = static_cast<MCustomInterfaceSupport*>(ptr);
437 if(!iObserverRegistered)
439 err = ciSupport->RegisterObserver(*this);
442 iObserverRegistered = ETrue;
445 err = ciSupport->RequestCustomInterface(aInterfaceId, ciPtr);
452 DP0_RET(ciPtr, "0x%x");
455 // -----------------------------------------------------------------------------
456 // CDevAudioControl::SetGain
457 // -----------------------------------------------------------------------------
458 TInt CDevAudioControl::SetGains(TInt aDevSoundGain, TInt aDevSoundMaxGain, TInt aBalance[2], const TTimeIntervalMicroSeconds& aRampDuration, TBool aBecomingActive)
460 DP_CONTEXT(CDevAudioControl::SetGains *CD1*, CtxDevSound, DPLOCAL);
462 ASSERT(aDevSoundGain>=0 && aDevSoundGain<=aDevSoundMaxGain); // higher layer assumed to scale
463 ASSERT(aBalance[ELeftCh]>=0 && aBalance[ELeftCh]<=100);
464 ASSERT(aBalance[ERightCh]>=0 && aBalance[ERightCh]<=100);
465 ASSERT(aDevSoundMaxGain>0); // assumed max gain is positive
467 TInt err = iGainControl->GetMaxGain(a3fMaxGain);
470 iLegacyGain = TInt(TReal(aDevSoundGain)*TReal(a3fMaxGain)/TReal(aDevSoundMaxGain)+0.5);
471 ASSERT(iLegacyGain>=0 && iLegacyGain<=a3fMaxGain);
472 iLegacyLeft = aBalance[ELeftCh];
473 iLegacyRight = aBalance[ERightCh];
477 // VolumeRamp is only applied when DevSound is becoming active
480 if (aRampDuration > 0 && aBecomingActive)
482 err = iGainControl->SetGain(iChannelGains, KUidGainSawTooth, aRampDuration);
486 err = iGainControl->SetGain(iChannelGains);
490 // This call will result on commit only when we are already active
491 // otherwise the changes will be commited by the DevAudioControl
492 // It means we're here due to RequestGainAndBalance call
493 if(err == KErrNone && !aBecomingActive)
495 err = iDevAudio->CommitAudioContext();
502 // -----------------------------------------------------------------------------
503 // CDevAudioControl::MapAndSetGains
504 // -----------------------------------------------------------------------------
506 void CDevAudioControl::MapGains()
508 DP_CONTEXT(CDevAudioControl::MapGains *CD1*, CtxDevSound, DPLOCAL);
511 // Map legacy values to CAP channel array.
512 if ( iLegacyLeft == iLegacyRight )
514 iChannelGains[ELeftCh].iGain = iLegacyGain;
515 iChannelGains[ERightCh].iGain = iLegacyGain;
517 else if ( iLegacyLeft > iLegacyRight )
519 iChannelGains[ELeftCh].iGain = iLegacyGain;
520 iChannelGains[ERightCh].iGain =
521 static_cast<TUint>((iLegacyGain*iLegacyRight)/iLegacyLeft);
525 iChannelGains[ERightCh].iGain = iLegacyGain;
526 iChannelGains[ELeftCh].iGain =
527 static_cast<TUint>((iLegacyGain*iLegacyLeft)/iLegacyRight);
533 // -----------------------------------------------------------------------------
534 // CDevAudioControl::DestroyChain
535 // -----------------------------------------------------------------------------
537 TBool CDevAudioControl::DestroyChain()
539 DP_CONTEXT(CDevAudioControl::DestroyChain *CD1*, CtxDevSound, DPLOCAL);
543 TBool readyToDestroy = EFalse;
544 switch(iDevAudio->iActiveState)
546 case EDevSoundAdaptorActive_Active:
547 case EDevSoundAdaptorPaused_Primed:
549 err = iDevAudio->iAudioStream->Stop();
552 err = iDevAudio->CommitAudioContext();
556 iDevAudio->iActiveState = EDevSoundAdaptorStopping;
560 case EDevSoundAdaptorInitialised_Idle:
562 err = iDevAudio->iAudioStream->Unload();
565 err = iDevAudio->CommitAudioContext();
569 iDevAudio->iActiveState = EDevSoundAdaptorUnloading;
573 case EDevSoundAdaptorInitialised_Initialised:
575 err = iDevAudio->iAudioStream->Uninitialize();
578 err = iDevAudio->CommitAudioContext();
582 iDevAudio->iActiveState = EDevSoundAdaptorUninitialising;
586 case EDevSoundAdaptorCreated_Uninitialised:
587 readyToDestroy = ETrue;
589 case EDevSoundAdaptorUnitialised_Uninitialised:
590 //If following condition is true, then we are here because of a
591 //pre-emption clash in last Commit cycle started from
592 //CDevCommonControl::ContextEventUpdateWithStateEventNoError.
593 if(iDevAudio->iPreviousState == EDevSoundAdaptorRemovingProcessingUnits)
595 err = RemoveProcessingUnits();
602 // Destroy sequence fail!
605 DP0(DLINFO, "================ Destroy sequence fail! ================");
606 readyToDestroy = ETrue;
608 // Set the flag only when needed
609 iDevAudio->iClosing = !readyToDestroy;
610 DP0_RET(readyToDestroy,"%d");
614 // -----------------------------------------------------------------------------
615 // CDevAudioControl::RemoveProcessingUnits
616 // -----------------------------------------------------------------------------
618 TInt CDevAudioControl::RemoveProcessingUnits()
620 DP_CONTEXT(CDevAudioControl::RemoveProcessingUnits *CD1*, CtxDevSound, DPLOCAL);
623 // Remove pUnits only allowed when stream is uninitialized
624 TInt err = iDevAudio->iAudioStream->RemoveProcessingUnit(iDevAudio->iAudioSource);
628 err = iDevAudio->iAudioStream->RemoveProcessingUnit(iDevAudio->iAudioSink);
632 err = iDevAudio->iAudioStream->RemoveProcessingUnit(iDevAudio->iAudioCodec);
637 err = iDevAudio->CommitAudioContext();
642 iDevAudio->iActiveState = EDevSoundAdaptorRemovingProcessingUnits;
647 // -----------------------------------------------------------------------------
648 // From class MAudioStreamObserver
649 // CDevAudioControl::StateEvent
650 // -----------------------------------------------------------------------------
652 void CDevAudioControl::StateEvent(MAudioStream& /*aStream*/,
654 TAudioState /*aNewState*/)
656 DP_CONTEXT(CDevAudio::StateEvent *CD1*, CtxDevSound, DPLOCAL);
662 // -----------------------------------------------------------------------------
663 // From class MAudioStreamObserver
664 // CDevAudioControl::AddProcessingUnitComplete
665 // -----------------------------------------------------------------------------
667 void CDevAudioControl::AddProcessingUnitComplete(MAudioStream& /*aStream*/,
668 MAudioProcessingUnit* /*aInstance*/,
673 // -----------------------------------------------------------------------------
674 // From class MAudioStreamObserver
675 // CDevAudioControl::RemoveProcessingUnitComplete
676 // -----------------------------------------------------------------------------
678 void CDevAudioControl::RemoveProcessingUnitComplete(MAudioStream& /*aStream*/,
679 MAudioProcessingUnit* /*aInstance*/,
684 // -----------------------------------------------------------------------------
685 // From class MAudioStreamObserver
686 // CDevAudioControl::ProcessingFinished
687 // -----------------------------------------------------------------------------
689 void CDevAudioControl::ProcessingFinished(MAudioStream& /*aStream*/)
693 // -----------------------------------------------------------------------------
694 // From class MAudioStreamObserver
695 // CDevAudioControl::FlushComplete
696 // -----------------------------------------------------------------------------
698 void CDevAudioControl::FlushComplete (MAudioStream& /*aStream*/, TInt aError)
700 // no action needed - should complete as part of the ContextEvent.
701 // otherwise could callback.
704 if(iPauseResumeSequenceDueToEmptyBuffers)
706 // Flush operation failed
707 if(aError != KErrNone)
709 iPauseResumeSequenceDueToEmptyBuffers = EFalse;
710 iAdaptationObserver->CallbackFromAdaptorReceived(KCallbackFlushComplete, aError);
712 // Handle throw-off scenarios, resume is not possible from here
713 // 1. ProcessingFinished has occurred
714 // 2. Preemption occurred
715 else if(iCallbackFromAdaptor != KCallbackNone ||
716 iDevAudio->iActiveState != EDevSoundAdaptorPaused_Primed)
718 iPauseResumeSequenceDueToEmptyBuffers = EFalse;
719 iAdaptationObserver->CallbackFromAdaptorReceived(KCallbackFlushComplete, KErrNone);
727 iPauseResumeSequenceDueToEmptyBuffers = EFalse;
728 iAdaptationObserver->CallbackFromAdaptorReceived(KCallbackFlushComplete, aError);
730 // Once ContextEvent be received
731 // EmptyBuffers can be considered completed
734 // EmptyBuffers operation has concluded here
735 // we didn't go through pause - resume sequence
738 iAdaptationObserver->CallbackFromAdaptorReceived(KCallbackFlushComplete, aError);
742 // -----------------------------------------------------------------------------
743 // From class MAudioGainControlObserver
744 // CDevAudioControl::MaxRampTimeChanged
745 // -----------------------------------------------------------------------------
747 void CDevAudioControl::MaxRampTimeChanged(MAudioGainControl& /*aGain*/)
749 DP_CONTEXT(CDevAudioControl::MaxRampTimeChanged *CD1*, CtxDevSound, DPLOCAL);
751 // this is not cached, no actions needed
755 // -----------------------------------------------------------------------------
756 // From class MAudioGainControlObserver
757 // CDevAudioControl::MaxGainChanged
758 // -----------------------------------------------------------------------------
760 void CDevAudioControl::MaxGainChanged(MAudioGainControl& /*aGain*/)
762 DP_CONTEXT(CDevAudioControl::MaxGainChanged *CD1*, CtxDevSound, DPLOCAL);
764 // this is not cached, no actions needed
768 // -----------------------------------------------------------------------------
769 // From class MAudioGainControlObserver
770 // CDevAudioControl::GainChanged
771 // -----------------------------------------------------------------------------
773 void CDevAudioControl::GainChanged(MAudioGainControl& aGain, TInt aError)
775 DP_CONTEXT(CDevAudioControl::GainChanged *CD1*, CtxDevSound, DPLOCAL);
776 DP1_IN("aError=%d", aError);
778 if(aError != KErrNone)
780 // Either our request failed, or MMRC has forced some values, and we
781 // have to update local values.
782 aGain.GetGain(iChannelGains);
783 ASSERT(iChannelGains.Count()==2);
784 // Map CAP channel array to legacy values.
785 // assumption: left%+right%=100
786 if ( iChannelGains[ELeftCh].iGain == iChannelGains[ERightCh].iGain )
788 iLegacyGain = iChannelGains[ELeftCh].iGain;
792 else if ( iChannelGains[ELeftCh].iGain > iChannelGains[ERightCh].iGain )
794 iLegacyGain = iChannelGains[ELeftCh].iGain;
795 iLegacyLeft = static_cast<TUint>
796 ((100*iLegacyGain)/(iLegacyGain+iChannelGains[ERightCh].iGain));
797 iLegacyRight = 100 - iLegacyLeft;
798 //(not that accurate, but sufficient for now)
802 iLegacyGain = iChannelGains[ERightCh].iGain;
803 iLegacyRight = static_cast<TUint>
804 ((100*iLegacyGain)/(iLegacyGain+iChannelGains[ELeftCh].iGain));
805 iLegacyLeft = 100 - iLegacyRight;
808 DP3(DLINFO,"New values :iLegacyGain %d, iLegacyLeft %d, iLegacyRight %d",
809 iLegacyGain,iLegacyLeft,iLegacyRight);
813 // our request completed succesfully, no need to update cached values
814 // just print values in debug version
816 RArray<TAudioChannelGain> gains;
820 aGain.GetGain(gains);
821 ASSERT(gains.Count()==2);
822 if ( iChannelGains[ELeftCh].iGain == iChannelGains[ERightCh].iGain )
824 gain = iChannelGains[ELeftCh].iGain;
828 else if ( iChannelGains[ELeftCh].iGain > iChannelGains[ERightCh].iGain )
830 gain = iChannelGains[ELeftCh].iGain;
832 static_cast<TUint>((100*gain)/(gain+iChannelGains[ERightCh].iGain));
837 gain = iChannelGains[ERightCh].iGain;
839 static_cast<TUint>((100*gain)/(gain+iChannelGains[ELeftCh].iGain));
843 DP3(DLINFO,"KErrNone (gain %d, left %d, right %d)", gain,left,right);
850 // -----------------------------------------------------------------------------
851 // From class MAudioCodecObserver
852 // CDevAudioControl::SampleRateSet
853 // -----------------------------------------------------------------------------
854 void CDevAudioControl::SampleRateSet(TInt aError)
858 //Review if we call SetConfig or is only the first time that we load the codec
859 if (iDesiredSampleRate > 0)
861 iCurrentSampleRate = iDesiredSampleRate;
866 iAdaptationObserver->NotifyError(aError);
868 iDesiredSampleRate = 0;
871 // -----------------------------------------------------------------------------
872 // From class MAudioCodecObserver
873 // CDevAudioControl::ModeSet
874 // -----------------------------------------------------------------------------
875 void CDevAudioControl::ModeSet(TInt aError)
879 //Review if we call SetConfig or is only the first time that we load the codec
880 if (iDesiredMode != KNullUid)
882 iCurrentMode = iDesiredMode;
887 iAdaptationObserver->NotifyError(aError);
889 iDesiredMode = KNullUid;
892 // -----------------------------------------------------------------------------
893 // From class MAudioCodecObserver
894 // CDevAudioControl::GetSupportedSampleRatesComplete
895 // -----------------------------------------------------------------------------
896 void CDevAudioControl::GetSupportedSampleRatesComplete(TInt aError)
898 iSupportedRates.Reset();
899 CompleteMessageCap(aError);
902 // -----------------------------------------------------------------------------
903 // From class MAudioCodecObserver
904 // CDevAudioControl::GetSupportedModesComplete
905 // -----------------------------------------------------------------------------
906 void CDevAudioControl::GetSupportedModesComplete(TInt aError)
908 iSupportedModes.Reset();
909 CompleteMessageCap(aError);
912 // -----------------------------------------------------------------------------
913 // CDevAudioControl::CompleteMessageCap
914 // -----------------------------------------------------------------------------
915 void CDevAudioControl::CompleteMessageCap(TInt aError)
917 if (iOutstandingCallbacks > 1) //waiting until the 2 outstanding callbacks arrival.
919 iOutstandingCallbacks--;
920 iError = aError; //keeping the error.
924 if (iError == KErrNone)
926 iAdaptationObserver->AsynchronousOperationComplete(aError, ETrue);
930 iAdaptationObserver->AsynchronousOperationComplete(iError, ETrue);
933 iOutstandingCallbacks = KMaxCallbacksExpected;
937 // -----------------------------------------------------------------------------
938 // CDevAudioControl::SetToneData
939 // -----------------------------------------------------------------------------
941 TInt CDevAudioControl::SetToneData(TToneData& /*aToneData*/)
943 DP_CONTEXT(CDevAudioControl::SetToneData *CD1*, CtxDevSound, DPLOCAL);
945 DP0_RET(KErrNotSupported, "%d");
949 // -----------------------------------------------------------------------------
950 // From class MAudioContextObserver
951 // CDevAudio::ContextEvent
952 // -----------------------------------------------------------------------------
954 void CDevAudioControl::ContextEvent(TUid aEvent, TInt aError)
956 DP_CONTEXT(CDevAudioControl::ContextEvent *CD1*, CtxDevSound, DPLOCAL);
959 if(!(iAdaptationObserver->AdaptorControlsContext()))
961 iIgnoreAsyncOpComplete = ETrue;
964 if (aEvent == KUidA3FContextUpdateComplete)
966 if(iIgnoreAsyncOpComplete)
968 iAdaptationObserver->PreemptionFinishedCallbackReceived(ETrue);
969 iIgnoreAsyncOpComplete = EFalse;
973 iAdaptationObserver->AsynchronousOperationComplete(aError, ETrue);
976 else if(aEvent == KUidA3FContextPreEmption)
978 //If we are in a normal pre-emption cycle, we should not be in a mid-state.
979 __ASSERT_DEBUG(!iDevAudio->IsMidState(iDevAudio->iActiveState), Panic(EInvalidStateDuringPreemptionCycle));
980 iIgnoreAsyncOpComplete = ETrue;
981 iAdaptationObserver->PreemptionStartedCallbackReceived();
983 //In a clashing pre-emption cycle we must be in a commit cycle, so do nothing here - CDevCommonControl deals
989 // -----------------------------------------------------------------------------
990 // From class MCustomInterfaceSupportObserver
991 // CDevAudio::CustomInterfaceRemoval
992 // -----------------------------------------------------------------------------
994 void CDevAudioControl::CustomInterfaceRemoval(TUid aUid, TAny* /*aPtr*/)
996 DP_CONTEXT(CDevAudioControl::CustomInterfaceRemoval *CD1*, CtxDevSound, DPLOCAL);
998 // TODO: Review this functionality
999 iAdaptationObserver->InterfaceDeleted(aUid);
1003 // ---------------------------------------------------------------------------
1004 // CDevAudioControl::ResolveSampleRate
1005 // ---------------------------------------------------------------------------
1006 TInt CDevAudioControl::ResolveSampleRate(TInt aSampleRate, TInt& aSampleRateValue)
1008 DP_CONTEXT(CDevAudioControl::ResolveSampleRate, CtxDevSound, DPLOCAL);
1010 TInt err(KErrArgument);
1012 for (TUint i=0; i<=KMaxSampleRateIndex; i++)
1014 if(KRateTableLookup[i].iSampleRate == aSampleRate)
1016 aSampleRateValue = KRateTableLookup[i].iSampleRateValue;
1022 //To avoid the value return a non desired value.
1023 if (err != KErrNone)
1025 aSampleRateValue = 0;
1032 // ---------------------------------------------------------------------------
1033 // CDevAudioControl::ResolveMode
1034 // ---------------------------------------------------------------------------
1035 TInt CDevAudioControl::ResolveMode(TUint aModeValue, TUid& aMode)
1037 DP_CONTEXT(CDevAudioControl::ResolveMode *CD1*, CtxDevSound, DPLOCAL);
1039 TInt err(KErrArgument);
1042 for (TInt i=0; i<=KMaxModeIndex; i++)
1044 const TAudioModeTableEntry& entry = KModeTableLookup[i];
1045 if (entry.iAudioModeValue == aModeValue)
1047 aMode = entry.iAudioMode;
1056 // ---------------------------------------------------------------------------
1057 // CDevAudioControl::GetModes
1058 // ---------------------------------------------------------------------------
1059 TUint CDevAudioControl::GetModes(const RArray<TUid>& aMode)
1061 DP_CONTEXT(CDevAudioControl::GetModes *CD1*, CtxDevSound, DPLOCAL);
1065 TInt count = aMode.Count();
1067 for (TInt i=0; i<count; i++)
1069 result |= GetMode(aMode[i]);
1071 DP0_RET(result,"%d");
1075 // ---------------------------------------------------------------------------
1076 // CDevAudioControl::GetMode
1077 // ---------------------------------------------------------------------------
1078 TUint CDevAudioControl::GetMode(TUid aMode)
1080 DP_CONTEXT(CDevAudioControl::GetMode *CD1*, CtxDevSound, DPLOCAL);
1085 for (TInt e=0; e<=KMaxModeIndex; e++)
1087 if(KModeTableLookup[e].iAudioMode == aMode)
1089 result = KModeTableLookup[e].iAudioModeValue;
1093 DP0_RET(result,"%d");
1096 // ---------------------------------------------------------------------------
1097 // CDevAudioControl::GetSampleRates
1098 // ---------------------------------------------------------------------------
1099 TUint CDevAudioControl::GetSampleRates(const RArray<TInt>& aSampleRates)
1101 DP_CONTEXT(CDevAudioControl::GetSampleRates *CD1*, CtxDevSound, DPLOCAL);
1105 TInt count = aSampleRates.Count();
1107 for (TInt i=0; i<count; i++)
1109 result |= GetSampleRate(aSampleRates[i]);
1111 DP0_RET(result,"%d");
1114 // ---------------------------------------------------------------------------
1115 // CDevAudioControl::GetSampleRate
1116 // ---------------------------------------------------------------------------
1117 TUint CDevAudioControl::GetSampleRate(TInt aSampleRates)
1119 DP_CONTEXT(CDevAudioControl::GetSampleRate *CD1*, CtxDevSound, DPLOCAL);
1124 TInt lowerbound = 0;
1125 TInt upperbound = KMaxSampleRateIndex;
1127 if ((aSampleRates < KRateTableLookup[lowerbound].iSampleRateValue) || (aSampleRates > KRateTableLookup[upperbound].iSampleRateValue))
1129 //value request not found in the array.
1130 DP0_RET(result,"%d");
1134 position = ( lowerbound + upperbound) / 2;
1136 while((KRateTableLookup[position].iSampleRateValue != aSampleRates) && (lowerbound <= upperbound))
1138 if (KRateTableLookup[position].iSampleRateValue > aSampleRates)
1140 upperbound = position - 1;
1144 lowerbound = position + 1;
1146 position = (lowerbound + upperbound) / 2;
1149 result = KRateTableLookup[position].iSampleRate;
1151 DP0_RET(result,"%d");
1154 // ---------------------------------------------------------------------------
1155 // CDevAudioControl::ProcessingFinishedReceived
1156 // ---------------------------------------------------------------------------
1157 TInt CDevAudioControl::ProcessingFinishedReceived(TBool& /*aAyncOperation*/)
1162 // ---------------------------------------------------------------------------
1163 // CDevAudioControl::ProcessingError
1164 // ---------------------------------------------------------------------------
1165 TInt CDevAudioControl::ProcessingError(TBool& /*aAyncOperation*/)
1170 // ---------------------------------------------------------------------------
1171 // CDevAudioControl::RequestEmptyBuffers
1172 // ---------------------------------------------------------------------------
1173 TInt CDevAudioControl::RequestEmptyBuffers()
1175 DP_CONTEXT(CDevAudioControl::RequestEmptyBuffers *CD1*, CtxDevSound, DPLOCAL);
1178 TInt err(KErrNotReady);
1182 if(iDevAudio->iActiveState == EDevSoundAdaptorPaused_Primed)
1184 err = iDevAudio->iAudioStream->Flush();
1186 else if (iDevAudio->iActiveState == EDevSoundAdaptorActive_Active)
1191 iPauseResumeSequenceDueToEmptyBuffers = ETrue;
1199 void CDevAudioControl::Panic(TDevSoundAdaptorPanicCode aCode)
1201 _LIT(KMMFDevSoundAdaptorPanicCategory, "DevSoundAdaptor");
1202 User::Panic(KMMFDevSoundAdaptorPanicCategory, aCode);
1205 // ---------------------------------------------------------------------------
1206 // CDevAudioControl::GetTimePlayed
1207 // ---------------------------------------------------------------------------
1208 TInt CDevAudioControl::GetTimePlayed(TTimeIntervalMicroSeconds& aTime)
1210 DP_CONTEXT(CDevAudioControl::GetTimePlayed *CD1*, CtxDevSound, DPLOCAL);
1212 TInt err = iDevAudio->iAudioStream->GetStreamTime(aTime);
1216 // ---------------------------------------------------------------------------
1217 // CDevAudioControl::Resume
1218 // ---------------------------------------------------------------------------
1219 TBool CDevAudioControl::Resume()
1221 DP_CONTEXT(CDevAudioControl::Stop *CD1*, CtxDevSound, DPLOCAL);
1224 DP0_RET(KErrNone, "%d");
1227 // -----------------------------------------------------------------------------
1228 // CDevAudioControl::BufferErrorEvent
1229 // -----------------------------------------------------------------------------
1231 void CDevAudioControl::BufferErrorEvent()
1233 ASSERT(EFalse); //This should never happen