Update contrib.
3 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
4 // All rights reserved.
5 // This component and the accompanying materials are made available
6 // under the terms of "Eclipse Public License v1.0"
7 // which accompanies this distribution, and is available
8 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
10 // Initial Contributors:
11 // Nokia Corporation - initial contribution.
20 #include <a3f/a3fbase.h>
21 #include <a3f/a3ffourcclookup.h>
22 #include <a3f/audioprocessingunittypeuids.h>
23 #include "maudiocodecadaptationobserver.h"
24 #include "audiocodec.h"
25 #include "resourcedata.h"
27 // THIS WILL REMAIN UNTIL THE REQUIREMENT WILL BE DEFINED
28 // THIS IMPLEMENTATION WILL WORK ONLY FOR HW DEVICES IMPLEMNETED AS SOFTWARE CODEC WRAPPERS
29 #define INCLUDE_HWDEVICES_AS_SWCODEC_WRAPPERS
31 #ifdef INCLUDE_HWDEVICES_AS_SWCODEC_WRAPPERS
32 #include <mmf/server/mmfswcodecwrappercustominterfacesuids.hrh>
35 const TInt KMicroSecsInOneSec = 1000000;
36 const TInt KHwDeviceDefaultDataLength= 9;
37 const TUint KDefaultMaxGain = 255; // TODO should discover at run time but this is value of current Symbian sound driver adaptor
39 //Values to find the request ask by the client
40 const TInt KRequestSampleRate = 0x0001;
41 const TInt KRequestMode = 0x0002;
42 const TAudioModeTableEntry KModeTableLookup[] = {
43 { EMMFMono, {KA3FModeMonoValue} },
44 { EMMFStereo, {KA3FModeStereoNonInterleavedValue} },
48 // ---------------------------------------------------------------------------
50 // ---------------------------------------------------------------------------
51 CAudioCodec::CAudioCodec(TUid aTypeId, const CFourCCConvertor& aFourCCConvertor)
52 : CActive(EPriorityStandard),
54 iHwDeviceState(EIdle),
55 iLastBufferAck(EFalse),
56 iRampOperation(KNullUid)
59 DP_CONTEXT(CAudioCodec::CAudioCodec *CD1*, CtxDevSound, DPLOCAL);
61 if(aTypeId==KUidAudioEncoder)
65 else if(aTypeId==KUidAudioDecoder)
69 iFourCCConvertor = static_cast<CFourCCConvertor*>( const_cast<CFourCCConvertor*>(&aFourCCConvertor) );
71 iHwDeviceInitArgs.iEapStreamId = 0;
72 iHwDeviceInitArgs.iPolicyId = 0;
76 // ---------------------------------------------------------------------------
78 // ---------------------------------------------------------------------------
79 EXPORT_C CAudioCodec* CAudioCodec::NewL(TUid aTypeId, const CFourCCConvertor& aFourCCConvertor)
81 DP_STATIC_CONTEXT(CAudioCodec::NewL *CD0*, CtxDevSound, DPLOCAL);
83 CAudioCodec* self = new(ELeave)CAudioCodec(aTypeId, aFourCCConvertor);
84 CleanupStack::PushL(self);
86 CleanupStack::Pop(self);
87 DP0_RET(self, "0x%x");
90 // ---------------------------------------------------------------------------
91 // Second phase constructor
92 // ---------------------------------------------------------------------------
93 void CAudioCodec::ConstructL()
95 DP_CONTEXT(CAudioCodec::ConstructL *CD1*, CtxDevSound, DPLOCAL);
97 CActiveScheduler::Add(this);
101 // ---------------------------------------------------------------------------
103 // ---------------------------------------------------------------------------
104 CAudioCodec::~CAudioCodec()
106 DP_CONTEXT(CAudioCodec::~CAudioCodec *CD1*, CtxDevSound, DPLOCAL);
108 iAudioCodecObservers.Close();
111 if (!iHwDeviceState == EStopped)
113 DP0(DLINFO, "StopAndDeleteCodec");
114 iHwDevice->StopAndDeleteCodec();
123 // ---------------------------------------------------------------------------
124 // CAudioCodec::SetFormat
125 // ---------------------------------------------------------------------------
126 EXPORT_C TInt CAudioCodec::SetFormat(TUid aFormat)
128 DP_CONTEXT(CAudioCodec::SetFormat *CD1*, CtxDevSound, DPLOCAL);
131 DP0_RET(KErrNone, "%d");
134 // ---------------------------------------------------------------------------
135 // CAudioCodec::Initialize
136 // ---------------------------------------------------------------------------
137 EXPORT_C TInt CAudioCodec::Initialize()
139 DP_CONTEXT(CAudioCodec::Initialize *CD1*, CtxDevSound, DPLOCAL);
143 err = iFourCCConvertor->FormatToFourCC(iFormat,aFourCC);
144 if(err == KErrNotFound)
146 err = KErrNotSupported;
150 TRAP(err, FourCCToHwDeviceUidL(aFourCC, iMode, iDeviceUid) );
154 err = LoadHwDevice();
157 #ifdef INCLUDE_HWDEVICES_AS_SWCODEC_WRAPPERS
160 TUid interfaceUid = {0};
161 TAny* interface = NULL;
162 if (iMode == EDecode)
164 interfaceUid.iUid = KMmfPlaySettingsCustomInterface;
166 else if(iMode == EEncode)
168 interfaceUid.iUid = KMmfRecordSettingsCustomInterface;
171 // This call at the sw codec wrapper creates the custom interfaces for playing and record
174 interface = iHwDevice->CustomInterface(interfaceUid);
175 if (iMode == EDecode)
177 iPlayCustomInterface = static_cast<MPlayCustomInterface*>(interface);
179 else if(iMode == EEncode)
181 iRecordCustomInterface = static_cast<MRecordCustomInterface*>(interface);
189 err = InitHwDevice();
194 // ---------------------------------------------------------------------------
196 // ---------------------------------------------------------------------------
197 EXPORT_C TInt CAudioCodec::Load(TInt aSampleRate, TUid aMode)
199 DP_CONTEXT(CAudioCodec::Load *CD1*, CtxDevSound, DPLOCAL);
201 iSampleRateConfig = aSampleRate;
204 err = SetHwDeviceConfig();
208 // ---------------------------------------------------------------------------
209 // CAudioCodec::Start
210 // ---------------------------------------------------------------------------
211 EXPORT_C TInt CAudioCodec::Start()
213 DP_CONTEXT(CAudioCodec::Start *CD1*, CtxDevSound, DPLOCAL);
216 iLastBuffer = EFalse;
218 // Needed since ToneHwDevice only exchange one buffer with its client
219 // Resume shouldn't clear the last buffer flag
220 // since this wont' result on a new buffer request
221 if(iHwDeviceState == EPaused && iDeviceUid.iUid == KUidToneHwDevice)
228 PRF(PRF_ID, PRF_START, PRF_TIME, AA_DS_StartHwDevice, "");
229 if (iMode == EDecode)
232 err = iHwDevice->Start(EDevDecode, EDevOutFlow);
233 DP1(DLINFO,"hwdevice decode start: error %d",err);
234 iIgnoreUnderflowInterface = reinterpret_cast<MIgnoreUnderflowEventsCustomInterface*>(iHwDevice->CustomInterface(KIgnoreUnderflowCustomInterfaceTypeUid));
235 if(iIgnoreUnderflowInterface)
237 iIgnoreUnderflowInterface->IgnoreUnderflowEvents();
240 else if (iMode == EEncode)
243 err = iHwDevice->Start(EDevEncode, EDevInFlow);
244 DP1(DLINFO,"hwdevice encode start: error %d",err);
248 err = KErrNotSupported;
249 DP1(DLINFO,"CAudioCodec::StartHwDevice - Unknown mode %d", iMode);
251 PRF(PRF_ID, PRF_STOP, PRF_TIME, AA_DS_StartHwDevice, "");
255 err = KErrHardwareNotAvailable;
260 iHwDeviceState = ERunning;
262 iLastBufferAck = EFalse;
266 // ---------------------------------------------------------------------------
267 // CAudioCodec::Pause
268 // ---------------------------------------------------------------------------
269 EXPORT_C TInt CAudioCodec::Pause()
271 DP_CONTEXT(CAudioCodec::Pause *CD1*, CtxDevSound, DPLOCAL);
276 DP0(DLINFO,"Pause hwdevice");
277 err = iHwDevice->Pause();
279 iHwDeviceState = EPaused;
283 // ---------------------------------------------------------------------------
285 // ---------------------------------------------------------------------------
286 EXPORT_C TInt CAudioCodec::Stop()
288 DP_CONTEXT(CAudioCodec::Stop *CD1*, CtxDevSound, DPLOCAL);
291 if (iHwDevice && !(iHwDeviceState == EStopped))
293 DP0(DLINFO,"Stop hwdevice");
295 err = iHwDevice->Stop();
296 iHwDeviceState = EStopped;
298 iLastBufferAck = EFalse;
302 // ---------------------------------------------------------------------------
303 // CAudioCodec::GetSupportedSampleRates
304 // ---------------------------------------------------------------------------
305 TInt CAudioCodec::GetSupportedSampleRates(RArray<TInt>& aSupportedRates)
307 DP_CONTEXT(CAudioCodec::GetSupportedSampleRates *CD1*, CtxDevSound, DPLOCAL);
310 aSupportedRates.Reset();
311 // Ask for rates from resource files
312 err = ReadResourceRates(aSupportedRates);
317 // ---------------------------------------------------------------------------
318 // CAudioCodec::GetSupportedModes
319 // ---------------------------------------------------------------------------
320 TInt CAudioCodec::GetSupportedModes(RArray<TUid>& aSupportedModes)
322 DP_CONTEXT(CAudioCodec::GetSupportedModes *CD1*, CtxDevSound, DPLOCAL);
325 aSupportedModes.Reset();
326 // Ask for modes from resource files
327 err = ReadResourceModes(aSupportedModes);
332 // ---------------------------------------------------------------------------
333 // CAudioCodec::GetCustomInterface
334 // ---------------------------------------------------------------------------
335 TInt CAudioCodec::RequestCustomInterface(TUid aUid, TAny*& aPtr)
337 DP_CONTEXT(CAudioCodec::GetCustomInterface *CD1*, CtxDevSound, DPLOCAL);
342 aPtr = iHwDevice->CustomInterface(aUid);
351 // ---------------------------------------------------------------------------
352 // CAudioCodec::RegisterObserver
353 // ---------------------------------------------------------------------------
354 TInt CAudioCodec::RegisterObserver(MCustomInterfaceSupportObserver& aObserver)
356 DP_CONTEXT(CAudioCodec::RegisterObserver *CD1*, CtxDevSound, DPLOCAL);
359 err = iCISupportObservers.Find(&aObserver);
360 if( err != KErrNotFound )
362 err = KErrAlreadyExists;
366 err = iCISupportObservers.Append(&aObserver);
371 // ---------------------------------------------------------------------------
372 // CAudioCodec::UnRegisterObserver
373 // ---------------------------------------------------------------------------
374 void CAudioCodec::UnRegisterObserver(MCustomInterfaceSupportObserver& aObserver)
376 DP_CONTEXT(CAudioCodec::UnRegisterObserver *CD1*, CtxDevSound, DPLOCAL);
378 TInt idxOrErr = iCISupportObservers.Find(&aObserver);
379 if( idxOrErr != KErrNotFound )
381 iCISupportObservers.Remove(idxOrErr);
386 // ---------------------------------------------------------------------------
387 // CAudioCodec::LoadHwDevice
388 // ---------------------------------------------------------------------------
389 TInt CAudioCodec::LoadHwDevice()
391 DP_CONTEXT(CAudioCodec::LoadHwDevice *CD1*, CtxDevSound, DPLOCAL);
395 if(iDeviceUid==KNullUid)
397 DP0_RET(KErrNotSupported, "%d");
400 TRAP(err, iHwDevice = CMMFHwDevice::NewL(iDeviceUid));
401 if(err == KErrNotFound)
403 err = KErrNotSupported;
408 // ---------------------------------------------------------------------------
409 // CAudioCodec::InitHwDevice
410 // ---------------------------------------------------------------------------
411 TInt CAudioCodec::InitHwDevice()
413 DP_CONTEXT(CAudioCodec::InitHwDevice *CD1*, CtxDevSound, DPLOCAL);
416 DP1(DLINFO, "eapStreamId %d", iHwDeviceInitArgs.iEapStreamId);
417 DP1(DLINFO, "policyId %d", iHwDeviceInitArgs.iPolicyId);
419 iHwDeviceInitParams.iHwDeviceObserver = this;
420 iHwDeviceInitParams.iHwDeviceInitArgsPtr.Set((TUint8*)&(iHwDeviceInitArgs),
421 sizeof(THwDeviceInitArgs),
422 sizeof(THwDeviceInitArgs));
425 err = iHwDevice->Init(iHwDeviceInitParams);
429 err = KErrHardwareNotAvailable;
434 // ---------------------------------------------------------------------------
435 // CAudioCodec::SetHwDeviceConfig
436 // ---------------------------------------------------------------------------
437 TInt CAudioCodec::SetHwDeviceConfig()
439 DP_CONTEXT(CAudioCodec::SetHwDeviceConfig *CD1*, CtxDevSound, DPLOCAL);
443 //TODO Look for another way to set those parameters
444 TTaskConfig taskconfig;
445 taskconfig.iUid = KUidRefDevSoundTaskConfig;
446 taskconfig.iStereoMode = ResolveMode(iModeConfig);
447 taskconfig.iRate = iSampleRateConfig;
449 DP1(DLINFO, "taskconfig.iRate %d", taskconfig.iRate);
450 DP1(DLINFO, "taskconfig.iStereoMode %d", taskconfig.iStereoMode);
451 DP1(DLINFO, "taskconfig.iUid %d", taskconfig.iUid);
453 if (err == KErrNone && iHwDevice)
455 err = iHwDevice->SetConfig(taskconfig);
459 err = KErrHardwareNotAvailable;
464 // ---------------------------------------------------------------------------
465 // CAudioCodec::ReadResourceRates
466 // ---------------------------------------------------------------------------
467 TInt CAudioCodec::ReadResourceRates(RArray<TInt>& aRates)
469 DP_CONTEXT(CAudioCodec::ReadResourceRates*CD1*, CtxDevSound, DPLOCAL);
473 CResourceData* resource = NULL;
474 TRAP(err, resource = CResourceData::NewL(iDeviceUid));
475 if (err == KErrNone && resource)
477 err = resource->GetSSampleRates(iMode,aRates);
484 // ---------------------------------------------------------------------------
485 // CAudioCodec::ReadResourceModes
486 // ---------------------------------------------------------------------------
487 TInt CAudioCodec::ReadResourceModes(RArray<TUid>& aModes)
489 DP_CONTEXT(CAudioCodec::ReadResourceModes*CD1*, CtxDevSound, DPLOCAL);
493 CResourceData* resource = NULL;
494 TRAP(err, resource = CResourceData::NewL(iDeviceUid));
495 if (err == KErrNone && resource)
497 err = resource->GetSModes(iMode,aModes);
504 // ---------------------------------------------------------------------------
505 // from class MAudioComponent
506 // CAudioCodec::GetOutputPort
507 // ---------------------------------------------------------------------------
508 TInt CAudioCodec::GetOutputPort(MOutputPort*& aOutputPort)
510 DP_CONTEXT(CAudioCodec::GetOutputPort *CD1*, CtxDevSound, DPLOCAL);
513 DP0_RET(KErrNone, "%d");
516 // ---------------------------------------------------------------------------
517 // from class MAudioComponent
518 // CAudioCodec::GetInputPort
519 // ---------------------------------------------------------------------------
520 TInt CAudioCodec::GetInputPort(MInputPort*& aInputPort)
522 DP_CONTEXT(CAudioCodec::GetInputPort *CD1*, CtxDevSound, DPLOCAL);
525 DP0_RET(KErrNone, "%d");
528 // ---------------------------------------------------------------------------
529 // from class MAudioComponent
530 // CAudioCodec::RegisterAudioComponentObserver
531 // ---------------------------------------------------------------------------
532 EXPORT_C TInt CAudioCodec::RegisterAudioCodecObserver(MAudioCodecAdaptationObserver& aObserver)
534 DP_CONTEXT(CAudioCodec::RegisterAudioCodecObserver *CD1*, CtxDevSound, DPLOCAL);
536 TInt err = iAudioCodecObservers.Find(&aObserver);
537 if(err == KErrNotFound)
539 iAudioCodecObservers.Append(&aObserver);
544 err = KErrAlreadyExists;
549 // ---------------------------------------------------------------------------
550 // from class MAudioComponent
551 // CAudioCodec::UnregisterAudioComponentObserver
552 // ---------------------------------------------------------------------------
553 EXPORT_C void CAudioCodec::UnregisterAudioCodecObserver(MAudioCodecAdaptationObserver& aObserver)
555 DP_CONTEXT(CAudioCodec::UnregisterAudioCodecObserver *CD1*, CtxDevSound, DPLOCAL);
557 TInt idxOrErr = iAudioCodecObservers.Find(&aObserver);
558 if( idxOrErr != KErrNotFound )
560 iAudioCodecObservers.Remove(idxOrErr);
565 // ---------------------------------------------------------------------------
566 // from class MInputPort
567 // CAudioCodec::EmptyBuffer
568 // ---------------------------------------------------------------------------
569 TInt CAudioCodec::EmptyBuffer(CMMFBuffer* /*aBuffer*/, MOutputPort* /*aSupplier*/)
571 DP_CONTEXT(CAudioCodec::EmptyBuffer *CD1*, CtxDevSound, DPLOCAL);
573 DP0_RET(KErrNotReady, "%d");
576 // ---------------------------------------------------------------------------
577 // from class MInputPort
578 // CAudioCodec::BufferFilled
579 // ---------------------------------------------------------------------------
580 TInt CAudioCodec::BufferFilled(CMMFBuffer* aBuffer)
582 DP_CONTEXT(CAudioCodec::BufferFilled *CD1*, CtxDevSound, DPLOCAL);
584 PRF(PRF_ID, PRF_STOP, PRF_LOAD, AA_DS_Fill, "");
586 if(aBuffer->LastBuffer())
592 err = iHwDevice->ThisHwBufferFilled(*aBuffer);
601 // ---------------------------------------------------------------------------
602 // from class MInputPort
603 // CAudioCodec::SetOutput
604 // ---------------------------------------------------------------------------
605 TInt CAudioCodec::SetOutput(MOutputPort* aOutput)
607 DP_CONTEXT(CAudioCodec::SetOutput *CD1*, CtxDevSound, DPLOCAL);
611 iOutputPort = aOutput;
616 // ---------------------------------------------------------------------------
617 // from class MInputPort
618 // CAudioCodec::RemoveOutput
619 // ---------------------------------------------------------------------------
620 TInt CAudioCodec::RemoveOutput(MOutputPort* /*aOutput*/)
622 DP_CONTEXT(CAudioCodec::RemoveOutput *CD1*, CtxDevSound, DPLOCAL);
624 DP0_RET(KErrNone, "%d");
627 // ---------------------------------------------------------------------------
628 // from class MOutputPort
629 // CAudioCodec::FillBuffer
630 // ---------------------------------------------------------------------------
631 TInt CAudioCodec::FillBuffer(CMMFBuffer* /*aBuffer*/, MInputPort* /*aConsumer*/)
633 DP_CONTEXT(CAudioCodec::FillBuffer *CD1*, CtxDevSound, DPLOCAL);
635 DP0_RET(KErrNotReady, "%d");
638 // ---------------------------------------------------------------------------
639 // from class MOutputPort
640 // CAudioCodec::BufferEmptied
641 // ---------------------------------------------------------------------------
642 TInt CAudioCodec::BufferEmptied(CMMFBuffer* aBuffer)
644 DP_CONTEXT(CAudioCodec::BufferEmptied *CD1*, CtxDevSound, DPLOCAL);
654 if (iLastBufferAck) //if the hwdevice return a buffer with the lastbuffer flag set, rather than returning a non-empty buffer
655 { //in this case we generate an empty buffer on behalf of the adaptation
656 TInt count = iAudioCodecObservers.Count();
657 for ( TInt i(0); i < count; i++ ) // causes a ProcessingFinished() to be called on the stream
659 iAudioCodecObservers[i]->AllBuffersProcessed();
661 iLastBufferAck = EFalse;
665 if(aBuffer->LastBuffer())
671 err = iHwDevice->ThisHwBufferEmptied(*aBuffer);
681 // ---------------------------------------------------------------------------
682 // from class MOutputPort
683 // CAudioCodec::SetInput
684 // ---------------------------------------------------------------------------
685 TInt CAudioCodec::SetInput(MInputPort* aInput)
687 DP_CONTEXT(CAudioCodec::SetInput *CD1*, CtxDevSound, DPLOCAL);
696 // ---------------------------------------------------------------------------
697 // from class MOutputPort
698 // CAudioCodec::RemoveInput
699 // ---------------------------------------------------------------------------
700 TInt CAudioCodec::RemoveInput(MInputPort* /*aInput*/)
705 // ---------------------------------------------------------------------------
706 // from class MOutputPort
707 // CAudioCodec::FlushBuffer
708 // ---------------------------------------------------------------------------
709 TInt CAudioCodec::FlushBuffer(MFlushHandlerObserver* aFlushObserver)
714 // Flush low layer buffers
717 ptr = iHwDevice->CustomInterface(TUid::Uid(KMmfUidEmptyBuffersCustomInterface));
718 MMMFDevSoundEmptyBuffers* emptybuffers = static_cast<MMMFDevSoundEmptyBuffers*>(ptr);
721 // Due to defect DEF127468, this do nothing
722 err = emptybuffers->EmptyBuffers();
726 err = KErrNotSupported;
734 // Flush source through an asynchronous request
737 err = iOutputPort->FlushBuffer(aFlushObserver);
743 // ---------------------------------------------------------------------------
744 // from class MMMFHwDeviceObserver
745 // CAudioCodec::FillThisHwBuffer
746 // ---------------------------------------------------------------------------
747 TInt CAudioCodec::FillThisHwBuffer(CMMFBuffer& aHwBuffer)
749 DP_CONTEXT(CAudioCodec::FillThisHwBuffer *CD1*, CtxDevSound, DPLOCAL);
751 PRF(PRF_ID, PRF_START, PRF_LOAD, AA_DS_Fill, "");
754 iAdaptationBuffer = static_cast<CMMFDataBuffer*> (&aHwBuffer);
756 ASSERT(iAdaptationBuffer);
759 iAdaptationBuffer->Data().SetLength(0);
760 BufferFilled(iAdaptationBuffer);
764 TRAP(err,iAdaptationBuffer->SetRequestSizeL(iAdaptationBuffer->Data().MaxLength() ));
769 err = iOutputPort->FillBuffer(&aHwBuffer, this);
780 // ---------------------------------------------------------------------------
781 // from class MMMFHwDeviceObserver
782 // CAudioCodec::EmptyThisHwBuffer
783 // ---------------------------------------------------------------------------
784 TInt CAudioCodec::EmptyThisHwBuffer(CMMFBuffer& aHwBuffer)
786 DP_CONTEXT(CAudioCodec::EmptyThisHwBuffer *CD1*, CtxDevSound, DPLOCAL);
790 iAdaptationBuffer = static_cast<CMMFDataBuffer*> (&aHwBuffer);
791 ASSERT(iAdaptationBuffer);
792 if(iHwDeviceState == EPaused)
794 if (iAdaptationBuffer->Data().Length() == 0) // empty buffer
796 TInt count = iAudioCodecObservers.Count();
797 for ( TInt i(0); i < count; i++ ) // causes a ProcessingFinished() to be called on the stream
799 iAudioCodecObservers[i]->AllBuffersProcessed();
804 if(aHwBuffer.LastBuffer())
806 aHwBuffer.SetLastBuffer(EFalse); // a buffer coming from hardware device should never have last buffer set...
807 iLastBufferAck = ETrue;
810 TRAP(err,iAdaptationBuffer->SetRequestSizeL(iAdaptationBuffer->Data().Length()));
815 err = iInputPort->EmptyBuffer(&aHwBuffer, this);
826 TRAP(err,iAdaptationBuffer->SetRequestSizeL(iAdaptationBuffer->Data().Length()));
831 err = iInputPort->EmptyBuffer(&aHwBuffer, this);
842 // ---------------------------------------------------------------------------
843 // from class MMMFHwDeviceObserver
844 // CAudioCodec::MsgFromHwDevice
845 // ---------------------------------------------------------------------------
846 TInt CAudioCodec::MsgFromHwDevice(TUid aMessageType, const TDesC8& aMsg)
848 DP_CONTEXT(CAudioCodec::MsgFromHwDevice *CD1*, CtxDevSound, DPLOCAL);
850 TBuf<50> formattedNumber;
851 formattedNumber.Format(_L("MessageType 0x%08x"), aMessageType.iUid);
854 buf.Append(formattedNumber);
855 if(aMessageType.iUid == KMmfHwDeviceObserverUpdateBytesPlayed)
857 //This is used by sw codec wrapper to request a bytes played update
858 //Bytes played won't be updated in Stopped() or Error() on sw codec wrapper
859 //As the sound device is closed. Non sw codec wrapper Hw device plugins
860 //Can get the bytes updated on Stopped() and/or Error()
863 DP1(DLINFO, "DeviceMessage is %S",&buf);
864 DP0_RET(KErrNone, "%d");
867 // ---------------------------------------------------------------------------
868 // from class MMMFHwDeviceObserver
869 // CAudioCodec::Stopped
870 // ---------------------------------------------------------------------------
871 void CAudioCodec::Stopped()
873 DP_CONTEXT(CAudioCodec::Stopped *CD1*, CtxDevSound, DPLOCAL);
875 //For sw codec wrappers hw devices bytes played are updated in MsgFromHwDevice
876 //But non sw codec wrappers hw devices may do it differently
877 //Also don't know if non sw codec wrappers hw devices will call Stopped or Error first
882 // ---------------------------------------------------------------------------
883 // from class MMMFHwDeviceObserver
884 // CAudioCodec::Error
885 // ---------------------------------------------------------------------------
887 void CAudioCodec::Error(TInt aError)
889 DP_CONTEXT(CAudioCodec::Error *CD1*, CtxDevSound, DPLOCAL);
892 TTimeIntervalMicroSeconds currentPosition;
896 RDebug::Print(_L("iDeviceUid=0x%x aError=%d iLastBuffer=%d"), iDeviceUid.iUid, aError, iLastBuffer);
898 // The most problable receiver is the logicalaudiocodec which should notify to the client through MAudioProcessingUnit
899 TUint count = iAudioCodecObservers.Count();
901 // Notify only for the
902 if (aError == KErrUnderflow && iMode == EDecode )
904 // Notify the observers
907 for ( TUint i(0); i < count; i++ )
909 iAudioCodecObservers[i]->AllBuffersProcessed();
916 //For sw codec wrappers hw devices bytes played are updated in MsgFromHwDevice
917 //But non sw codec wrappers hw devices may do it differently
918 //Also don't know if non sw codec wrappers hw devices will call Stopped or Error first
921 err = GetControlPosition(currentPosition);
928 RDebug::Print(_L("Restart decoding"));
934 else if (aError == KErrOverflow && iMode == EEncode )
936 if (!iLastBuffer && iHwDeviceState == ERunning)
939 err = GetControlPosition(currentPosition);
948 if (iDeviceUid.iUid != KUidToneHwDevice)
951 RDebug::Print(_L("Is this is not needed for other encoders but toneHwDevice"));
953 for ( TUint i(0); i < count; i++ )
955 iAudioCodecObservers[i]->AllBuffersProcessed();
962 for ( TUint i(0); i < count; i++ )
964 iAudioCodecObservers[i]->ProcessingUnitError(aError);
971 // ---------------------------------------------------------------------------
972 // from class MGainHelper
973 // CAudioCodec::GetGain
974 // ---------------------------------------------------------------------------
975 TInt CAudioCodec::GetGain(TInt& aGain) const
977 DP_CONTEXT(CAudioCodec::GetGain *CD1*, CtxDevSound, DPLOCAL);
980 if (iMode == EDecode && iPlayCustomInterface)
982 aGain = iPlayCustomInterface->Volume();
984 else if( iMode == EEncode && iRecordCustomInterface)
986 aGain = iRecordCustomInterface->Gain();
991 // ---------------------------------------------------------------------------
992 // from class MGainHelper
993 // CAudioCodec::SetGain
994 // ---------------------------------------------------------------------------
995 TInt CAudioCodec::SetGain(RArray<TAudioChannelGain>& aChannels)
997 DP_CONTEXT(CAudioCodec::SetGain *CD1*, CtxDevSound, DPLOCAL);
1001 // Current adaptation doesn't support multichannel
1003 TUint count = aChannels.Count();
1008 for (TUint i(0); i < count; i++)
1010 totalGain =+ aChannels[i].iGain;
1012 gain = totalGain / count;
1015 if (gain > KDefaultMaxGain)
1017 gain = KDefaultMaxGain;
1024 if (iMode == EDecode && iPlayCustomInterface)
1026 iPlayCustomInterface->SetVolume(gain);
1028 else if( iMode == EEncode && iRecordCustomInterface)
1030 iRecordCustomInterface->SetGain(gain);
1037 TInt CAudioCodec::ConfigureRamp(TUid aRampOperation, const TTimeIntervalMicroSeconds& aRampDuration)
1039 DP_CONTEXT(CAudioCodec::ConfigureRamp *CD1*, CtxDevSound, DPLOCAL);
1041 TInt err = KErrNone;
1043 if (aRampOperation == KUidGainSawTooth)
1045 if (iMode == EDecode && iPlayCustomInterface)
1047 iPlayCustomInterface->SetVolumeRamp(aRampDuration);
1050 else if (iRampOperation == KNullUid)
1052 if (iMode == EDecode && iPlayCustomInterface)
1054 iPlayCustomInterface->SetVolumeRamp(0);
1059 err = KErrA3fUnsupportedRamp;
1065 // ---------------------------------------------------------------------------
1066 // from class MPositionControl
1067 // CAudioCodec::GetControlPosition
1068 // ---------------------------------------------------------------------------
1069 TInt CAudioCodec::GetControlPosition(TTimeIntervalMicroSeconds& aPosition)
1071 DP_CONTEXT(CAudioCodec::GetControlPosition *CD1*, CtxDevSound, DPLOCAL);
1073 TInt err = KErrNone;
1074 TInt sampleRateValue = iSampleRateConfig;
1076 // At this adaptation EMMFSoundEncoding16BitPCM encoding is assumed
1077 // Due RMdaDevSound which is always pcm16 each sample is 2 bytes
1078 TInt bytesPerAudioSample = 2;
1080 // Here is secure to convert to TInt a TAudioMode since the values
1081 // are chossen according to the value they represent.
1082 TInt numberOfChannels = ResolveMode(iModeConfig);
1085 if (err == KErrNone)
1087 if( iMode == EDecode && iPlayCustomInterface)
1089 TInt64 bytesPlayed = iPlayCustomInterface->BytesPlayed();
1092 iPlayedBytesCount = bytesPlayed;
1095 samples = iPlayedBytesCount;
1097 if(numberOfChannels > 1)
1099 samples /= numberOfChannels;
1102 if(bytesPerAudioSample > 1)
1104 samples /= bytesPerAudioSample;
1107 else if( iMode == EEncode && iRecordCustomInterface)
1109 samples = iRecordCustomInterface->BytesRecorded();
1110 if(numberOfChannels > 1)
1112 samples /= numberOfChannels;
1114 if(bytesPerAudioSample > 1)
1116 samples /= bytesPerAudioSample;
1123 iPosition = (TInt64(samples) * KMicroSecsInOneSec / sampleRateValue);
1125 aPosition = iPosition;
1126 DP1(DLINFO,"GetControlPosition Samples = %d", samples);
1128 RDebug::Print(_L("GetControlPosition Position=%d"), iPosition);
1133 // ---------------------------------------------------------------------------
1134 // CAudioCodec::ResetControlPosition
1135 // ---------------------------------------------------------------------------
1136 void CAudioCodec::ResetControlPosition()
1138 DP_CONTEXT(CAudioCodec::ResetControlPosition *CD1*, CtxDevSound, DPLOCAL);
1141 iPlayedBytesCount = 0;
1145 // ---------------------------------------------------------------------------
1146 // CAudioCodec::FourCCToHwDeviceUid
1147 // ---------------------------------------------------------------------------
1148 void CAudioCodec::FourCCToHwDeviceUidL(TFourCC aFourCC, TMode aMode, TUid &aHWDev)
1150 DP_CONTEXT(CAudioCodec::FourCCToHwDeviceUid *CD1*, CtxDevSound, DPLOCAL);
1153 //check argument precondition for aState
1154 if ((aMode != EDecode) && (aMode != EEncode))
1156 User::Leave(KErrArgument);
1159 // Array to return hw device plugin resource info(place on cleanupstack
1160 // _after_ ListImplementationsL() )
1161 RImplInfoPtrArray plugInArray;
1162 TUid KUidMmfHWPluginInterfaceCodec = {KMmfUidPluginInterfaceHwDevice};
1164 // ListImplementationsL leaves if it cannot find anything so trap the error
1165 TRAPD(err, REComSession::ListImplementationsL(KUidMmfHWPluginInterfaceCodec,
1167 CleanupResetAndDestroyPushL(plugInArray);
1169 TUint numberOfHwDevicePlugins = plugInArray.Count();
1171 // if no errors and have hwdevice plugin resource entries then scan entries
1172 // matching on a datatype of pcm16 as the destination datatype for play and
1173 // the source datatype for record. If a match is found and isn't already in
1174 // the list of supported data types, then add it to the list
1175 if ((err == KErrNone) && (numberOfHwDevicePlugins))
1177 CImplementationInformation* hwDeviceResourceEntry = NULL;
1178 _LIT8(KPCM16FourCCString, " P16");
1179 TBufC8<KFOURCCLENGTH> fourCCStringPCM16(KPCM16FourCCString);
1180 TPtr8 fourCCPtrPCM16 = fourCCStringPCM16.Des();
1182 // check each resource entry for dst 4CC = P16 for play and
1183 // src 4CC = P16 for record
1184 for (TUint hwDeviceEntry = 0;
1185 hwDeviceEntry < numberOfHwDevicePlugins;
1188 hwDeviceResourceEntry = plugInArray[hwDeviceEntry];
1190 if (IsDataTypeMatch(hwDeviceResourceEntry, fourCCPtrPCM16, aMode))
1192 // resource entry data field has dest/src datatype ' P16'
1193 // i.e. pcm16 for play/record
1194 TPtrC8 fourCCPtr(0,0);
1196 if (aMode == EDecode)
1198 // datatype supported 4CC is left 4 chars
1200 hwDeviceResourceEntry->DataType().Left(KFOURCCLENGTH));
1202 else if (aMode == EEncode)
1204 // datatype supported 4CC is right 4 chars
1206 hwDeviceResourceEntry->DataType().Right(KFOURCCLENGTH));
1209 TFourCC fourCCEntry(fourCCPtr);
1212 if (fourCCEntry == aFourCC)
1215 aHWDev = hwDeviceResourceEntry->ImplementationUid();
1221 // Verify there is a HwDeviceUid
1222 if(aHWDev.iUid == 0)
1224 User::Leave(KErrNotSupported);
1229 // if an error occured and not KErrNotFound then must be a 'real' error
1230 // e.g. KErrNoMemory
1231 if ((err != KErrNotFound) && (err != KErrNone))
1237 CleanupStack::PopAndDestroy(&plugInArray);
1241 // ---------------------------------------------------------------------------
1242 // CAudioCodec::IsDataTypeMatch
1243 // ---------------------------------------------------------------------------
1244 TBool CAudioCodec::IsDataTypeMatch(CImplementationInformation* aHwDeviceResourceEntry,
1245 const TDesC8& aHwMatchFourCC, TMode aState)
1247 DP_CONTEXT(CAudioCodec::IsDataTypeMatch *CD1*, CtxDevSound, DPLOCAL);
1249 TBool match = EFalse;
1251 // Check for resource entry lenght since for HwDeviceAdaptor it is just "*"
1252 if (aHwDeviceResourceEntry->DataType().Length()>=KHwDeviceDefaultDataLength)
1254 if (aState == EDecode)
1256 //play need to match with the right four characters
1257 match = (!(aHwMatchFourCC.Match(
1258 aHwDeviceResourceEntry->DataType().Right(KFOURCCLENGTH)) ==
1261 else if (aState == EEncode)
1263 //record need to match with the left four characters
1265 (!(aHwMatchFourCC.Match(
1266 aHwDeviceResourceEntry->DataType().Left(KFOURCCLENGTH)) ==
1273 RDebug::Print(_L("HwDeviceEntry %S"), &aHwDeviceResourceEntry->DataType());
1277 DP0_RET(match, "0x%x");
1280 // ---------------------------------------------------------------------------
1281 // CAudioCodec::ResolveMode
1282 // ---------------------------------------------------------------------------
1283 TInt CAudioCodec::ResolveMode(TUid aMode)
1285 DP_CONTEXT(CAudioCodec::ResolveMode *CD1*, CtxDevSound, DPLOCAL);
1289 //Mapping an uid mode to an int channel
1290 for (TUint i=0; i<=KMaxModeIndex; i++)
1292 if(KModeTableLookup[i].iAudioMode == aMode)
1294 result = KModeTableLookup[i].iAudioModeValue;
1298 DP0_RET(result, "%d");
1301 // ---------------------------------------------------------------------------
1302 // CAudioCodec::SupportedRates
1303 // ---------------------------------------------------------------------------
1304 EXPORT_C TInt CAudioCodec::SupportedRates(RArray<TInt>& aSupportedRates)
1306 DP_CONTEXT(CAudioCodec::Service *CD1*, CtxDevSound, DPLOCAL);
1308 iRequest |= KRequestSampleRate;
1310 //Get request capabilities
1311 iErrorRates = GetSupportedSampleRates(aSupportedRates);
1313 // Simulate an asyncronous response
1316 TRequestStatus* status = &iStatus;
1317 User::RequestComplete(status, KErrNone);
1320 DP0_RET(iErrorRates, "%d");
1323 // ---------------------------------------------------------------------------
1324 // CAudioCodec::SupportedModes
1325 // ---------------------------------------------------------------------------
1326 EXPORT_C TInt CAudioCodec::SupportedModes(RArray<TUid>& aSupportedModes)
1328 DP_CONTEXT(CAudioCodec::Service *CD1*, CtxDevSound, DPLOCAL);
1330 iRequest |= KRequestMode;
1332 iErrorModes = GetSupportedModes(aSupportedModes);
1334 // Simulate an asyncronous response
1337 TRequestStatus* status = &iStatus;
1338 User::RequestComplete(status, KErrNone);
1341 DP0_RET(iErrorModes, "%d");
1346 // ---------------------------------------------------------------------------
1347 // CAudioCodec::RunL
1348 // ---------------------------------------------------------------------------
1349 void CAudioCodec::RunL()
1351 DP_CONTEXT(CAudioCodec::RunL *CD1*, CtxDevSound, DPLOCAL);
1354 // Send the callback for the request operation
1355 if (iRequest & KRequestMode)
1357 TUint count = iAudioCodecObservers.Count();
1358 for ( TUint i(0); i < count; i++ )
1360 iAudioCodecObservers[i]->GetSupportedAModesComplete(iErrorModes);
1363 // Reset the request flag
1364 iRequest &= ~KRequestMode;
1367 // Send the callback for the request operation
1368 if (iRequest & KRequestSampleRate)
1370 TUint count = iAudioCodecObservers.Count();
1371 for ( TUint i(0); i < count; i++ )
1373 iAudioCodecObservers[i]->GetSupportedARatesComplete(iErrorRates);
1376 // Reset the request flag
1377 iRequest &= ~KRequestSampleRate;
1383 // ---------------------------------------------------------------------------
1384 // CAudioCodec::RunError
1385 // ---------------------------------------------------------------------------
1386 TInt CAudioCodec::RunError(TInt aError)
1388 DP_CONTEXT(CAudioCodec::RunError *CD1*, CtxDevSound, DPLOCAL);
1390 DP0_RET(aError, "%d");
1393 // ---------------------------------------------------------------------------
1394 // CAudioCodec::DoCancel
1395 // ---------------------------------------------------------------------------
1396 void CAudioCodec::DoCancel()
1398 DP_CONTEXT(CAudioCodec::DoCancel *CD1*, CtxDevSound, DPLOCAL);