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: sl@0: #ifndef CDEVAUDIOCONTROL_H sl@0: #define CDEVAUDIOCONTROL_H sl@0: sl@0: #include sl@0: sl@0: #include "cdevaudio.h" sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: sl@0: class MAudioCodec; sl@0: class MAudioGainControl; sl@0: sl@0: /** sl@0: * Panic category and codes that DevSoundAdaptor raises on the client sl@0: */ sl@0: enum TDevSoundAdaptorPanicCode sl@0: { sl@0: ECommitFailedDuringStop = 1, sl@0: ECommitFailedDuringPause, sl@0: EStreamBeingDemotedToEIdle, sl@0: EAudioCodecIsNull, sl@0: EStreamMismatch, sl@0: EBufferMismatch, sl@0: EInvalidStateDuringPreemptionCycle sl@0: }; sl@0: sl@0: sl@0: /** sl@0: * CDevAudioControl. sl@0: * sl@0: * ?description sl@0: * sl@0: * @lib mmfdevsoundadaptation.lib sl@0: * @since sl@0: */ sl@0: NONSHARABLE_CLASS(CDevAudioControl) : public CBase, sl@0: public MAudioStreamObserver, sl@0: public MAudioGainControlObserver, sl@0: public MAudioContextObserver, sl@0: public MCustomInterfaceSupportObserver, sl@0: public MAudioCodecObserver sl@0: { sl@0: sl@0: public: sl@0: sl@0: enum TStereoCh sl@0: { sl@0: ELeftCh=0, sl@0: ERightCh=1 sl@0: }; sl@0: sl@0: ~CDevAudioControl(); sl@0: sl@0: /** sl@0: * Initialize wanted state control components sl@0: * @since sl@0: * @return error code sl@0: */ sl@0: virtual TInt Initialize(TUid aFormat); sl@0: sl@0: /** sl@0: * Uninitialize wanted state control components sl@0: * @since sl@0: * @return error code sl@0: */ sl@0: virtual TInt Uninitialize(); sl@0: sl@0: /** sl@0: * Remove any processing unit sl@0: * @since sl@0: * @return error code sl@0: */ sl@0: virtual TInt RemoveProcessingUnits(); sl@0: sl@0: /** sl@0: * Returns the supported Audio settings ie. encoding, sample rates, sl@0: * mono/stereo operation, buffer size etc.. sl@0: * @since sl@0: * @param aCaps on return, contains supported capabilities sl@0: * @return error code sl@0: */ sl@0: TInt GetCapabilities(TMMFCapabilities& aCap); sl@0: sl@0: /** sl@0: * Returns the current device configuration. sl@0: * @since sl@0: * @param aConfig on return, contains device settings. sl@0: * @return error code sl@0: */ sl@0: TInt GetConfig(TMMFCapabilities& aConfig); sl@0: sl@0: /** sl@0: * Configure CMMFDevSound object with the settings in aConfig. Use this sl@0: * to set sampling rate, encoding and mono/stereo. sl@0: * Leaves on failure. sl@0: * @since sl@0: * @param const TMMFCapabilities& aConfig The attribute values to which sl@0: * CMMFDevSound object will be configured to. sl@0: * @return error code sl@0: */ sl@0: TInt SetConfig(const TMMFCapabilities& aCaps); sl@0: sl@0: /** sl@0: * Initializes and starts the wanted operation (Play, Record, TonePlay). sl@0: * @since sl@0: * @return error code sl@0: */ sl@0: virtual TInt ProcessInit(); sl@0: sl@0: /** sl@0: * Processes the data (PlayData, RecordData). sl@0: * @since sl@0: * @return void sl@0: */ sl@0: virtual void ProcessData(); sl@0: sl@0: /** sl@0: * Stops the ongoing operation (Play, Record, TonePlay). sl@0: * @since sl@0: * @return void sl@0: */ sl@0: virtual TInt Stop(); sl@0: sl@0: /** sl@0: * Temporarily Stops the ongoing operation (Play, Record, TonePlay). sl@0: * @since sl@0: * @return void sl@0: */ sl@0: virtual TInt Pause(); sl@0: sl@0: /** sl@0: * Returns the samples played/recorded so far sl@0: * @since sl@0: * @return TInt Returns the samples played/recorded. sl@0: */ sl@0: virtual TInt GetSamples(); sl@0: sl@0: /** sl@0: * Retrieves a custom interface to the device. sl@0: * @since sl@0: * @param TUid aInterfaceId The interface UID, defined with the custom sl@0: * interface. sl@0: * @return TAny* A pointer to the interface implementation, or NULL if sl@0: * the device does not implement the interface requested. The sl@0: * return value must be cast to the correct type by the user. sl@0: */ sl@0: virtual TAny* CustomInterface(TUid aInterfaceId); sl@0: sl@0: /** sl@0: * Apply gains, balance. Scale gain to underlying (a3f) max gain. sl@0: * Assumed to be in active state. When called for SetVolume() etc call on higher-level sl@0: * aCommit should be ETrue, and will call Commit() if derived result is KErrNone. sl@0: * @param aDevSoundGain the DevSound gain to be applied sl@0: * @param aDevSoundMaxGain the cached A3F Max Gain to be used as boundary sl@0: * @param aBalance the balance value to be applied sl@0: * @param const TTimeIntervalMicroSeconds &aRampDuration The period over sl@0: * which the volume is to rise. A zero value causes the sl@0: * sample to be played at the normal level for the full duration sl@0: * of the playback. A value, which is longer than the duration of sl@0: * the overall clip means that the sample never reaches its normal sl@0: * volume level. sl@0: * @param aBecomingActive indicates if DevSoundAdaptor is becoming active sl@0: * which is needed to avoid if a commit here could clash with the one that is going to activate the stream sl@0: sl@0: * @return error code sl@0: */ sl@0: TInt SetGains(TInt aDevSoundGain, TInt aDevSoundMaxGain, TInt aBalance[2], const TTimeIntervalMicroSeconds& aRampDuration, TBool aBecomingActive); sl@0: sl@0: /** sl@0: * Maps "legacy" volume/gain values to CAP channel array sl@0: * @since sl@0: */ sl@0: void MapGains(); sl@0: sl@0: /** sl@0: * Destroy logical chain sl@0: * @since sl@0: * @ sl@0: */ sl@0: TBool DestroyChain(); sl@0: sl@0: // From base class MAudioStreamObserver sl@0: sl@0: /** sl@0: * Handles audio stream state change event. sl@0: */ sl@0: virtual void StateEvent(MAudioStream& aStream, TInt aReason, TAudioState aNewState); sl@0: sl@0: /** sl@0: * Notifies that adding of processing unit to the stream has been completed sl@0: * successfully or otherwise. sl@0: */ sl@0: virtual void AddProcessingUnitComplete(MAudioStream& aStream, MAudioProcessingUnit* aInstance, TInt aError); sl@0: sl@0: /** sl@0: * Notifies that removing of processing unit from the stream has been completed sl@0: * successfully or otherwise. sl@0: */ sl@0: virtual void RemoveProcessingUnitComplete(MAudioStream& aStream, MAudioProcessingUnit* aInstance, TInt aError); sl@0: sl@0: /* sl@0: Call-back indicating that is the last buffer has been processed by the sink. sl@0: */ sl@0: virtual void ProcessingFinished (MAudioStream & aStream); sl@0: sl@0: /** sl@0: * Signals completion of a Flush() operation. sl@0: */ sl@0: virtual void FlushComplete (MAudioStream& aStream, TInt aError); sl@0: sl@0: // From base class MAudioGainControlObserver sl@0: sl@0: /** sl@0: * Notifies the observer that the max ramp time supported by the stream, has changed. sl@0: * sl@0: * @since sl@0: * @param aStream a reference to the stream whose max ramp time changed. sl@0: */ sl@0: virtual void MaxRampTimeChanged(MAudioGainControl& aGain); sl@0: sl@0: /** sl@0: * Notifies the observer that the maximum gain value supported by the stream has changed. sl@0: * sl@0: * @since sl@0: * @param aStream a reference to the stream whose supported con sl@0: */ sl@0: virtual void MaxGainChanged(MAudioGainControl& aGain); sl@0: sl@0: /** sl@0: * Notifies the observer that the stream gain has changes, due to request from the client sl@0: * or otherwise. sl@0: * sl@0: * If gain change by the client cannot be fulfilled, a gain change with an error code sl@0: * other than KErrNone will be issued. sl@0: * sl@0: * @since sl@0: * @param aStream a reference to the stream whose gain has changed. sl@0: * @param aStream an error code. KErrNone if the gain change was requested by the client sl@0: * and was completed successfully. sl@0: */ sl@0: virtual void GainChanged(MAudioGainControl& aGain, TInt aError); sl@0: sl@0: /** sl@0: * Saves tonedata for later use sl@0: * This includes information about tone type, data, length, etc. sl@0: * sl@0: * @since sl@0: * @param aToneData sl@0: * @return error code sl@0: */ sl@0: virtual TInt SetToneData(TToneData& aToneData); sl@0: sl@0: // From base class MAudioContextObserver sl@0: /** sl@0: * Callback to context observer to show progression through Commit() and pre-emption cycles sl@0: * sl@0: * @param aEvent a Uid giving the specific event. sl@0: * @param aError an error code. KErrNone if successful, otherwise one of the system wide error codes. sl@0: */ sl@0: virtual void ContextEvent(TUid aEvent, TInt aError); sl@0: sl@0: // from MCustomInterfaceSupportObserver sl@0: virtual void CustomInterfaceRemoval(TUid, TAny* aPtr); sl@0: sl@0: //From MAudioCodecObserver sl@0: sl@0: virtual void SampleRateSet(TInt aError); sl@0: sl@0: virtual void ModeSet(TInt aError); sl@0: sl@0: virtual void GetSupportedSampleRatesComplete (TInt aError); sl@0: sl@0: virtual void GetSupportedModesComplete (TInt aError); sl@0: sl@0: /** sl@0: * Called when a ProcessingFinished callback is received sl@0: * sl@0: * @since sl@0: * @param TBool& aAyncCompletion sl@0: * @return an error code KErrNone if successful sl@0: */ sl@0: virtual TInt ProcessingFinishedReceived(TBool& aAyncCompletion); sl@0: sl@0: virtual TInt ProcessingError(TBool& aAyncCompletion); sl@0: sl@0: /** sl@0: * EmptyBuffers using A3F::Flush sl@0: * sl@0: * @since sl@0: * @return an error code. KErrNone if successful sl@0: * KErrNotReady if not playing or paused sl@0: * KErrNotSupported if the operation is not supported sl@0: */ sl@0: virtual TInt RequestEmptyBuffers(); sl@0: sl@0: /** sl@0: * Gets the current play time from the audio renderer sl@0: * @since sl@0: * @param TTimeIntervalMicroSeconds& aTime On return contains the current play time sl@0: * @return an error code KErrNone if successful sl@0: */ sl@0: virtual TInt GetTimePlayed(TTimeIntervalMicroSeconds& aTime); sl@0: sl@0: /** sl@0: * Resume the operation (Play, Record, TonePlay) temporarily paused . sl@0: * @since sl@0: * @return TInt KErrNone if succesful sl@0: * KErrNotSupported if the operation is not supported by this implementation sl@0: */ sl@0: virtual TInt Resume(); sl@0: sl@0: /* sl@0: Used to send a stop call when there is a error in the buffer sl@0: */ sl@0: virtual void BufferErrorEvent(); sl@0: sl@0: protected: sl@0: sl@0: CDevAudioControl(); sl@0: sl@0: void ConstructL(CDevAudio* aDevAudio, MDevSoundAdaptationObserver& aDevSoundObserver); sl@0: sl@0: // Ensure iAudioCodecIf is setup properly sl@0: TInt CacheAudioCodecIf(); sl@0: sl@0: /** sl@0: * Returns to initialized state wanted control components sl@0: * @since sl@0: * @return error code sl@0: */ sl@0: TInt Unload(); sl@0: sl@0: sl@0: /** sl@0: * Panic the thread sl@0: * @since sl@0: * @param panic code sl@0: */ sl@0: void Panic(TDevSoundAdaptorPanicCode aCode); sl@0: sl@0: private: sl@0: TInt ResolveMode(TUint aMode, TUid& aModeValue); sl@0: TInt ResolveSampleRate(TInt aSampleRate, TInt& aSampleRateValue); sl@0: TUint GetModes(const RArray& aMode); sl@0: TUint GetMode(TUid aMode); sl@0: TUint GetSampleRates(const RArray& aSampleRates); sl@0: TUint GetSampleRate(TInt aSampleRates); sl@0: void CompleteMessageCap(TInt aError); sl@0: sl@0: /** sl@0: * Member data is protected for subclass access sl@0: */ sl@0: protected: // data sl@0: sl@0: // Not own sl@0: CDevAudio *iDevAudio; sl@0: sl@0: /** sl@0: * Pointer to audio codec sl@0: * Not own. sl@0: */ sl@0: MAudioCodec* iAudioCodecIf; sl@0: sl@0: /** sl@0: * Pointer to audio gain control sl@0: * Not own. sl@0: */ sl@0: MAudioGainControl* iGainControl; sl@0: sl@0: /** sl@0: * Observer for callbacks to DevSound Framework sl@0: * Not own. sl@0: */ sl@0: MDevSoundAdaptationObserver *iAdaptationObserver; sl@0: sl@0: sl@0: /* sl@0: * TODO: Review if this for buffer exchange sl@0: */ sl@0: CMMFBuffer* iBuffer; sl@0: sl@0: /** sl@0: * Local cache of volume stuff sl@0: */ sl@0: TInt iLegacyGain; sl@0: TInt iLegacyLeft; sl@0: TInt iLegacyRight; sl@0: sl@0: TInt iError; sl@0: TBool iGainUpdateNeeded; sl@0: TBool iStateEventReceived; sl@0: TInt iStateEventError; sl@0: TInt iCallbackFromAdaptor; sl@0: TInt iProcessingUnitError; sl@0: sl@0: TInt iErrorCondition; sl@0: sl@0: TBool iObserverRegistered; sl@0: sl@0: //Indicates whether the AsyncOperationComplete callback needs to be made during Preemption sl@0: TBool iIgnoreAsyncOpComplete; sl@0: sl@0: TBool iPauseResumeSequenceDueToEmptyBuffers; sl@0: sl@0: private: sl@0: sl@0: RArray iChannelGains; sl@0: sl@0: RArray iSupportedModes; sl@0: RArray iSupportedRates; sl@0: TInt iDesiredSampleRate; sl@0: TUid iDesiredMode; sl@0: TInt iCurrentSampleRate; sl@0: TUid iCurrentMode; sl@0: TInt iOutstandingCallbacks; sl@0: sl@0: }; sl@0: sl@0: #endif // CDEVAUDIOCONTROL_H