sl@0: // Copyright (c) 2002-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: #ifndef __MMF_AUDIOOUTPUT_H__
sl@0: #define __MMF_AUDIOOUTPUT_H__
sl@0: 
sl@0: // Standard EPOC32 includes required by this header file
sl@0: #include <e32base.h>
sl@0: #include <e32std.h>
sl@0: 
sl@0: 
sl@0: #include <mmf/common/mmfpaniccodes.h>
sl@0: 
sl@0: //DevSound
sl@0: #include <mmf/server/sounddevice.h>
sl@0: 
sl@0: /** 
sl@0: @publishedAll
sl@0: @deprecated
sl@0: */
sl@0: const TUint KAudioOutputDefaultFrameSize = 0x1000;
sl@0: 
sl@0: 
sl@0: void Panic(TInt aPanicCode);
sl@0: 
sl@0: /**
sl@0: @publishedAll
sl@0: @released
sl@0: 
sl@0: Interface class to allow dynamic linkage to CMMFAudioOutput.
sl@0: */
sl@0: class MMMFAudioOutput : public MDataSink
sl@0: 	{
sl@0: public:
sl@0: 	//factory function
sl@0: 	/**
sl@0: 	Gets a new audio output object.
sl@0: 
sl@0: 	@param  aImplementationUid
sl@0: 	        The implementation UID.
sl@0: 	@param  aInitData
sl@0: 	        The initialisation data.
sl@0: 
sl@0: 	@return The audio output object.
sl@0: 	*/
sl@0: 	inline static MMMFAudioOutput* NewAudioOutputL(TUid aImplementationUid, const TDesC8& aInitData);
sl@0: 	//interface
sl@0: 
sl@0: 	/**
sl@0: 	Returns the sound device.
sl@0: 
sl@0: 	Accessor function exposing public CMMFDevsound methods.
sl@0: 
sl@0: 	@return	A reference to a CMMFDevSound objector.
sl@0: 	*/
sl@0: 	virtual CMMFDevSound& SoundDevice() = 0;
sl@0: 
sl@0: 	/**
sl@0: 	Returns the number of bytes played.
sl@0: 
sl@0: 	@return	The number of bytes played. If 16-bit divide this number returned by 2 to get word
sl@0: 	        length.
sl@0: 	*/
sl@0: 	virtual TInt BytesPlayed() = 0;
sl@0: 
sl@0: 	/**
sl@0: 	@deprecated
sl@0: 
sl@0: 	Gets audio from hardware device abstracted MMFDevsound (not used).
sl@0: 
sl@0: 	@param	aBuffer
sl@0: 			The data to read in from a Hardware Device
sl@0: 	@param	aSupplier
sl@0: 			The MDataSink consuming the data contained in aBuffer.
sl@0: 	*/
sl@0: 	virtual void HWEmptyBufferL(CMMFBuffer* aBuffer, MDataSource* aSupplier)=0;//called by a EmptyBufferL if using HW codec
sl@0: protected:
sl@0: 	//constructor
sl@0: 	/**
sl@0: 	Protected constructor.
sl@0: 	*/
sl@0: 	MMMFAudioOutput() : MDataSink(KUidMmfAudioOutput) {}
sl@0: 	};
sl@0: 
sl@0: inline MMMFAudioOutput* MMMFAudioOutput::NewAudioOutputL( TUid aImplementationUid,  const TDesC8& aInitData )
sl@0: 	{
sl@0: 	//make sure the cast will be ok by checking the uid is what we expect
sl@0: 	__ASSERT_ALWAYS(aImplementationUid==KUidMmfAudioOutput, Panic(EMMFAudioOutputPanicBadUID));
sl@0: 	MMMFAudioOutput* retPtr = STATIC_CAST(MMMFAudioOutput*, MDataSink::NewSinkL(aImplementationUid, aInitData));
sl@0: 	return retPtr;
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: @publishedAll
sl@0: @released
sl@0: 
sl@0: The interface into DevSound.
sl@0: 
sl@0: Abstract data sink class providing an interface into hardware sound output.
sl@0: 
sl@0: Uses CMMFDevSound to access such output.
sl@0: */
sl@0: class CMMFChannelAndSampleRateConverterFactory;
sl@0: class CMMFChannelAndSampleRateConverter;
sl@0: class CMMFAudioOutput : public CBase, public MMMFAudioOutput, public MDevSoundObserver
sl@0: 
sl@0: 	{
sl@0: public:
sl@0: 	static MDataSink* NewSinkL() ;
sl@0: 	virtual ~CMMFAudioOutput();
sl@0: 	void ConstructL();
sl@0: 
sl@0: 	//MDataSink mixin implementations
sl@0: 	virtual TFourCC SinkDataTypeCode(TMediaId aMediaId); //used by data path MDataSource/Sink for codec matching
sl@0: 	virtual void EmptyBufferL(CMMFBuffer* aBuffer, MDataSource* aSupplier, TMediaId aMediaId);//called by a MDataSource to empty a buffer
sl@0: 	virtual void BufferFilledL(CMMFBuffer* aBuffer); //called by MDataSource to pass back full buffer to the sink
sl@0: 	virtual TBool CanCreateSinkBuffer();
sl@0: 	virtual CMMFBuffer* CreateSinkBufferL(TMediaId aMediaId, TBool &aReference);
sl@0: 	virtual TInt SinkThreadLogon(MAsyncEventHandler& aEventHandler);
sl@0: 	virtual void SinkThreadLogoff();
sl@0: 	virtual void SinkPrimeL();
sl@0: 	virtual void SinkPauseL();
sl@0: 	virtual void SinkPlayL();
sl@0: 	virtual void SinkStopL();
sl@0: 	virtual void SetSinkPrioritySettings(const TMMFPrioritySettings& aPrioritySettings);
sl@0: 	virtual void NegotiateL(MDataSource& aSource);
sl@0: 	// MMMFAudioOutput mixin implementations
sl@0: 	TInt BytesPlayed();
sl@0: 	void HWEmptyBufferL(CMMFBuffer* aBuffer, MDataSource* aSupplier);//called by a EmptyBufferL if using HW codec
sl@0: 	CMMFDevSound& SoundDevice();
sl@0: 	virtual TInt SetSinkDataTypeCode(TFourCC aSinkFourCC, TMediaId aMediaId);
sl@0: 
sl@0: 	//The following DataType() methods should not be used.
sl@0: 	//They are provided to maintain BC/SC with 7.0s
sl@0: 	virtual void SetDataTypeL(TFourCC aAudioType);
sl@0: 	virtual TFourCC DataType() const;
sl@0: 
sl@0: protected:
sl@0: 	virtual void ConstructSinkL( const TDesC8& aInitData ) ;
sl@0: 
sl@0: private:
sl@0: 	inline CMMFAudioOutput() {}
sl@0: 
sl@0: 	void ConfigDevSoundL();
sl@0: 	void LoadL();
sl@0: 	TInt State();
sl@0: 
sl@0: 	//MDevSoundObserver mixin implementations	
sl@0: 	virtual void InitializeComplete(TInt aError);
sl@0: 	virtual void ToneFinished(TInt aError); 
sl@0: 	virtual void BufferToBeFilled(CMMFBuffer* aBuffer);
sl@0: 	virtual void PlayError(TInt aError); 
sl@0: 	virtual void BufferToBeEmptied(CMMFBuffer* aBuffer); 
sl@0: 	virtual void RecordError(TInt aError); 
sl@0: 	virtual void ConvertError(TInt aError);
sl@0: 	virtual void DeviceMessage(TUid aMessageType, const TDesC8& aMsg);
sl@0: 	virtual void SendEventToClient(const TMMFEvent& /*aEvent*/);
sl@0: 
sl@0: public:
sl@0: 	virtual TBool IsResumeSupported();
sl@0: 
sl@0: private:
sl@0: 	MAsyncEventHandler* iEventHandler;
sl@0: 	CMMFDevSound* iMMFDevSound;	//this is now private to stop stuff "grabbing it"
sl@0: 	CMMFBuffer* iAudioBuffer;
sl@0: 	TInt iInitializeState;	
sl@0: 	enum TState
sl@0: 		{
sl@0: 		EIdle=0,
sl@0: 		EDevSoundReady,
sl@0: 		EPaused
sl@0: 		};
sl@0: 
sl@0: 	enum TError
sl@0: 		{
sl@0: 		ECantCreateBuffer,
sl@0: 		EEmptyBuffer,
sl@0: 		EDevSoundNotLoaded,
sl@0: 		ERecordNotSupported,
sl@0: 		EDevSoundError,
sl@0: 		EUnknown
sl@0: 		};
sl@0: 
sl@0: 	MDataSource* iSupplier;
sl@0: 	TState iState;
sl@0: 
sl@0: 	TBool iCanSendBuffers;
sl@0: 	TBool iPlayStarted;
sl@0: 	TBool iDevSoundLoaded;
sl@0: 
sl@0: 	TError iError;
sl@0: 	TInt iMMFDevsoundError;
sl@0: 	TMMFPrioritySettings iPrioritySettings;
sl@0: 
sl@0: 	TUint iSourceSampleRate; 
sl@0: 	TUint iSourceChannels;
sl@0: 	TFourCC iSourceFourCC;
sl@0: 	TFourCC iDataTypeCode;
sl@0: 	CMMFDataBuffer* iDevSoundBuffer;
sl@0: 
sl@0: 	TMMFCapabilities iDevSoundConfig;
sl@0: 
sl@0:  	TBool iNeedsSWConversion;
sl@0: 	TUint iSWConvertSampleRate;
sl@0: 	TUint iSWConvertChannels;
sl@0:  	CMMFChannelAndSampleRateConverterFactory* iChannelAndSampleRateConverterFactory;
sl@0:  	CMMFChannelAndSampleRateConverter* iChannelAndSampleRateConverter;
sl@0:  	CMMFDataBuffer* iConvertBuffer;
sl@0:  	CMMFBuffer* iBufferToEmpty;
sl@0:  	CActiveSchedulerWait* iActiveSchedulerWait;
sl@0: 	};
sl@0: 
sl@0: #endif