sl@0: //audiostream.cpp sl@0: sl@0: // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: sl@0: sl@0: sl@0: #include <a3f/a3fbase.h> sl@0: #include <a3f/audioprocessingunittypeuids.h> sl@0: #include <a3f/a3ffourcclookup.h> sl@0: sl@0: #include "audiostream.h" sl@0: sl@0: // PHYSICAL COMPONENTS sl@0: #include "audiocodec.h" sl@0: #include "audiostream.h" sl@0: #include "buffersource.h" sl@0: #include "buffersink.h" sl@0: #include "audiodevicesource.h" sl@0: #include "audiodevicesink.h" sl@0: #include "audiogaincontrol.h" sl@0: #include "maudiostreamadaptationobserver.h" sl@0: sl@0: #include <a3f/maudiodatasupplier.h> sl@0: #include <a3f/maudiodataconsumer.h> sl@0: sl@0: #include "minputport.h" sl@0: #include "moutputport.h" sl@0: #include "audiocontext.h" sl@0: sl@0: #include <ecom/implementationproxy.h> sl@0: sl@0: sl@0: sl@0: const TInt KSampleRate8000Hz = 8000; sl@0: sl@0: // Map the interface implementation UIDs to implementation factory functions sl@0: const TImplementationProxy ImplementationTable[] = sl@0: { sl@0: IMPLEMENTATION_PROXY_ENTRY(0x10283461, CAudioStream::NewL), sl@0: }; sl@0: sl@0: sl@0: EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount) sl@0: { sl@0: aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy); sl@0: return ImplementationTable; sl@0: } sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // Constructor sl@0: // --------------------------------------------------------------------------- sl@0: // sl@0: CAudioStream::CAudioStream() sl@0: : iCurrentStreamState(EUninitialized), sl@0: iDesiredStreamState(EUninitialized) sl@0: { sl@0: TRACE_CREATE(); sl@0: DP_CONTEXT(CAudioStream::CAudioStream *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: // Some init config values sl@0: iSampleRateConfig = KSampleRate8000Hz; sl@0: iModeConfig = KA3FModeMono; sl@0: sl@0: DP_OUT(); sl@0: } sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // Factory method sl@0: // --------------------------------------------------------------------------- sl@0: // sl@0: CAudioStream* CAudioStream::NewL() sl@0: { sl@0: DP_STATIC_CONTEXT(CAudioStream::NewL *CD0*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: CAudioStream* self = new(ELeave)CAudioStream(); sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(); sl@0: CleanupStack::Pop(self); sl@0: DP0_RET(self, "0x%x"); sl@0: } sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // Second phase constructor sl@0: // --------------------------------------------------------------------------- sl@0: // sl@0: void CAudioStream::ConstructL() sl@0: { sl@0: DP_CONTEXT(CAudioStream::ConstructL *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: DP_OUT(); sl@0: } sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // Destructor sl@0: // --------------------------------------------------------------------------- sl@0: // sl@0: CAudioStream::~CAudioStream() sl@0: { sl@0: DP_CONTEXT(CAudioStream::~CAudioStream *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: sl@0: iAudioStreamObservers.Close(); sl@0: iAudioCodecObservers.Close(); sl@0: // Just for now sl@0: DeletePhysicalComponents(); sl@0: REComSession::FinalClose(); sl@0: DP_OUT(); sl@0: } sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // CAudioStream::RegisterAudioStreamObserver sl@0: // --------------------------------------------------------------------------- sl@0: // sl@0: TInt CAudioStream::RegisterAudioStreamObserver(MAudioStreamAdaptationObserver& aObserver) sl@0: { sl@0: DP_CONTEXT(CAudioStream::RegisterAudioStreamObserver *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: TInt err = iAudioStreamObservers.Find(&aObserver); sl@0: if(err == KErrNotFound) sl@0: { sl@0: err = iAudioStreamObservers.Append(&aObserver); sl@0: } sl@0: else sl@0: { sl@0: err = KErrAlreadyExists; sl@0: } sl@0: DP0_RET(err, "%d"); sl@0: } sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // CAudioStream::UnregisterAudioStreamObserver sl@0: // --------------------------------------------------------------------------- sl@0: // sl@0: void CAudioStream::UnregisterAudioStreamObserver(MAudioStreamAdaptationObserver& aObserver) sl@0: { sl@0: DP_CONTEXT(CAudioStream::UnregisterAudioStreamObserver *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: TInt idxOrErr = iAudioStreamObservers.Find(&aObserver); sl@0: if( idxOrErr != KErrNotFound ) sl@0: { sl@0: iAudioStreamObservers.Remove(idxOrErr); sl@0: } sl@0: DP_OUT(); sl@0: } sl@0: sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // CAudioStream::SetFourCC sl@0: // --------------------------------------------------------------------------- sl@0: // sl@0: void CAudioStream::SetFourCC(const CFourCCConvertor& aFourCCConvertor) sl@0: { sl@0: DP_CONTEXT(CAudioStream::SetFourCC *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: CFourCCConvertor& ref = const_cast<CFourCCConvertor&>(aFourCCConvertor); sl@0: iFourCCConvertor = static_cast<CFourCCConvertor*>(static_cast<TAny*>(&ref)); sl@0: DP_OUT(); sl@0: } sl@0: sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // CAudioStream::UnregisterAudioStreamObserver sl@0: // --------------------------------------------------------------------------- sl@0: // sl@0: void CAudioStream::UnregisterAllAudioStreamObserver() sl@0: { sl@0: DP_CONTEXT(CAudioStream::UnregisterAudioStreamObserver *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: sl@0: iAudioStreamObservers.Reset(); sl@0: sl@0: DP_OUT(); sl@0: } sl@0: sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // MMRC extension mechanism sl@0: // --------------------------------------------------------------------------- sl@0: TAny* CAudioStream::GetComponent(TUid aType) sl@0: { sl@0: TAny* ptr = NULL; sl@0: MLogicalChain* clientDesiredChain = NULL; sl@0: CAudioContext* context = static_cast<CAudioContext*>(iAudioContext); sl@0: if(context) sl@0: { sl@0: clientDesiredChain = context->GetLogicalChain(0); sl@0: } sl@0: if (clientDesiredChain) sl@0: { sl@0: ptr = clientDesiredChain->GetComponent(aType); sl@0: } sl@0: return ptr; sl@0: } sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // CAudioStream::Message sl@0: // --------------------------------------------------------------------------- sl@0: TInt CAudioStream::Message(MLogicalChain& aCurrentChain, MLogicalChain& aDesiredChain, MAudioContext& aContext, TInt aFlags) sl@0: { sl@0: DP_CONTEXT(CAudioStream::Message *CD0*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: TInt err = KErrNone; sl@0: sl@0: iCurrentChain = &aCurrentChain; sl@0: iDesiredChain = &aDesiredChain; sl@0: sl@0: TUint messageType = aDesiredChain.MessageType(); sl@0: sl@0: iAudioContext = &aContext; sl@0: sl@0: CAudioContext* audioContext = static_cast<CAudioContext*> (iAudioContext); sl@0: // TO NOTIFY DIRECTLY CONTEXT sl@0: MMultimediaResourceControlObserver* mmrcObserver = static_cast<MMultimediaResourceControlObserver*>(audioContext); sl@0: sl@0: // Register stream observer sl@0: if (messageType & ERegisterStreamObserver != 0) sl@0: { sl@0: // Use MMRC extension mechanism sl@0: TAny* ptr = GetComponent(KUidAudioStreamAdaptationObserver); sl@0: MAudioStreamAdaptationObserver* observer = static_cast<MAudioStreamAdaptationObserver*>(ptr); sl@0: if(observer) sl@0: { sl@0: err = RegisterAudioStreamObserver(*observer); sl@0: } sl@0: } sl@0: sl@0: // Register codec observer sl@0: if (messageType & ERegisterCodecObserver != 0) sl@0: { sl@0: // Use MMRC extension mechanism sl@0: TAny* ptr = GetComponent(KUidAudioCodecObserver); sl@0: MAudioCodecObserver* observer = static_cast<MAudioCodecObserver*>(ptr); sl@0: if (observer) sl@0: { sl@0: err = RegisterAudioCodecObserver(*observer); sl@0: } sl@0: } sl@0: sl@0: // Component creation sl@0: TUint bit = messageType & EComponentCreation; sl@0: if( (err == KErrNone) && (bit != 0) ) sl@0: { sl@0: CAudioContext* context = static_cast<CAudioContext*>(iAudioContext); sl@0: MLogicalChain* clientDesiredChain = context->GetLogicalChain(0); sl@0: err = CreatePhysicalComponents(*clientDesiredChain); sl@0: sl@0: // For Configuration sl@0: if (err==KErrNone) sl@0: { sl@0: clientDesiredChain->SetAdaptationStream(*this); sl@0: clientDesiredChain->SetStreamBufferControl(*this); sl@0: } sl@0: } sl@0: sl@0: // Component alteration sl@0: // Changes that must be applied before stream state transition sl@0: TBool configCodec = EFalse; sl@0: bit = messageType & EComponentAlterationCodec; sl@0: if( (err == KErrNone) && (bit != 0) ) sl@0: { sl@0: // Set Format sl@0: if(iCodec) sl@0: { sl@0: TUid desiredCodecFormat = iDesiredChain->CodecFormat(); sl@0: err = iCodec->SetFormat( desiredCodecFormat ); sl@0: } sl@0: sl@0: if(err == KErrNone) sl@0: { sl@0: //if samplerate or mode has changed, update value and trigger callbacks at appropriate point sl@0: if ((iDesiredChain->GetSampleRate() > 0) && (iDesiredChain->GetSampleRate() != iSampleRateConfig)) sl@0: { sl@0: iSampleRateConfig = iDesiredChain->GetSampleRate(); sl@0: configCodec = ETrue; sl@0: } sl@0: if ((iDesiredChain->GetMode() != KNullUid) && (iDesiredChain->GetMode() != iModeConfig)) sl@0: { sl@0: iModeConfig = iDesiredChain->GetMode(); sl@0: configCodec = ETrue; sl@0: } sl@0: } sl@0: } sl@0: sl@0: sl@0: bit = messageType & EComponentAlterationGain; sl@0: if( (err == KErrNone) && (bit != 0) ) sl@0: { sl@0: // Apply volume ramp sl@0: // Note that ramp operation and gain now are applied separately because current tone arquitecture sl@0: // need the volume ramp to be set before start the tonehwdevice sl@0: TTimeIntervalMicroSeconds currentRampTimeValue = 0; sl@0: TUid currentRampTimeOperation(KNullUid); sl@0: TTimeIntervalMicroSeconds desiredRampTimeValue = 0; sl@0: TUid desiredRampTimeOperation(KNullUid); sl@0: iCurrentChain->GetVolumeRampParameters(currentRampTimeOperation, currentRampTimeValue); sl@0: iDesiredChain->GetVolumeRampParameters(desiredRampTimeOperation, desiredRampTimeValue); sl@0: sl@0: if(currentRampTimeOperation != desiredRampTimeOperation || sl@0: currentRampTimeValue.Int64() != desiredRampTimeValue.Int64() ) sl@0: { sl@0: if (iGainControl) sl@0: { sl@0: err = iGainControl->ConfigureRamp(desiredRampTimeOperation, desiredRampTimeValue); sl@0: } sl@0: } sl@0: } sl@0: sl@0: //Configuration request sl@0: // Stream state sl@0: TBool invokeStateEventCallback = EFalse; sl@0: iDesiredStreamState = iDesiredChain->StreamState(); sl@0: if( (err == KErrNone) && (iCurrentStreamState != iDesiredStreamState) ) sl@0: { sl@0: err = ChangeState(iCurrentStreamState, iDesiredStreamState); sl@0: if (err == KErrNone) sl@0: { sl@0: iCurrentStreamState = iDesiredStreamState; sl@0: } sl@0: invokeStateEventCallback = ETrue; sl@0: } sl@0: sl@0: // Component alteration sl@0: // Changes that must be applied after stream state transition sl@0: TBool gainUpdated = EFalse; sl@0: bit = messageType & EComponentAlterationGain; sl@0: if( (err == KErrNone) && (bit != 0) ) sl@0: { sl@0: TAny* ptr = GetComponent(KUidAudioGainControl); sl@0: MAudioGainControl* gaincontrol = static_cast<MAudioGainControl*>(ptr); sl@0: if (iGainControl && gaincontrol) sl@0: { sl@0: RArray<TAudioChannelGain> channels; sl@0: TInt err = gaincontrol->GetGain(channels); sl@0: if (channels.Count() != 0 ) sl@0: { sl@0: err = iGainControl->SetGain(channels); sl@0: gainUpdated = ETrue; sl@0: } sl@0: channels.Close(); sl@0: } sl@0: } sl@0: sl@0: TBool invokeCodecCallbacks = EFalse; sl@0: bit = messageType & EComponentAlterationCodec; sl@0: if ( (err == KErrNone) && (bit != 0) && configCodec && (iCurrentStreamState == EInitialized) ) sl@0: { sl@0: //codec loading actually configures sample rate and mode sl@0: ASSERT(iCodec); sl@0: err = iCodec->Load(iSampleRateConfig, iModeConfig); sl@0: iIsCodecConfig = (err == KErrNone); sl@0: invokeCodecCallbacks = ETrue; sl@0: if ( err != KErrNone ) sl@0: { sl@0: //get back to previous values in case of error sl@0: iSampleRateConfig = iCurrentChain->GetSampleRate(); sl@0: iModeConfig = iCurrentChain->GetMode(); sl@0: } sl@0: } sl@0: sl@0: // Component destruction sl@0: bit = messageType & EComponentDestruction; sl@0: if( (err == KErrNone) && (bit != 0) ) sl@0: { sl@0: DeletePhysicalComponents(); sl@0: } sl@0: sl@0: TUint isStopping = aFlags & KServerStopping; sl@0: TUint preemptionRequest = aFlags & KPreemptionRequest; sl@0: sl@0: // HERE WE CAN GUARANTEE THAT THE REQUEST IS SUCCESFUL sl@0: // Notify context sl@0: // 1ST CALLBACK sl@0: if(!preemptionRequest) sl@0: { sl@0: mmrcObserver->ReceiveResourceUpdate(&aDesiredChain, KErrNone); sl@0: } sl@0: else sl@0: { sl@0: mmrcObserver->ReceivePreemptionUpdate(&aDesiredChain, err); sl@0: } sl@0: sl@0: // Processing unit callbacks sl@0: // Gain control sl@0: // Note that due to error checking before applying any change sl@0: // this callback always returned the error obtained by calling SetGain sl@0: // or KErrNone sl@0: if(gainUpdated) sl@0: { sl@0: if (iGainControl) sl@0: { sl@0: iGainControl->IssueGainChangedCallBack(err); sl@0: } sl@0: } sl@0: sl@0: // Stream sl@0: if(invokeStateEventCallback) sl@0: { sl@0: invokeStateEventCallback = EFalse; sl@0: for ( TUint idx(0); idx < iAudioStreamObservers.Count(); idx++ ) sl@0: { sl@0: if ( !isStopping ) sl@0: { sl@0: iAudioStreamObservers[idx]->StateEvent(err, iCurrentStreamState); sl@0: } sl@0: } sl@0: } sl@0: if( invokeCodecCallbacks && (iCurrentStreamState == EInitialized) ) sl@0: { sl@0: TInt count = iAudioCodecObservers.Count(); sl@0: for ( TInt idx = 0; idx < count; idx++ ) sl@0: { sl@0: //TODO replace this functionality with the new mmrc sl@0: iAudioCodecObservers[idx]->SampleRateSet(err); sl@0: iAudioCodecObservers[idx]->ModeSet(err); sl@0: } sl@0: } sl@0: sl@0: // Now has no effect on context sl@0: // But it's needed to let the MMRC know about the operation being completed sl@0: // and in such way let it to know that sl@0: for ( TUint idx(0); idx < iAudioStreamObservers.Count(); idx++ ) sl@0: { sl@0: if ( !isStopping ) sl@0: { sl@0: iAudioStreamObservers[idx]->PhysicalAdaptationEvent(EOperationComplete, err); sl@0: } sl@0: } sl@0: sl@0: // Don't need to send last callback sync sl@0: // Let MMRC do it sl@0: sl@0: DP0_RET(err, "%d"); sl@0: } sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // CAudioStream::DeletePhysicalComponents sl@0: // --------------------------------------------------------------------------- sl@0: void CAudioStream::DeletePhysicalComponents() sl@0: { sl@0: DP_CONTEXT(CAudioStream::DeletePhysicalComponents *CD0*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: if(iBufferSource) sl@0: { sl@0: delete iBufferSource; sl@0: iBufferSource = NULL; sl@0: } sl@0: if(iBufferSink) sl@0: { sl@0: delete iBufferSink; sl@0: iBufferSink = NULL; sl@0: } sl@0: if(iCodec) sl@0: { sl@0: delete iCodec; sl@0: iCodec = NULL; sl@0: iIsCodecConfig = EFalse; sl@0: } sl@0: if(iGainControl) sl@0: { sl@0: delete iGainControl; sl@0: iGainControl = NULL; sl@0: } sl@0: if(iDeviceSource) sl@0: { sl@0: delete iDeviceSource; sl@0: iDeviceSource = NULL; sl@0: } sl@0: if(iDeviceSink) sl@0: { sl@0: delete iDeviceSink; sl@0: iDeviceSink= NULL; sl@0: } sl@0: DP_OUT(); sl@0: } sl@0: sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // CAudioStream::CreatePhysicalComponents sl@0: // --------------------------------------------------------------------------- sl@0: TInt CAudioStream::CreatePhysicalComponents(MLogicalChain& aDesiredChain) sl@0: { sl@0: DP_CONTEXT(CAudioStream::CreatePhysicalComponents *CD0*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: sl@0: TInt err = KErrNone; sl@0: TInt units = aDesiredChain.AudioProcessingUnitsCount(); sl@0: TInt index=0; sl@0: TUid typeId; sl@0: sl@0: for (index=0; index < units ; index++) sl@0: { sl@0: typeId = aDesiredChain.AudioProcessingUnitUid(index); sl@0: sl@0: // By the moment all components sl@0: if (err == KErrNone) sl@0: { sl@0: if (typeId == KUidAudioDecoder || typeId == KUidAudioEncoder ) sl@0: { sl@0: if(!iCodec) sl@0: { sl@0: TRAP(err, iCodec = CAudioCodec::NewL(typeId, *iFourCCConvertor )); sl@0: iIsCodecConfig = EFalse; sl@0: iCodec->RegisterAudioCodecObserver(*this); sl@0: TAny* ptr = GetComponent(KUidAudioCodecAdaptationObserver); sl@0: MAudioCodecAdaptationObserver* observer = static_cast<MAudioCodecAdaptationObserver*>(ptr); sl@0: if(observer) sl@0: { sl@0: iCodec->RegisterAudioCodecObserver(*observer); sl@0: } sl@0: // For HW custom interface sl@0: aDesiredChain.SetCustomInterfaceProvider(*iCodec); sl@0: } sl@0: if(iGainControl) sl@0: { sl@0: iGainControl->SetHelper(*iCodec); sl@0: } sl@0: // This mechanism is temporary and must be replaced sl@0: // with the Extension mechanism when the MMRC server sl@0: aDesiredChain.SetStreamPositionControl(*iCodec); sl@0: } sl@0: else if (typeId == KUidMmfBufferSource) sl@0: { sl@0: if(!iBufferSource) sl@0: { sl@0: TRAP(err,iBufferSource = CBufferSource::NewL()); sl@0: // This mechanism is temporary and must be replaced sl@0: // with the Extension mechanism when the MMRC server sl@0: aDesiredChain.SetAdaptationSource(*iBufferSource); sl@0: /* sl@0: TAny* ptr = aDesiredChain.GetComponent(KUidMmfBufferSource); sl@0: MMMFAudioDataSupplier* supplier = static_cast<MMMFAudioDataSupplier*>(ptr); sl@0: if(supplier) sl@0: { sl@0: iBufferSource->SetDataSupplier(*supplier); sl@0: } sl@0: */ sl@0: } sl@0: } sl@0: else if (typeId == KUidMmfBufferSink) sl@0: { sl@0: if(!iBufferSink) sl@0: { sl@0: TRAP(err, iBufferSink = CBufferSink::NewL()); sl@0: // This mechanism is temporary and must be replaced sl@0: // with the Extension mechanism when the MMRC server sl@0: aDesiredChain.SetAdaptationSink(*iBufferSink); sl@0: } sl@0: } sl@0: else if (typeId == KUidAudioGainControl) sl@0: { sl@0: if(!iGainControl) sl@0: { sl@0: // This mechanism is temporary and must be replaced sl@0: // with the Extension mechanism when the MMRC server sl@0: TRAP(err, iGainControl = CAudioGainControl::NewL()); sl@0: aDesiredChain.SetAdaptationGainControl(*iGainControl); sl@0: } sl@0: } sl@0: else if (typeId == KUidAudioDeviceSink) sl@0: { sl@0: if(!iDeviceSink) sl@0: { sl@0: TRAP(err, iDeviceSink = CAudioDeviceSink::NewL()); sl@0: } sl@0: } sl@0: else if (typeId == KUidAudioDeviceSource) sl@0: { sl@0: if(!iDeviceSource) sl@0: { sl@0: TRAP(err, iDeviceSource = CAudioDeviceSource::NewL()); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: err = KErrNotSupported; sl@0: } sl@0: } sl@0: sl@0: // Notify the observers sl@0: for ( TUint idx(0); idx < iAudioStreamObservers.Count(); idx++ ) sl@0: { sl@0: iAudioStreamObservers[idx]->AddProcessingUnitComplete(typeId, err); sl@0: } sl@0: } sl@0: DP0_RET(err, "%d"); sl@0: } sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // CAudioStream::CreateDataPath sl@0: // --------------------------------------------------------------------------- sl@0: TInt CAudioStream::CreateDataPath() sl@0: { sl@0: DP_CONTEXT(CAudioStream::CreateDataPath *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: TInt err(KErrNotReady); sl@0: sl@0: if(iBufferSource && iCodec) // && iSink && iGain) sl@0: { sl@0: // TMode == Decode sl@0: if(KErrNone == iBufferSource->GetOutputPort(iOutputport) && KErrNone == iCodec->GetInputPort(iInputport)) sl@0: { sl@0: iOutputport->SetInput(iInputport); sl@0: iInputport->SetOutput(iOutputport); sl@0: err = KErrNone; sl@0: } sl@0: } sl@0: else if(iBufferSink && iCodec) // && iSink && iGain) sl@0: { sl@0: //TMode == Encode sl@0: if(KErrNone == iCodec->GetOutputPort(iOutputport) && KErrNone == iBufferSink->GetInputPort(iInputport)) sl@0: { sl@0: iOutputport->SetInput(iInputport); sl@0: iInputport->SetOutput(iOutputport); sl@0: err = KErrNone; sl@0: } sl@0: } sl@0: DP0_RET(err, "%d"); sl@0: } sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // CAudioStream::DemolishDataPath sl@0: // --------------------------------------------------------------------------- sl@0: // sl@0: TInt CAudioStream::DemolishDataPath() sl@0: { sl@0: DP_CONTEXT(CAudioStream::DemolishDataPath *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: iOutputport->RemoveInput(iInputport); sl@0: iInputport->RemoveOutput(iOutputport); sl@0: DP0_RET(KErrNone, "%d"); sl@0: } sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // CAudioStream::ChangeState sl@0: // --------------------------------------------------------------------------- sl@0: TInt CAudioStream::ChangeState(TAudioState aPreviousState, TAudioState aDesiredState) sl@0: { sl@0: DP_CONTEXT(CAudioStream::ChangeState *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: TInt err(KErrNone); sl@0: iCurrentStreamState = aPreviousState; sl@0: iDesiredStreamState = aDesiredState; sl@0: sl@0: // Ensure that there is no dereference of a NULL pointer sl@0: ASSERT(iDesiredStreamState < EInitialized || iDesiredStreamState > EActive || iCodec); sl@0: sl@0: switch (iDesiredStreamState) sl@0: { sl@0: case EInitialized: sl@0: { sl@0: if (iCurrentStreamState == EUninitialized) //Initialize sl@0: { sl@0: err = CreateDataPath(); sl@0: if(err == KErrNone) sl@0: { sl@0: err = iCodec->Initialize(); sl@0: } sl@0: } sl@0: else if( iCurrentStreamState == EIdle ) //codec unload (actually, unconfig) sl@0: { sl@0: iIsCodecConfig = EFalse; sl@0: err = KErrNone; sl@0: } sl@0: // Preemption sl@0: // This A3F adaptation allows going from Active/Primed directly to initialised sl@0: // otherwise reference MMRC would need to handle those transitions separately sl@0: else if(iCurrentStreamState == EActive || iCurrentStreamState == EPrimed) sl@0: { sl@0: // To Idle sl@0: err = iCodec->Stop(); sl@0: // To Initilised sl@0: iIsCodecConfig = EFalse; sl@0: } sl@0: sl@0: if(err == KErrNone) sl@0: { sl@0: iCurrentStreamState = EInitialized; sl@0: } sl@0: break; sl@0: } sl@0: case EIdle: sl@0: { sl@0: if ( (iCurrentStreamState == EInitialized) && !iIsCodecConfig ) sl@0: { sl@0: //codec loading actually configures sample rate and mode sl@0: err = iCodec->Load(iSampleRateConfig, iModeConfig); sl@0: iIsCodecConfig = (err == KErrNone); sl@0: } sl@0: else if (iCurrentStreamState == EActive) sl@0: { sl@0: err = iCodec->Stop(); sl@0: } sl@0: else if (iCurrentStreamState == EPrimed) sl@0: { sl@0: err = iCodec->Stop(); sl@0: } sl@0: sl@0: if(err == KErrNone) sl@0: { sl@0: iTimeProcessed = 0; sl@0: iCurrentStreamState = EIdle; sl@0: } sl@0: break; sl@0: } sl@0: case EPrimed: sl@0: { sl@0: if (iCurrentStreamState == EIdle) sl@0: { sl@0: DP0(DLINFO,"============== Stream is going from EIdle -> PRIMED"); sl@0: DP0(DLINFO,"Nothing to be done"); sl@0: } sl@0: else if (iCurrentStreamState == EActive) sl@0: { sl@0: DP0(DLINFO,"============== Stream is going from EActive -> PRIMED"); sl@0: err = iCodec->Pause(); sl@0: } sl@0: if(err == KErrNone) sl@0: { sl@0: iCurrentStreamState = EPrimed; sl@0: } sl@0: break; sl@0: } sl@0: case EActive: sl@0: { sl@0: if (iCurrentStreamState == EPrimed) //Activate from Primed sl@0: { sl@0: // Reusing AudioCodec::Start for resuming sl@0: DP0(DLINFO,"============== Stream is going from EPrimed -> ACTIVE"); sl@0: err = iCodec->Start(); sl@0: } sl@0: else if(iCurrentStreamState == EIdle) //Activate from Idle sl@0: { sl@0: DP0(DLINFO,"============== Stream is going from EIdle -> ACTIVATE"); sl@0: err = iCodec->Start(); sl@0: } sl@0: sl@0: if(err == KErrNone) sl@0: { sl@0: iCurrentStreamState = EActive; sl@0: } sl@0: break; sl@0: } sl@0: case EUninitialized: sl@0: { sl@0: err = DemolishDataPath(); sl@0: if(err == KErrNone) sl@0: { sl@0: iCurrentStreamState = EUninitialized; sl@0: } sl@0: break; sl@0: } sl@0: case EDead: sl@0: { sl@0: err = DemolishDataPath(); sl@0: if(err == KErrNone) sl@0: { sl@0: iCurrentStreamState = EDead; sl@0: } sl@0: break; sl@0: } sl@0: default: sl@0: err = KErrNotSupported; sl@0: DP1(DLINFO,"CAudioStream::ChangeState Unknown state! %d", iDesiredStreamState); sl@0: break; sl@0: } sl@0: DP0_RET(err, "%d"); sl@0: } sl@0: sl@0: TInt CAudioStream::FlushBuffers() sl@0: { sl@0: DP_CONTEXT(CAudioStream::FlushBuffers *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: sl@0: TInt err = KErrNone; sl@0: sl@0: MOutputPort* outPort= static_cast<MOutputPort*>(iCodec); sl@0: if(outPort) sl@0: { sl@0: outPort->FlushBuffer(this); sl@0: } sl@0: else sl@0: { sl@0: err = KErrNotReady; sl@0: } sl@0: err = KErrNone; sl@0: DP0_RET(err, "%d"); sl@0: } sl@0: sl@0: sl@0: void CAudioStream::FlushComplete(TInt aError) sl@0: { sl@0: DP_CONTEXT(CAudioStream::FlushComplete *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: TUint count = iAudioStreamObservers.Count(); sl@0: for ( TUint i(0); i < count; i++ ) sl@0: { sl@0: iAudioStreamObservers[i]->FlushComplete(aError); sl@0: } sl@0: DP_OUT(); sl@0: } sl@0: sl@0: void CAudioStream::AllBuffersProcessed() sl@0: { sl@0: DP_CONTEXT(CAudioStream::AllBuffersProcessed *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: TUint count = iAudioStreamObservers.Count(); sl@0: for ( TUint i(0); i < count; i++ ) sl@0: { sl@0: iAudioStreamObservers[i]->ProcessingFinished(); sl@0: } sl@0: DP_OUT(); sl@0: } sl@0: sl@0: void CAudioStream::ProcessingUnitError(TInt /*aError*/) sl@0: { sl@0: DP_CONTEXT(CAudioStream::ProcessingUnitError *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: DP_OUT(); sl@0: } sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // CAudioStream::RegisterAudioCodecObserver sl@0: // --------------------------------------------------------------------------- sl@0: TInt CAudioStream::RegisterAudioCodecObserver(MAudioCodecObserver& aObserver) sl@0: { sl@0: DP_CONTEXT(CAudioStream::RegisterAudioCodecObserver *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: TInt err = iAudioCodecObservers.Find(&aObserver); sl@0: if(err == KErrNotFound) sl@0: { sl@0: err = iAudioCodecObservers.Append(&aObserver); sl@0: } sl@0: else sl@0: { sl@0: err = KErrAlreadyExists; sl@0: } sl@0: DP0_RET(err, "%d"); sl@0: } sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // CAudioStream::UnregisterAudioCodecObserver sl@0: // --------------------------------------------------------------------------- sl@0: void CAudioStream::UnregisterAudioCodecObserver(MAudioCodecObserver& aObserver) sl@0: { sl@0: DP_CONTEXT(CAudioStream::UnregisterAudioCodecObserver *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: TInt idxOrErr = iAudioCodecObservers.Find(&aObserver); sl@0: if( idxOrErr != KErrNotFound ) sl@0: { sl@0: iAudioCodecObservers.Remove(idxOrErr); sl@0: } sl@0: DP_OUT(); sl@0: } sl@0: sl@0: void CAudioStream::GetSupportedAModesComplete(TInt /*aError*/) sl@0: { sl@0: DP_CONTEXT(CAudioStream::GetSupportedAModesComplete *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: DP_OUT(); sl@0: } sl@0: sl@0: void CAudioStream::GetSupportedARatesComplete(TInt /*aError*/) sl@0: { sl@0: DP_CONTEXT(CAudioStream::GetSupportedARatesComplete *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: DP_OUT(); sl@0: } sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // CAudioStream::GetSupportedSampleRates sl@0: // --------------------------------------------------------------------------- sl@0: TInt CAudioStream::GetSupportedSampleRates(RArray<TInt>& aSupportedRates) sl@0: { sl@0: TInt err = (KErrNotReady); sl@0: err = iCodec->SupportedRates(aSupportedRates); sl@0: return err; sl@0: } sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // CAudioStream::GetSupportedModes sl@0: // --------------------------------------------------------------------------- sl@0: TInt CAudioStream::GetSupportedModes(RArray<TUid>& aSupportedModes) sl@0: { sl@0: TInt err = (KErrNotReady); sl@0: err = iCodec->SupportedModes(aSupportedModes); sl@0: return err; sl@0: } sl@0: sl@0: // end of file