sl@0: //audiocontext.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: #include sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: #include "audiocontext.h" sl@0: #include "audioprocessingunit.h" sl@0: #include "logicalaudiostream.h" sl@0: #include "audiostreammanager.h" sl@0: sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // Default constructor sl@0: // --------------------------------------------------------------------------- sl@0: // sl@0: CAudioContext::CAudioContext() sl@0: { sl@0: TRACE_CREATE(); sl@0: DP_CONTEXT(CAudioContext::CAudioContext *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: iInCommit = EFalse; sl@0: DP_OUT(); sl@0: } sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // Symbian 2nd phase constructor sl@0: // --------------------------------------------------------------------------- sl@0: void CAudioContext::ConstructL() sl@0: { sl@0: DP_CONTEXT(CAudioContext::ConstructL *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: sl@0: // Setup Multimedia Resource Control sl@0: User::LeaveIfError(iMMRC.Open(*this)); sl@0: User::LeaveIfError(iCriticalSection.CreateLocal()); sl@0: DP_OUT(); sl@0: } sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // Symbian constructor sl@0: // --------------------------------------------------------------------------- sl@0: EXPORT_C CAudioContext* CAudioContext::NewL() sl@0: { sl@0: DP_STATIC_CONTEXT(CAudioContext::NewL *CD0*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: CAudioContext* self = new(ELeave)CAudioContext(); 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: // Destructor sl@0: // --------------------------------------------------------------------------- sl@0: // sl@0: EXPORT_C CAudioContext::~CAudioContext() sl@0: { sl@0: DP_CONTEXT(CAudioContext::~CAudioContext *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: iMMRC.Close(); sl@0: iAudioContextObservers.Close(); sl@0: iAudioProcessingUnits.Close(); sl@0: if (iActualChain) sl@0: { sl@0: iActualChain->Release(); sl@0: }; sl@0: iCriticalSection.Close(); sl@0: DP_OUT(); sl@0: } sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // From class MAudioContext sl@0: // CAudioContext::SetClientSettings sl@0: // --------------------------------------------------------------------------- sl@0: // sl@0: TInt CAudioContext::SetClientSettings(const TClientContextSettings& aSettings) sl@0: { sl@0: DP_CONTEXT(CAudioContext::SetClientSettings *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: TInt err(KErrNone); sl@0: iClientSettings = aSettings; sl@0: if( iContextId.Id() == 0 ) sl@0: { sl@0: TUint64 id = iMMRC.LogOn(iClientSettings.iProcessId); sl@0: TAudioContextId temp(id); sl@0: iContextId = temp; 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: // --------------------------------------------------------------------------- sl@0: // From class MAudioContext sl@0: // CAudioContext::GetContextId sl@0: // --------------------------------------------------------------------------- sl@0: // sl@0: TAudioContextId CAudioContext::ContextId() const sl@0: { sl@0: DP_CONTEXT(CAudioContext::ContextId *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: DP_OUT(); sl@0: return iContextId; sl@0: } sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // From class MAudioContext sl@0: // CAudioContext::Commit sl@0: // --------------------------------------------------------------------------- sl@0: // sl@0: TInt CAudioContext::Commit() sl@0: { sl@0: DP_CONTEXT(CAudioContext::Commit *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: TInt err(KErrNone); sl@0: iInCommit = ETrue; sl@0: sl@0: if (iClientSettings.iProcessId.Id() == 0) sl@0: { sl@0: DP0_RET(KErrNotReady, "%d"); sl@0: } sl@0: sl@0: err = iMMRC.SendResourceRequest(iActualChain, iDesiredChain, this); sl@0: DP0_RET(err, "%d"); sl@0: } sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // From class MAudioContext sl@0: // CAudioContext::CreateAudioStream sl@0: // --------------------------------------------------------------------------- sl@0: // sl@0: TInt CAudioContext::CreateAudioStream(MAudioStream *&aStream) sl@0: { sl@0: DP_CONTEXT(CAudioContext::CreateAudioStream *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: TInt err(KErrNone); sl@0: sl@0: CAudioStreamManager* manager(NULL); sl@0: sl@0: // Create desired logical chain sl@0: TRAP(err, manager = CAudioStreamManager::NewL(KUidAudioStream)); sl@0: if(err == KErrNone) sl@0: { sl@0: aStream = static_cast(manager); sl@0: sl@0: // Use this as desired chain (this is the one that the client modify) sl@0: CLogicalAudioStream* logicalAudioStream = static_cast(aStream); sl@0: iDesiredChain = static_cast(logicalAudioStream); sl@0: logicalAudioStream->SetParentContext(*this); sl@0: if (iActualChain) sl@0: { sl@0: iActualChain->Release(); sl@0: iActualChain=NULL; sl@0: } sl@0: TRAP(err, iActualChain = iDesiredChain->CloneL()); sl@0: } sl@0: DP0_RET(err, "%d"); sl@0: } sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // From class MAudioContext sl@0: // CAudioContext::DeleteAudioStream sl@0: // --------------------------------------------------------------------------- sl@0: // sl@0: void CAudioContext::DeleteAudioStream(MAudioStream *&aStream) sl@0: { sl@0: DP_CONTEXT(CAudioContext::DeleteAudioStream *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: CAudioStreamManager* manager = static_cast(aStream); sl@0: delete manager; sl@0: DP_OUT(); sl@0: } sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // From class MAudioContext sl@0: // CAudioContext::CreateAudioProcessingUnit sl@0: // --------------------------------------------------------------------------- sl@0: // sl@0: TInt CAudioContext::CreateAudioProcessingUnit(TUid aTypeId, MAudioProcessingUnit *&aProcessingUnit) sl@0: { sl@0: DP_CONTEXT(CAudioContext::CreateAudioProcessingUnit *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: TInt err(KErrNone); sl@0: TAudioComponentId unitInstance = GetAndSetInstanceID(); sl@0: sl@0: CAudioProcessingUnit* pUnit=NULL; sl@0: TComponentParameters cParameters; sl@0: cParameters.iTypeUid = aTypeId; sl@0: cParameters.iInstanceId = unitInstance; sl@0: cParameters.iContextId = iContextId; sl@0: cParameters.iSettingsObserver = this; sl@0: sl@0: TRAP(err, pUnit = CAudioProcessingUnit::NewL(cParameters)); sl@0: if (err==KErrNone) sl@0: { sl@0: aProcessingUnit = static_cast(pUnit); sl@0: err = iAudioProcessingUnits.Append(aProcessingUnit); sl@0: if(err!=KErrNone) sl@0: { sl@0: delete pUnit; sl@0: aProcessingUnit = NULL; sl@0: } sl@0: } sl@0: DP0_RET(err, "%d"); sl@0: } sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // From class MAudioContext sl@0: // CAudioContext::DeleteAudioProcessingUnit sl@0: // --------------------------------------------------------------------------- sl@0: // sl@0: void CAudioContext::DeleteAudioProcessingUnit( sl@0: MAudioProcessingUnit *&aProcessingUnit) sl@0: { sl@0: DP_CONTEXT(CAudioContext::DeleteAudioProcessingUnit *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: DP_OUT(); sl@0: CAudioProcessingUnit* cUnit = static_cast(aProcessingUnit); sl@0: TAudioComponentId param = aProcessingUnit->InstanceId(); sl@0: TUint count= iAudioProcessingUnits.Count(); sl@0: sl@0: for ( TUint i(0); i < count; i++ ) sl@0: { sl@0: // find and delete component sl@0: if( iAudioProcessingUnits[i]->InstanceId() == param) sl@0: { sl@0: iAudioProcessingUnits.Remove(i); sl@0: delete cUnit; sl@0: break; sl@0: } sl@0: } sl@0: } sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // From class MAudioContext sl@0: // CAudioContext::RegisterAudioContextObserver sl@0: // --------------------------------------------------------------------------- sl@0: // sl@0: TInt CAudioContext::RegisterAudioContextObserver( sl@0: MAudioContextObserver& aObserver) sl@0: { sl@0: DP_CONTEXT(CAudioContext::RegisterAudioContextObserver *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: TInt err = iAudioContextObservers.Find(&aObserver); sl@0: if( err != KErrNotFound ) sl@0: { sl@0: err = KErrAlreadyExists; sl@0: } sl@0: else sl@0: { sl@0: err = iAudioContextObservers.Append(&aObserver); sl@0: } sl@0: DP0_RET(err, "%d"); sl@0: } sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // From class MAudioContext sl@0: // CAudioContext::UnregisterAudioContextObserver sl@0: // --------------------------------------------------------------------------- sl@0: // sl@0: void CAudioContext::UnregisterAudioContextObserver( sl@0: MAudioContextObserver& aObserver) sl@0: { sl@0: DP_CONTEXT(CAudioContext::UnregisterAudioContextObserver *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: sl@0: TInt idxOrErr = iAudioContextObservers.Find(&aObserver); sl@0: if( idxOrErr != KErrNotFound ) sl@0: { sl@0: iAudioContextObservers.Remove(idxOrErr); sl@0: } sl@0: DP_OUT(); sl@0: } sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // From class MAudioContext sl@0: // CAudioContext::Interface sl@0: // --------------------------------------------------------------------------- sl@0: // sl@0: TAny* CAudioContext::Interface(TUid aType) sl@0: { sl@0: DP_CONTEXT(CAudioContext::Interface *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: TAny* interface = NULL; sl@0: if(aType == KUIdAudioResourceNotification) sl@0: { sl@0: #ifndef SYMBIAN_DISABLE_ARN sl@0: interface = static_cast(this); sl@0: #else sl@0: interface = NULL; sl@0: #endif sl@0: } sl@0: else sl@0: { sl@0: interface = NULL; sl@0: } sl@0: DP_OUT(); sl@0: return interface; sl@0: } sl@0: sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // From class MAudioContext sl@0: // CAudioContext::Reset sl@0: // --------------------------------------------------------------------------- sl@0: // sl@0: TInt CAudioContext::Reset() sl@0: { sl@0: DP_CONTEXT(CAudioContext::Reset *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: TInt err = KErrNone; sl@0: if (iInCommit) sl@0: { sl@0: err = KErrNotReady; sl@0: } sl@0: iDesiredChain->ResetMessage(); sl@0: iDesiredChain->CopySettings(*iActualChain); sl@0: DP0_RET(err, "%d"); sl@0: } sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // From class MMultimediaResourceControlObserver sl@0: // CAudioContext::ReceiveResourceResponse sl@0: // --------------------------------------------------------------------------- sl@0: // sl@0: void CAudioContext::ReceiveResourceResponse(MLogicalChain* aAppliedChain, TInt aError) sl@0: { sl@0: DP_CONTEXT(CAudioContext::ReceiveResourceResponse *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: sl@0: iCriticalSection.Wait(); sl@0: iMsgVersion++; sl@0: iMMRC.ResetMessages(); sl@0: iCriticalSection.Signal(); sl@0: sl@0: if ( aError == KErrNone || iPreempted ) sl@0: { sl@0: if ( iPreempted ) sl@0: { sl@0: iPreempted = EFalse; sl@0: } sl@0: // Desired chain was commited succesfully sl@0: TInt err; sl@0: MLogicalChain* lc = NULL; sl@0: TRAP(err, lc = aAppliedChain->CloneL()); sl@0: DP1(DLERR,"ECloneLeftWhenReceivingResourceResponse %d", err); sl@0: __ASSERT_DEBUG(err == KErrNone, Panic(ECloneLeftWhenReceivingResourceResponse)); sl@0: if ( iActualChain ) sl@0: { sl@0: iActualChain->Release(); sl@0: } sl@0: iActualChain = lc; sl@0: } sl@0: else sl@0: { sl@0: iDesiredChain->CopySettings(*iActualChain); sl@0: } sl@0: iDesiredChain->ResetMessage(); sl@0: ContextEventSignal(KUidA3FContextUpdateComplete, aError); sl@0: iInCommit = EFalse; sl@0: DP_OUT(); sl@0: } sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // From class MMultimediaResourceControlObserver sl@0: // CAudioContext::ReceiveResourceUpdate sl@0: // --------------------------------------------------------------------------- sl@0: // sl@0: void CAudioContext::ReceiveResourceUpdate(MLogicalChain* /*aMessage*/, TInt aError) sl@0: { sl@0: DP_CONTEXT(CAudioContext::ReceiveResourceUpdate *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: ContextEventSignal(KUidA3FContextCommitUpdate, aError); sl@0: DP_OUT(); sl@0: } sl@0: sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // From class MMultimediaResourceControlObserver sl@0: // CAudioContext::ReceivePreemptionUpdate sl@0: // --------------------------------------------------------------------------- sl@0: // sl@0: void CAudioContext::ReceivePreemptionUpdate(MLogicalChain* /*aMessage*/, TInt aError) sl@0: { sl@0: DP_CONTEXT(CAudioContext::ReceivePreemptionUpdate *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: iPreempted = ETrue; sl@0: if(iInCommit) sl@0: { sl@0: // Send only one callback sl@0: ContextEventSignal(KUidA3FContextPreEmptedCommit, aError); sl@0: } sl@0: else sl@0: { sl@0: // Send two callbacks sl@0: ContextEventSignal(KUidA3FContextPreEmption, aError); sl@0: ContextEventSignal(KUidA3FContextPreEmptionUpdate, aError); sl@0: } sl@0: DP_OUT(); sl@0: } sl@0: sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // From class MLogicalSettingObserver sl@0: // CAudioContext::ReceiveComponentSettingsChange sl@0: // --------------------------------------------------------------------------- sl@0: void CAudioContext::ReceiveComponentSettingsChange(TUid /*aId*/, TMMRCMessageType aMessageType) sl@0: { sl@0: iDesiredChain->SetMessageType(aMessageType); sl@0: } sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // Internals sl@0: // CAudioContext::GetAndSetInstanceID sl@0: // --------------------------------------------------------------------------- sl@0: TAudioComponentId CAudioContext::GetAndSetInstanceID() sl@0: { sl@0: DP_CONTEXT(CAudioContext::GetAndSetInstanceID *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: TUint id(1); // start ID count from 1 sl@0: TAudioComponentId idComponent(1); sl@0: TUint count = iAudioProcessingUnits.Count(); sl@0: if ( count < KMaxTUint ) sl@0: { sl@0: id = ++count; sl@0: } sl@0: idComponent = id; sl@0: DP_OUT(); sl@0: return idComponent; sl@0: } sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // Internals sl@0: // CAudioContext::ContextEventSignal sl@0: // --------------------------------------------------------------------------- sl@0: void CAudioContext::ContextEventSignal(TUid aEvent, TInt aError) sl@0: { sl@0: DP_CONTEXT(CAudioContext::ContextEventSignal *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: TUint count = iAudioContextObservers.Count(); sl@0: for ( TUint idx(0); idx < count; idx++ ) sl@0: { sl@0: iAudioContextObservers[idx]->ContextEvent(aEvent, aError); sl@0: } sl@0: DP_OUT(); sl@0: } sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // CAudioContext::GetLogicalChain sl@0: // --------------------------------------------------------------------------- sl@0: EXPORT_C MLogicalChain* CAudioContext::GetLogicalChain(TInt aIndex) sl@0: { sl@0: DP_CONTEXT(CAudioContext::GetLogicalChain *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: MLogicalChain* logChain = NULL; sl@0: if (aIndex == 0) sl@0: { sl@0: logChain = iDesiredChain; sl@0: } sl@0: else sl@0: { sl@0: logChain = iActualChain; sl@0: } sl@0: DP_OUT(); sl@0: return logChain; sl@0: } sl@0: sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // CAudioContext::RegisterAsClient sl@0: // --------------------------------------------------------------------------- sl@0: TInt CAudioContext::RegisterAsClient(TUid aEventType, const TDesC8& aNotificationRegistrationData, MA3FDevSoundAutoPauseResumeObserver* aObserverPtr) sl@0: { sl@0: DP_CONTEXT(CAudioContext::RegisterAsClient *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: TInt err(KErrNone); sl@0: iObserverPtr = aObserverPtr; sl@0: err = iMMRC.RegisterAsClient(aEventType, aNotificationRegistrationData); sl@0: DP0_RET(err, "%d"); sl@0: } sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // CAudioContext::CancelRegisterAsClient sl@0: // --------------------------------------------------------------------------- sl@0: TInt CAudioContext::CancelRegisterAsClient(TUid aEventType) sl@0: { sl@0: DP_CONTEXT(CAudioContext::CancelRegisterAsClient *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: TInt err(KErrNone); sl@0: err = iMMRC.CancelRegisterAsClient(aEventType); sl@0: DP0_RET(err, "%d"); sl@0: } sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // CAudioContext::WillResumePlay sl@0: // --------------------------------------------------------------------------- sl@0: TInt CAudioContext::WillResumePlay() sl@0: { sl@0: DP_CONTEXT(CAudioContext::WillResumePlay *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: TInt err(KErrNone); sl@0: err = iMMRC.WillResumePlay(); sl@0: DP0_RET(err, "%d"); sl@0: } sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: // From class MMultimediaResourceControlObserver sl@0: // CAudioContext::CanResume sl@0: // --------------------------------------------------------------------------- sl@0: // sl@0: void CAudioContext::CanResume() sl@0: { sl@0: DP_CONTEXT(CAudioContext::CanResume *CD1*, CtxDevSound, DPLOCAL); sl@0: DP_IN(); sl@0: if(iObserverPtr) sl@0: { sl@0: iObserverPtr->NotifyResume(); sl@0: } sl@0: DP_OUT(); sl@0: } sl@0: sl@0: void CAudioContext::Panic(TAudioContextPanicCodes aCode) sl@0: { sl@0: User::Panic(KAudioContextPanicCategory, aCode); sl@0: } sl@0: sl@0: EXPORT_C TInt CAudioContext::MsgVersion() sl@0: { sl@0: return iMsgVersion; sl@0: } sl@0: sl@0: EXPORT_C RCriticalSection& CAudioContext::CriticalSection() sl@0: { sl@0: return iCriticalSection; sl@0: } sl@0: // End of file