os/mm/mmdevicefw/mdf/src/audio/mdasoundadapter/mdasoundadapterbody.h
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 #ifndef MDASOUNDADAPTERBODY_H
    17 #define MDASOUNDADAPTERBODY_H
    18 
    19 #include "mdasoundadapter.h"
    20 #include <d32soundsc.h>
    21 #include <e32base.h>
    22 #include <e32std.h>
    23 
    24 /** 
    25 Panic category and codes for the mdasoundadapter
    26 */
    27 _LIT(KSoundAdapterPanicCategory, "mdasoundadapter");
    28 enum TSoundAdapterPanicCodes
    29 	{
    30 	EDeviceNotOpened,
    31 	EPanicPartialBufferConverterNotSupported,
    32 	EBadState,
    33 	ENoClientPlayRequest,
    34 	EFifoEmpty,
    35 	EFifoFull
    36 	};
    37 	
    38 //Structure used to map samples per second to the corresponding enums in RSoundSc
    39 struct TSampleRateEnumTable
    40   	{
    41 	TInt iRate;
    42 	TSoundRate iRateEnum;
    43 	TUint iRateConstant;
    44 	};
    45 
    46 //Table that maps given samples per second to the corresponding enums in RSoundSc
    47 const TSampleRateEnumTable KRateEnumLookup[] =
    48 								 {
    49 									{48000,ESoundRate48000Hz,KSoundRate48000Hz},
    50 			                   		{44100,ESoundRate44100Hz,KSoundRate44100Hz},
    51 				                  	{32000,ESoundRate32000Hz,KSoundRate32000Hz},
    52 									{24000,ESoundRate24000Hz,KSoundRate24000Hz},
    53 				                  	{22050,ESoundRate22050Hz,KSoundRate22050Hz},
    54 				                  	{16000,ESoundRate16000Hz,KSoundRate16000Hz},
    55 				                  	{12000,ESoundRate12000Hz,KSoundRate12000Hz},
    56 				                  	{11025,ESoundRate11025Hz,KSoundRate11025Hz},
    57 				                  	{8000, ESoundRate8000Hz, KSoundRate8000Hz}
    58                    				 };
    59 //Structure used to map linear value of the volume to the decibel value.
    60 struct TLinearToDbTable
    61 	{
    62 	TInt iLiniearValue;
    63 	TInt iDBValue;
    64 	};
    65 
    66 
    67 //Table that maps given linear value of volume to the corresponding decibel value.
    68 const TLinearToDbTable KLinerToDbConstantLookup[] =
    69 						{
    70 							{0,0},
    71 							{1,158},
    72 							{2,170},
    73 							{3,177},
    74 							{4,182},
    75 							{5,186},
    76 							{6,189},
    77 							{7,192},
    78 							{8,194},
    79 							{9,196},
    80 							{10,198},
    81 							{11,200},
    82 							{12,201},
    83 							{13,203},
    84 							{14,204},
    85 							{15,205},
    86 							{16,206},
    87 							{17,207},
    88 							{18,208},
    89 							{19,209},
    90 							{20,210},
    91 							{21,211},
    92 							{22,212},
    93 							{23,213},
    94 							{24,213},
    95 							{25,214},
    96 							{26,215},
    97 							{27,215},
    98 							{28,216},
    99 							{29,217},
   100 							{30,217},
   101 							{31,218},
   102 							{32,218},
   103 							{33,219},
   104 							{34,219},
   105 							{35,220},
   106 							{36,220},
   107 							{37,221},
   108 							{38,221},
   109 							{39,222},
   110 							{40,222},
   111 							{41,223},
   112 							{42,223},
   113 							{43,224},
   114 							{44,224},
   115 							{45,224},
   116 							{46,225},
   117 							{47,225},
   118 							{48,225},
   119 							{49,226},
   120 							{50,226},
   121 							{51,226},
   122 							{52,227},
   123 							{53,227},
   124 							{54,227},
   125 							{55,228},
   126 							{56,228},
   127 							{57,228},
   128 							{58,229},
   129 							{59,229},
   130 							{60,229},
   131 							{61,230},
   132 							{62,230},
   133 							{63,230},
   134 							{64,230},
   135 							{65,231},
   136 							{66,231},
   137 							{67,231},
   138 							{68,231},
   139 							{69,232},
   140 							{70,232},
   141 							{71,232},
   142 							{72,232},
   143 							{73,233},
   144 							{74,233},
   145 							{75,233},
   146 							{76,233},
   147 							{77,234},
   148 							{78,234},
   149 							{79,234},
   150 							{80,234},
   151 							{81,235},
   152 							{82,235},
   153 							{83,235},
   154 							{84,235},
   155 							{85,235},
   156 							{86,236},
   157 							{87,236},
   158 							{88,236},
   159 							{89,236},
   160 							{90,236},
   161 							{91,237},
   162 							{92,237},
   163 							{93,237},
   164 							{94,237},
   165 							{95,237},
   166 							{96,237},
   167 							{97,238},
   168 							{98,238},
   169 							{99,238},
   170 							{100,238},
   171 							{101,238},
   172 							{102,239},
   173 							{103,239},
   174 							{104,239},
   175 							{105,239},
   176 							{106,239},
   177 							{107,239},
   178 							{108,240},
   179 							{109,240},
   180 							{110,240},
   181 							{111,240},
   182 							{112,240},
   183 							{113,240},
   184 							{114,240},
   185 							{115,241},
   186 							{116,241},
   187 							{117,241},
   188 							{118,241},
   189 							{119,241},
   190 							{120,241},
   191 							{121,241},
   192 							{122,242},
   193 							{123,242},
   194 							{124,242},
   195 							{125,242},
   196 							{126,242},
   197 							{127,242},
   198 							{128,242},
   199 							{129,243},
   200 							{130,243},
   201 							{131,243},
   202 							{132,243},
   203 							{133,243},
   204 							{134,243},
   205 							{135,243},
   206 							{136,244},
   207 							{137,244},
   208 							{138,244},
   209 							{139,244},
   210 							{140,244},
   211 							{141,244},
   212 							{142,244},
   213 							{143,244},
   214 							{144,245},
   215 							{145,245},
   216 							{146,245},
   217 							{147,245},
   218 							{148,245},
   219 							{149,245},
   220 							{150,245},
   221 							{151,245},
   222 							{152,245},
   223 							{153,246},
   224 							{154,246},
   225 							{155,246},
   226 							{156,246},
   227 							{157,246},
   228 							{158,246},
   229 							{159,246},
   230 							{160,246},
   231 							{161,246},
   232 							{162,247},
   233 							{163,247},
   234 							{164,247},
   235 							{165,247},
   236 							{166,247},
   237 							{167,247},
   238 							{168,247},
   239 							{169,247},
   240 							{170,247},
   241 							{171,247},
   242 							{172,248},
   243 							{173,248},
   244 							{174,248},
   245 							{175,248},
   246 							{176,248},
   247 							{177,248},
   248 							{178,248},
   249 							{179,248},
   250 							{180,248},
   251 							{181,248},
   252 							{182,249},
   253 							{183,249},
   254 							{184,249},
   255 							{185,249},
   256 							{186,249},
   257 							{187,249},
   258 							{188,249},
   259 							{189,249},
   260 							{190,249},
   261 							{191,249},
   262 							{192,250},
   263 							{193,250},
   264 							{194,250},
   265 							{195,250},
   266 							{196,250},
   267 							{197,250},
   268 							{198,250},
   269 							{199,250},
   270 							{200,250},
   271 							{201,250},
   272 							{202,250},
   273 							{203,250},
   274 							{204,251},
   275 							{205,251},
   276 							{206,251},
   277 							{207,251},
   278 							{208,251},
   279 							{209,251},
   280 							{210,251},
   281 							{211,251},
   282 							{212,251},
   283 							{213,251},
   284 							{214,251},
   285 							{215,251},
   286 							{216,252},
   287 							{217,252},
   288 							{218,252},
   289 							{219,252},
   290 							{220,252},
   291 							{221,252},
   292 							{222,252},
   293 							{223,252},
   294 							{224,252},
   295 							{225,252},
   296 							{226,252},
   297 							{227,252},
   298 							{228,252},
   299 							{229,253},
   300 							{230,253},
   301 							{231,253},
   302 							{232,253},
   303 							{233,253},
   304 							{234,253},
   305 							{235,253},
   306 							{236,253},
   307 							{237,253},
   308 							{238,253},
   309 							{239,253},
   310 							{240,253},
   311 							{241,253},
   312 							{242,254},
   313 							{243,254},
   314 							{244,254},
   315 							{245,254},
   316 							{246,254},
   317 							{247,254},
   318 							{248,254},
   319 							{249,254},
   320 							{250,254},
   321 							{251,254},
   322 							{252,254},
   323 							{253,254},
   324 							{254,254},
   325 							{255,254}
   326 						};
   327 
   328 // Total Number of sample rates
   329 const TUint KNumSampleRates = 9;
   330 // Number of shared chunk buffers used for playing
   331 // Each buffer is permanently mapped, via an index number, to a particular buffer in the chunk
   332 // The esoundsc.ldd can only handle a max of 8 pending play requests, therefore no point in having
   333 // more than 8 play buffers...
   334 const TUint KPlaySharedChunkBuffers = 8;
   335 // Size of RSoundSc play buffers
   336 const TUint KPlaySharedChunkBufferSize = 4096;
   337 
   338 //Number of shared chunk buffers used for recording
   339 const TUint KRecordMaxSharedChunkBuffers = 8;
   340 // Size of RSoundSc record buffers
   341 const TUint KRecordSharedChunkBufferSize = 4096;
   342 
   343 //Shared chunk driver does not support max. buffer size. 16K is given in order to simulate the old driver behavior.
   344 const TUint KMaxBufferSize = 0x4000;
   345 
   346 class TPlaySharedChunkBufConfig : public TSharedChunkBufConfigBase
   347 	{
   348 public:
   349 	TInt iBufferOffsetList[KPlaySharedChunkBuffers];
   350 	};
   351 
   352 class TRecordSharedChunkBufConfig : public TSharedChunkBufConfigBase
   353 	{
   354 public:
   355 	TInt iBufferOffsetList[KRecordMaxSharedChunkBuffers];
   356 	};
   357 	
   358 class CChannelAndSampleRateConverter; // forward dec
   359 
   360 GLDEF_C void Panic(TSoundAdapterPanicCodes aPanicCode);//forward declaration
   361 
   362 // RFifo class which manages a fifo of up to COUNT items of type T
   363 template<typename T, TUint32 COUNT> class RFifo
   364 	{
   365 public:
   366 	RFifo()
   367 		: iWriteIndex(0), iReadIndex(0)
   368 		{}
   369 	TBool IsEmpty() const
   370 		{
   371 		return iWriteIndex == iReadIndex;
   372 		}
   373 	TBool IsFull() const
   374 		{
   375 		// Full if writing one more item would make iWriteIndex equal to iReadIndex
   376 		TUint32 next = NextIndex(iWriteIndex);
   377 		return next == iReadIndex;
   378 		}
   379 	/// Push item into FIFO. Does not take ownership. Will PANIC with EFifoFull if full.
   380 	void Push(const T &aItem)
   381 		{
   382 		if(IsFull())
   383 			{
   384 			Panic(EFifoFull);
   385 			}
   386 		iFifo[iWriteIndex] = aItem;
   387 		iWriteIndex = NextIndex(iWriteIndex);
   388 		}
   389     /// Pop item from FIFO. Will PANIC with EFifoEmpty if empty 
   390 	T Pop()
   391 		{
   392 		if(IsEmpty())
   393 			{
   394 			Panic(EFifoEmpty);
   395 			}
   396 		TUint32 tmp = iReadIndex;
   397 		iReadIndex = NextIndex(iReadIndex);
   398 		return iFifo[tmp];
   399 		}
   400 
   401     /// Peek first item from FIFO. Will PANIC with EFifoEmpty if empty 
   402 	T Peek()
   403 		{
   404 		if(IsEmpty())
   405 			{
   406 			Panic(EFifoEmpty);
   407 			}
   408 		return iFifo[iReadIndex];
   409 		}
   410 	TUint Length() const
   411 		{
   412 		TUint len;
   413 		if(iWriteIndex >= iReadIndex)
   414 			{
   415 			len = iWriteIndex - iReadIndex;
   416 			}
   417 		else
   418 			{
   419 			len =  COUNT+1 - (iReadIndex - iWriteIndex);
   420 			}
   421 		return len;
   422 		}
   423 private:
   424 	TUint32 NextIndex(TUint32 aIndex) const
   425 		{
   426 		++aIndex;
   427 		aIndex %= (COUNT+1);
   428 		return aIndex;
   429 		}
   430 	T iFifo[COUNT+1];
   431 	TUint32 iWriteIndex;
   432 	TUint32 iReadIndex;
   433 	};
   434 
   435 
   436 
   437 //Body class for the adapter
   438 NONSHARABLE_CLASS( RMdaDevSound::CBody ): public CBase
   439 	{
   440 public:
   441 	//This class handles the play/record completions from the new sound driver
   442 	NONSHARABLE_CLASS( CPlayer ) : public CActive
   443 		{
   444 	public:
   445 		explicit CPlayer(TInt aPriority, RMdaDevSound::CBody& aParent, TInt aIndex);
   446 		~CPlayer();
   447 		void RunL();
   448 		TInt RunError(TInt aError);
   449 		void DoCancel();
   450 		void PlayData(TUint aChunkOffset, TInt aLength);
   451 
   452 		TUint GetPlayerIndex() const;
   453 
   454 	private:		
   455 		RMdaDevSound::CBody& iParent;
   456 		const TUint iIndex; // index of this object in parent
   457 		
   458 		TInt iBufferOffset;
   459 		TInt iBufferLength;
   460 		};
   461 
   462 	
   463 	NONSHARABLE_CLASS( CRecorder ) : public CActive
   464 		{
   465 	public:
   466 		explicit CRecorder(TInt aPriority, RMdaDevSound::CBody& aParent);
   467 		~CRecorder();
   468 		void RunL();
   469 		TInt RunError(TInt aError);
   470 		void DoCancel();
   471 		void RecordData(TInt& aLength);
   472 
   473 	private:		
   474 		RMdaDevSound::CBody& iParent;
   475 
   476 		TInt iBufferOffset;
   477 		TInt iBufferLength;
   478 		};
   479 	
   480 	enum TStateEnum
   481 		{
   482 		ENotReady,
   483 		EStopped,
   484 		ERecording,
   485 		ERecordingPausedInHw,
   486 		ERecordingPausedInSw,
   487 		EPlaying,
   488 		EPlayingPausedInHw, // ie. Play request pending on h/w and paused
   489 		EPlayingPausedInSw, // ie. Driver not playing or paused
   490 		EPlayingUnderrun
   491 		};
   492 
   493 	NONSHARABLE_CLASS( TState )
   494 		{
   495 		public:
   496 			TState(TStateEnum aState) : iState(aState) {}
   497 			const TText8 *Name() const;
   498 			TState &operator=(TStateEnum aNewState);
   499 			operator TStateEnum() const { return iState; }
   500 		private:
   501 			TStateEnum iState;
   502 		};
   503 		
   504 	class TFormatData
   505 		{
   506 	public:
   507 		inline TFormatData():
   508 			iSampleRate(8000), iRequestedChannels(1) // default
   509 			{
   510 			}
   511 	public:
   512 		CChannelAndSampleRateConverter* iConverter;
   513 		TInt iSampleRate;
   514 		TInt iActualRate;
   515 		TInt iRequestedChannels;
   516 		TInt iActualChannels;			
   517 		};
   518 		
   519 public:
   520 	~CBody();
   521 	static CBody* NewL();
   522 	TInt Open(TInt aUnit=KNullUnit);
   523 	TVersion VersionRequired() const;
   524 	TInt IsMdaSound();
   525 	void PlayFormatsSupported(TSoundFormatsSupportedBuf& aFormatsSupported);
   526 	void GetPlayFormat(TCurrentSoundFormatBuf& aFormat);
   527 	TInt SetPlayFormat(const TCurrentSoundFormatBuf& aFormat);
   528 	TInt PlayVolume();
   529 	void SetPlayVolume(TInt aVolume);
   530 	void SetVolume(TInt aLogarithmicVolume);
   531 	void CancelPlayData();
   532 	void RecordFormatsSupported(TSoundFormatsSupportedBuf& aFormatsSupported);
   533 	void GetRecordFormat(TCurrentSoundFormatBuf& aFormat);
   534 	TInt SetRecordFormat(const TCurrentSoundFormatBuf& aFormat);
   535 	TInt RecordLevel();
   536 	void SetRecordLevel(TInt aLevel);
   537 	void CancelRecordData();
   538 	void FlushRecordBuffer();
   539 	TInt BytesPlayed();
   540 	void ResetBytesPlayed();
   541 	void PausePlayBuffer();
   542 	void ResumePlaying();
   543 	void PauseRecordBuffer();
   544 	void ResumeRecording();
   545 	TInt GetTimePlayed(TTimeIntervalMicroSeconds& aTimePlayed);
   546 	void Close();
   547 	TInt Handle();
   548 	void PlayData(TRequestStatus& aStatus,const TDesC8& aData);
   549 	void RecordData(TRequestStatus& aStatus,TDes8& aData);
   550 	void NotifyRecordError(TRequestStatus& aStatus);
   551 	void NotifyPlayError(TRequestStatus& aStatus);
   552 	void CancelNotifyPlayError();
   553 	void CancelNotifyRecordError();
   554 	void FlushPlayBuffer();
   555 	//internal methods added to reduce the code
   556 	void FormatsSupported(TSoundFormatsSupportedBuf& aFormatsSupported, RSoundSc& aDevice);
   557 	void GetFormat(TCurrentSoundFormatBuf& aFormat, RSoundSc& aDevice, const TFormatData &aFormatData);
   558 	TInt SetFormat(const TCurrentSoundFormatBuf& aFormat, RSoundSc& aDevice, TFormatData &aFormatData);
   559 	
   560 	//for players
   561 	void SoundDeviceError(TInt aError);
   562 	RSoundSc& PlaySoundDevice();
   563 	RSoundSc& RecordSoundDevice();
   564 	const TState &State() const;
   565 	void BufferFilled(TInt aError);
   566 
   567 	// Called whenever a player becomes inactive.
   568 	// This includes driver request ok, driver request failed, CPlayer:::RunError invoked.
   569 	void PlayRequestHasCompleted(CPlayer *aPlayer, TInt aStatus, TBool aDueToCancelCommand);
   570 
   571 private:
   572 	CBody();
   573 	void ConstructL();
   574 	
   575 	TInt NegotiateFormat(const TCurrentSoundFormatBuf& aFormat, RSoundSc& aDevice, TFormatData &aFormatData);
   576 
   577 	void StartPlayersAndUpdateState();
   578 	void StartRecordRequest();
   579 
   580 	const char *StateName() const;
   581 
   582 	TBool InRecordMode() const;
   583 	TBool InPlayMode() const;
   584 
   585 	TUint32 CurrentTimeInMsec() const;
   586 	TUint64 BytesPlayed64();
   587 
   588 private:
   589 	RSoundSc iPlaySoundDevice;
   590 	RChunk iPlayChunk;//handle to the shared chunk
   591 	RSoundSc iRecordSoundDevice;
   592 	RChunk iRecordChunk;//handle to the shared chunk
   593 	TState iState;
   594 
   595 	//Playing Properties
   596 	TPlaySharedChunkBufConfig iPlayBufferConfig;
   597 	TInt iDeviceBufferLength;
   598 	
   599 	//Stores the status of CDataPathPlayer
   600 	TRequestStatus* iClientPlayStatus;
   601 	TPtrC8 iClientPlayData;
   602 	//Stores the status of CSoundDevPlayErrorReceiver
   603 	TRequestStatus* iClientPlayErrorStatus;
   604 	RBuf8 iConvertedPlayData;
   605 	RBuf8 iSavedTrailingData;
   606 
   607 	CPlayer* iPlayers[KPlaySharedChunkBuffers];
   608 	RFifo<CPlayer *, KPlaySharedChunkBuffers> iFreePlayers;
   609 	RFifo<TUint32, KPlaySharedChunkBuffers> iActivePlayRequestSizes;
   610 	
   611 	TInt iRequestMinSize;
   612 	TUint iRequestMinMask;
   613 	
   614 	//Recording Properties
   615 	TRecordSharedChunkBufConfig iRecordBufferConfig;
   616 	TInt iBufferOffset;
   617 	TInt iBufferLength;
   618 
   619 	//Stores the status of CDataPathRecorder
   620 	TRequestStatus* iClientRecordStatus;
   621 	//Stores the status of CSoundDevRecordErrorReceiver
   622 	TRequestStatus* iClientRecordErrorStatus;
   623 	TDes8* iClientRecordData;//stores the data pointer from datapath recorder
   624 	RBuf8 iBufferedRecordData; // Used if RSoundSc returns more data than current client request requires.
   625 
   626 	CRecorder* iRecorder; // We only need one recorder. The driver will buffer data for us.
   627 
   628 	TBool iUnderFlowReportedSinceLastPlayOrRecordRequest;
   629 	
   630 	TUint64 iBytesPlayed;
   631 	TUint32 iNTickPeriodInUsec;
   632 	TUint32 iStartTime; // Time when previous driver PlayData completed (or first was issued) in msec
   633 	TUint32 iPauseTime; // Time when pause started in msec
   634 	TUint64 iPausedBytesPlayed;
   635 
   636 	TFormatData iPlayFormatData;
   637 	TFormatData iRecordFormatData;
   638 	};
   639 #endif