mmdevicefw/mdf/src/audio/mdasoundadapter/mdasoundadapterbody.h
changeset 0 40261b775718
child 24 2672ba96448e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mmdevicefw/mdf/src/audio/mdasoundadapter/mdasoundadapterbody.h	Tue Feb 02 01:56:55 2010 +0200
@@ -0,0 +1,505 @@
+// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+//
+
+#ifndef MDASOUNDADAPTERBODY_H
+#define MDASOUNDADAPTERBODY_H
+
+#include "mdasoundadapter.h"
+#include <d32soundsc.h>
+#include <e32base.h>
+#include <e32std.h>
+
+/** 
+Panic category and codes for the mdasoundadapter
+*/
+_LIT(KSoundAdapterPanicCategory, "mdasoundadapter");
+enum TSoundAdapterPanicCodes
+	{
+	EDeviceNotOpened,
+	EPanicPartialBufferConverterNotSupported,
+	};
+	
+//Structure used to map samples per second to the corresponding enums in RSoundSc
+struct TSampleRateEnumTable
+  	{
+	TInt iRate;
+	TSoundRate iRateEnum;
+	TUint iRateConstant;
+	};
+
+//Table that maps given samples per second to the corresponding enums in RSoundSc
+const TSampleRateEnumTable KRateEnumLookup[] =
+								 {
+									{48000,ESoundRate48000Hz,KSoundRate48000Hz},
+			                   		{44100,ESoundRate44100Hz,KSoundRate44100Hz},
+				                  	{32000,ESoundRate32000Hz,KSoundRate32000Hz},
+									{24000,ESoundRate24000Hz,KSoundRate24000Hz},
+				                  	{22050,ESoundRate22050Hz,KSoundRate22050Hz},
+				                  	{16000,ESoundRate16000Hz,KSoundRate16000Hz},
+				                  	{12000,ESoundRate12000Hz,KSoundRate12000Hz},
+				                  	{11025,ESoundRate11025Hz,KSoundRate11025Hz},
+				                  	{8000, ESoundRate8000Hz, KSoundRate8000Hz}
+                   				 };
+//Structure used to map linear value of the volume to the decibel value.
+struct TLinearToDbTable
+	{
+	TInt iLiniearValue;
+	TInt iDBValue;
+	};
+
+
+//Table that maps given linear value of volume to the corresponding decibel value.
+const TLinearToDbTable KLinerToDbConstantLookup[] =
+						{
+							{0,0},
+							{1,158},
+							{2,170},
+							{3,177},
+							{4,182},
+							{5,186},
+							{6,189},
+							{7,192},
+							{8,194},
+							{9,196},
+							{10,198},
+							{11,200},
+							{12,201},
+							{13,203},
+							{14,204},
+							{15,205},
+							{16,206},
+							{17,207},
+							{18,208},
+							{19,209},
+							{20,210},
+							{21,211},
+							{22,212},
+							{23,213},
+							{24,213},
+							{25,214},
+							{26,215},
+							{27,215},
+							{28,216},
+							{29,217},
+							{30,217},
+							{31,218},
+							{32,218},
+							{33,219},
+							{34,219},
+							{35,220},
+							{36,220},
+							{37,221},
+							{38,221},
+							{39,222},
+							{40,222},
+							{41,223},
+							{42,223},
+							{43,224},
+							{44,224},
+							{45,224},
+							{46,225},
+							{47,225},
+							{48,225},
+							{49,226},
+							{50,226},
+							{51,226},
+							{52,227},
+							{53,227},
+							{54,227},
+							{55,228},
+							{56,228},
+							{57,228},
+							{58,229},
+							{59,229},
+							{60,229},
+							{61,230},
+							{62,230},
+							{63,230},
+							{64,230},
+							{65,231},
+							{66,231},
+							{67,231},
+							{68,231},
+							{69,232},
+							{70,232},
+							{71,232},
+							{72,232},
+							{73,233},
+							{74,233},
+							{75,233},
+							{76,233},
+							{77,234},
+							{78,234},
+							{79,234},
+							{80,234},
+							{81,235},
+							{82,235},
+							{83,235},
+							{84,235},
+							{85,235},
+							{86,236},
+							{87,236},
+							{88,236},
+							{89,236},
+							{90,236},
+							{91,237},
+							{92,237},
+							{93,237},
+							{94,237},
+							{95,237},
+							{96,237},
+							{97,238},
+							{98,238},
+							{99,238},
+							{100,238},
+							{101,238},
+							{102,239},
+							{103,239},
+							{104,239},
+							{105,239},
+							{106,239},
+							{107,239},
+							{108,240},
+							{109,240},
+							{110,240},
+							{111,240},
+							{112,240},
+							{113,240},
+							{114,240},
+							{115,241},
+							{116,241},
+							{117,241},
+							{118,241},
+							{119,241},
+							{120,241},
+							{121,241},
+							{122,242},
+							{123,242},
+							{124,242},
+							{125,242},
+							{126,242},
+							{127,242},
+							{128,242},
+							{129,243},
+							{130,243},
+							{131,243},
+							{132,243},
+							{133,243},
+							{134,243},
+							{135,243},
+							{136,244},
+							{137,244},
+							{138,244},
+							{139,244},
+							{140,244},
+							{141,244},
+							{142,244},
+							{143,244},
+							{144,245},
+							{145,245},
+							{146,245},
+							{147,245},
+							{148,245},
+							{149,245},
+							{150,245},
+							{151,245},
+							{152,245},
+							{153,246},
+							{154,246},
+							{155,246},
+							{156,246},
+							{157,246},
+							{158,246},
+							{159,246},
+							{160,246},
+							{161,246},
+							{162,247},
+							{163,247},
+							{164,247},
+							{165,247},
+							{166,247},
+							{167,247},
+							{168,247},
+							{169,247},
+							{170,247},
+							{171,247},
+							{172,248},
+							{173,248},
+							{174,248},
+							{175,248},
+							{176,248},
+							{177,248},
+							{178,248},
+							{179,248},
+							{180,248},
+							{181,248},
+							{182,249},
+							{183,249},
+							{184,249},
+							{185,249},
+							{186,249},
+							{187,249},
+							{188,249},
+							{189,249},
+							{190,249},
+							{191,249},
+							{192,250},
+							{193,250},
+							{194,250},
+							{195,250},
+							{196,250},
+							{197,250},
+							{198,250},
+							{199,250},
+							{200,250},
+							{201,250},
+							{202,250},
+							{203,250},
+							{204,251},
+							{205,251},
+							{206,251},
+							{207,251},
+							{208,251},
+							{209,251},
+							{210,251},
+							{211,251},
+							{212,251},
+							{213,251},
+							{214,251},
+							{215,251},
+							{216,252},
+							{217,252},
+							{218,252},
+							{219,252},
+							{220,252},
+							{221,252},
+							{222,252},
+							{223,252},
+							{224,252},
+							{225,252},
+							{226,252},
+							{227,252},
+							{228,252},
+							{229,253},
+							{230,253},
+							{231,253},
+							{232,253},
+							{233,253},
+							{234,253},
+							{235,253},
+							{236,253},
+							{237,253},
+							{238,253},
+							{239,253},
+							{240,253},
+							{241,253},
+							{242,254},
+							{243,254},
+							{244,254},
+							{245,254},
+							{246,254},
+							{247,254},
+							{248,254},
+							{249,254},
+							{250,254},
+							{251,254},
+							{252,254},
+							{253,254},
+							{254,254},
+							{255,254}
+						};
+
+//Total Number of sample rates
+const TInt KNumSampleRates = 9;
+//Number of shared chunk buffers used for playing
+const TInt KPlayMaxSharedChunkBuffers = 2;
+const TInt KPlayMaxSharedChunkBuffersMask = KPlayMaxSharedChunkBuffers-1; // use for % KPlayMaxSharedChunkBuffers
+//Number of shared chunk buffers used for recording
+const TInt KRecordMaxSharedChunkBuffers = 3;
+//we need to two players for playing and one is sufficient for recording
+const TInt KNumPlayers = 2;
+const TInt KNumPlayersMask = KNumPlayers-1; // & KNumPlayersMask is equiv to % KNumPlayers
+//Shared chunk driver does not support max. buffer size. 16K is given in order to simulate the old driver behavior.
+const TInt KMaxBufferSize = 0x4000;
+
+class TPlaySharedChunkBufConfig : public TSharedChunkBufConfigBase
+	{
+public:
+	TInt iBufferOffsetList[KPlayMaxSharedChunkBuffers];
+	};
+
+class TRecordSharedChunkBufConfig : public TSharedChunkBufConfigBase
+	{
+public:
+	TInt iBufferOffsetList[KRecordMaxSharedChunkBuffers];
+	};
+	
+class CChannelAndSampleRateConverter; // forward dec
+
+//Body class for the adapter
+NONSHARABLE_CLASS( RMdaDevSound::CBody ): public CBase
+	{
+public:
+	//This class handles the play/record completions from the new sound driver
+	NONSHARABLE_CLASS( CPlayer ) : public CActive
+		{
+	public:
+		explicit CPlayer(TInt aPriority, RMdaDevSound::CBody& aParent, TInt aIndex);
+		~CPlayer();
+		void RunL();
+		TInt RunError(TInt aError);
+		void DoCancel();
+		void RecordData(TInt& aLength);
+		void PlayData(TInt aBufferOffset, TInt aBufferLength);
+		void Stop();
+		void ResetPlayer();
+		void PlaySoundDevice();
+	private:
+		RMdaDevSound::CBody& iParent;
+		const TInt iIndex; // index of this object in parent
+		TBool iRequestPending;
+		TInt iBufferOffset;
+		TInt iBufferLength;
+		};
+	
+	enum TState
+		{
+		ENotReady,
+		EOpened,
+		EPlaying,
+		ERecording,
+		EPlayBuffersFlushed,
+		EPaused
+		};
+		
+	class TFormatData
+		{
+	public:
+		inline TFormatData():
+			iSampleRate(8000), iRequestedChannels(1) // default
+			{
+			}
+	public:
+		CChannelAndSampleRateConverter* iConverter;
+		TInt iSampleRate;
+		TInt iActualRate;
+		TInt iRequestedChannels;
+		TInt iActualChannels;			
+		};
+		
+public:
+	~CBody();
+	static CBody* NewL();
+	TInt Open(TInt aUnit=KNullUnit);
+	TVersion VersionRequired() const;
+	TInt IsMdaSound();
+	void PlayFormatsSupported(TSoundFormatsSupportedBuf& aFormatsSupported);
+	void GetPlayFormat(TCurrentSoundFormatBuf& aFormat);
+	TInt SetPlayFormat(const TCurrentSoundFormatBuf& aFormat);
+	TInt PlayVolume();
+	void SetPlayVolume(TInt aVolume);
+	void SetVolume(TInt aLogarithmicVolume);
+	void CancelPlayData();
+	void RecordFormatsSupported(TSoundFormatsSupportedBuf& aFormatsSupported);
+	void GetRecordFormat(TCurrentSoundFormatBuf& aFormat);
+	TInt SetRecordFormat(const TCurrentSoundFormatBuf& aFormat);
+	TInt RecordLevel();
+	void SetRecordLevel(TInt aLevel);
+	void CancelRecordData();
+	void FlushRecordBuffer();
+	TInt BytesPlayed();
+	void ResetBytesPlayed();
+	void PausePlayBuffer();
+	void ResumePlaying();
+	void PauseRecordBuffer();
+	void ResumeRecording();
+	TInt GetTimePlayed(TTimeIntervalMicroSeconds& aTimePlayed);
+	void Close();
+	TInt Handle();
+	void PlayData(TRequestStatus& aStatus,const TDesC8& aData);
+	void RecordData(TRequestStatus& aStatus,TDes8& aData);
+	void NotifyRecordError(TRequestStatus& aStatus);
+	void NotifyPlayError(TRequestStatus& aStatus);
+	void CancelNotifyPlayError();
+	void CancelNotifyRecordError();
+	void FlushPlayBuffer();
+	//internal methods added to reduce the code
+	void FormatsSupported(TSoundFormatsSupportedBuf& aFormatsSupported, RSoundSc& aDevice);
+	void GetFormat(TCurrentSoundFormatBuf& aFormat, RSoundSc& aDevice, const TFormatData &aFormatData);
+	TInt SetFormat(const TCurrentSoundFormatBuf& aFormat, RSoundSc& aDevice, TFormatData &aFormatData);
+	
+	//for players
+	void SoundDeviceError(TInt aError);
+	void SoundDeviceError(TInt aError, TInt aPlayerIndex);
+	RSoundSc& PlaySoundDevice();
+	RSoundSc& RecordSoundDevice();
+	TState State();
+	void BufferFilled(TInt aError);
+	void BufferEmptied();
+	void PlayCancelled();
+	void UpdateTimeAndBytesPlayed();
+	TBool TimerActive();
+	TBool FlushCalledDuringPause();
+
+private:
+	CBody();
+	void ConstructL();
+	
+	TInt NegotiateFormat(const TCurrentSoundFormatBuf& aFormat, RSoundSc& aDevice, TFormatData &aFormatData);
+private:
+	RSoundSc iPlaySoundDevice;
+	RSoundSc iRecordSoundDevice;
+	RChunk iChunk;//handle to the shared chunk
+	TState iState;
+	CPlayer* iPlayers[KNumPlayers];//we need atleast two players for playing and one for recording
+	
+	//Playing Properties
+	TPlaySharedChunkBufConfig iBufferConfig;
+	TInt iBufferIndex;
+	TInt iCurrentPlayer;
+	TInt iDeviceBufferLength;
+	//Stores the status of CDataPathPlayer
+	TRequestStatus* iPlayerStatus;
+	//Stores the status of CSoundDevPlayErrorReceiver
+	TRequestStatus* iPlayErrorStatus;
+	RBuf8 iBufferRemaining;
+	TBool iHaveSecondPhaseData;
+	TInt iRequestMinSize;
+	TUint iRequestMinMask;
+	
+	//Recording Properties
+	TRecordSharedChunkBufConfig iRecordBufferConfig;
+	TInt iBufferOffset;
+	TInt iBufferLength;
+	TPtrC8 iSecondPhaseData;
+	//Stores the status of CDataPathRecorder
+	TRequestStatus* iRecorderStatus;
+	//Stores the status of CSoundDevRecordErrorReceiver
+	TRequestStatus* iRecordErrorStatus;
+	TDes8* iData;//stores the data pointer from datapath recorder
+	TInt iBytesPlayed;
+#ifdef SYMBIAN_SOUNDADAPTER_BYTESPLAYED
+	TInt iFCFrequency;
+#endif
+	TUint32 iStartTime;
+	TBool iTimerActive;
+	TBool iFlushCalledDuringPause;
+	TBool iPauseDeviceDriverOnNewData;
+
+	TFormatData iPlayData;
+	TFormatData iRecordData;
+	};
+GLDEF_C void Panic(TSoundAdapterPanicCodes aPanicCode);//forward declaration
+#endif