os/mm/devsound/devsoundrefplugin/src/platsec/server/AudioServer/MmfDevSoundSessionBody.inl
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2004-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 #include <mmf/server/mmfswcodecwrapper.h> //for SwCodecWrapper CustomInterfaces
    17 #include <mmf/server/mmfswcodecwrappercustominterfacesuids.hrh>
    18 #ifdef SYMBIAN_MULTIMEDIA_CODEC_API
    19 #include <mmf/server/mmfhwdevicesetup.h>
    20 #endif // SYMBIAN_MULTIMEDIA_CODEC_API
    21 #include "MmfDevSoundServer.h"
    22 #include "MmfDevSoundSessionBody.h"
    23 /*
    24  *
    25  *	Initializes DevSound object for the mode aMode for processing audio data
    26  *	with hardware device aHWDev.
    27  *
    28  *	On completion of Initialization, the observer will be notified via call back
    29  *	InitializeComplete().
    30  *
    31  *	Leaves on failure.
    32  *  
    33  *	@param	"MDevSoundObserver& aDevSoundObserver"
    34  *			A reference to DevSound Observer instance.
    35  *
    36  *	@param	"TUid aHWDev"
    37  *			CMMFHwDevice implementation identifier.
    38  *
    39  *	@param	"TMMFState aMode"
    40  *			Mode for which this object will be used.
    41  *
    42  */
    43  
    44  #ifdef _DEBUG
    45 _LIT(KMMFDevSoundSessionCategory, "MMFDevSoundSessionCategory");
    46 inline void Panic(TInt aError)
    47 	{
    48 	User::Panic(KMMFDevSoundSessionCategory, aError); 
    49 	}
    50 enum TMMFDevSoundSessionPanics
    51 	{
    52 	TMMFDevSoundSessionPolicyNotInvalidated
    53 	};
    54 #endif
    55  
    56 inline void CMMFDevSoundSvrImp::InitializeL(MDevSoundObserver& aDevSoundObserver, TUid aHWDev, TMMFState aMode)
    57 	{
    58 	TInt initError = KErrNone;
    59 	iDevSoundObserver = &aDevSoundObserver;
    60 
    61 	if (aMode == EMMFStateIdle)
    62 		User::Leave(KErrNotSupported);
    63 
    64 	iMode= static_cast<TMMFDevSoundState> (aMode);
    65 	iHasPolicy = EFalse;
    66 
    67 	if (iMode == EMMFDevSoundStateRecording)
    68 		{//DEF037912 incase the recording capabilities differ from play
    69 		User::LeaveIfError(InitializeFormat(iRecordFormatsSupported, iRecordFormat));
    70 		}
    71 
    72 
    73 	iDevSoundObserver = &aDevSoundObserver;
    74 	iHwDeviceID.iUid = aHWDev.iUid;
    75     if(iCMMFHwDevice)
    76 		{
    77 		delete iCMMFHwDevice;
    78 		iHwDeviceBuffer = NULL; // buffer is deleted by HwDevice delete
    79 		iPlayCustomInterface = NULL; //custom interfaces are also invalid
    80 		iRecordCustomInterface = NULL;
    81 		iTimePlayedCustomInterface = NULL;
    82 		}
    83     
    84     iCMMFHwDevice = NULL;
    85 
    86 	// Load the HwDevice implementation from ECom
    87     TRAP(initError,iCMMFHwDevice = CMMFHwDevice::NewL(aHWDev));//trap it to get debug print
    88 
    89 	if (initError == KErrNone)
    90 		{
    91 #ifdef SYMBIAN_MULTIMEDIA_CODEC_API
    92 		if (iFourCCSet)
    93 			{
    94 			MMdfHwDeviceSetup* setup = reinterpret_cast<MMdfHwDeviceSetup*>(iCMMFHwDevice->CustomInterface(KUidHwDeviceSetupInterface)); 
    95 			if (setup!=NULL)
    96 				{
    97 				setup->SetDataTypesL(iSrcFourCC, iDestFourCC);	
    98 				}
    99 			}
   100 #endif // SYMBIAN_MULTIMEDIA_CODEC_API
   101 		iDevInfo.iHwDeviceObserver = this;
   102 		initError = iCMMFHwDevice->Init(iDevInfo);
   103 		if (initError == KErrNone) 
   104 			{
   105 			TUid playCustomInterfaceUid;
   106 			playCustomInterfaceUid.iUid = KMmfPlaySettingsCustomInterface;
   107 			TUid recordCustomInterfaceUid;
   108 			recordCustomInterfaceUid.iUid = KMmfRecordSettingsCustomInterface;
   109 			iPlayCustomInterface = 
   110 				(MPlayCustomInterface*)iCMMFHwDevice->CustomInterface(playCustomInterfaceUid);
   111 			if (!iPlayCustomInterface) 
   112 				{//DEF40443 need to check custom interface has been created
   113 				initError = KErrNoMemory;//it won't if there is no memory
   114 				}
   115 			else
   116 				{
   117 				iRecordCustomInterface = 
   118 					(MRecordCustomInterface*)iCMMFHwDevice->CustomInterface(recordCustomInterfaceUid);
   119 				if (!iRecordCustomInterface) 
   120 					initError = KErrNoMemory;
   121 				}
   122 			}
   123 		}
   124 
   125 	// in the InitializeComplete() call we will signal the observer that the 
   126 	// custom interface may have changed
   127 	iDevSoundObserver->InitializeComplete(initError);  
   128 
   129 	if (initError)
   130 		{
   131 		User::Leave(initError);
   132 		}
   133 	__ASSERT_DEBUG(!(iHasPolicy&&(iMode == EMMFDevSoundStatePlaying)), Panic(TMMFDevSoundSessionPolicyNotInvalidated));
   134 	}
   135 
   136 /*
   137  *
   138  *	Initializes DevSound object for the mode aMode for processing audio data
   139  *	with hardware device supporting FourCC aDesiredFourCC.
   140  *
   141  *	On completion of Initialization, the observer will be notified via call back
   142  *	InitializeComplete().
   143  *
   144  *	Leaves on failure.
   145  *  
   146  *	@param	"MDevSoundObserver& aDevSoundObserver"
   147  *			A reference to DevSound Observer instance.
   148  *
   149  *	@param	"TFourCC aDesiredFourCC"
   150  *			CMMFHwDevice implementation FourCC.
   151  *
   152  *	@param	"TMMFState aMode"
   153  *			Mode for which this object will be used.
   154  *
   155  */
   156 inline void CMMFDevSoundSvrImp::InitializeL(MDevSoundObserver& aDevSoundObserver, TFourCC aDesiredFourCC, TMMFState aMode)
   157 	{
   158 	// to get HW Uid from the FourCC
   159 	RImplInfoPtrArray plugInArray;
   160 	TFourCC KPCM16FourCC(' ','P','1','6');
   161 	_LIT(KNullString, "");
   162 
   163 	TUid hwDevicePluginInterface = {KMmfUidPluginInterfaceHwDevice};
   164 	TUid implUid = {0};  
   165 	
   166 	CleanupResetAndDestroyPushL( plugInArray );
   167 	// Get the implementation UID based on the FourCC and mode.
   168 #ifdef SYMBIAN_MULTIMEDIA_CODEC_API
   169 	TInt err = KErrNone;
   170 	RArray<TFourCC> dataTypes;
   171 	CleanupClosePushL(dataTypes);
   172 	
   173 	TRAP(err, iDevSoundUtil->SeekCodecPluginsL(dataTypes, aMode, EFalse));
   174 	// if we find a new codec plugin
   175 	TBool found = EFalse;
   176 	if (!err && dataTypes.Find(aDesiredFourCC)!=KErrNotFound)
   177 		{
   178 		TRAP(err, iDevSoundUtil->FindHwDeviceAdapterL(hwDevicePluginInterface, plugInArray));
   179 		if (err == KErrNone)
   180 			{
   181 			if (aMode == EMMFDevSoundStatePlaying)
   182 				{//destination four CC is pcm16
   183 				iFourCCSet = ETrue;
   184 				iSrcFourCC = aDesiredFourCC;
   185 				iDestFourCC = KPCM16FourCC;
   186 				}
   187 			else if (aMode == EMMFDevSoundStateRecording)
   188 				{//source fourCC is pcm16
   189 				iFourCCSet = ETrue;
   190 				iSrcFourCC = KPCM16FourCC;
   191 				iDestFourCC = aDesiredFourCC;
   192 				}
   193 			found = ETrue;
   194 			}
   195 		}
   196 	if (!found)
   197 #endif // SYMBIAN_MULTIMEDIA_CODEC_API
   198 		{
   199 		plugInArray.ResetAndDestroy();
   200 		if (aMode == EMMFDevSoundStatePlaying)
   201 			{//destination four CC is pcm16
   202 			iFourCCSet = ETrue;
   203 			iSrcFourCC = aDesiredFourCC;
   204 			iDestFourCC = KPCM16FourCC;
   205 			iDevSoundUtil->SeekUsingFourCCL(hwDevicePluginInterface, plugInArray, aDesiredFourCC, KPCM16FourCC, KNullString);
   206 			}
   207 		else if (aMode == EMMFDevSoundStateRecording)
   208 			{//source fourCC is pcm16
   209 			iFourCCSet = ETrue;
   210 			iSrcFourCC = KPCM16FourCC;
   211 			iDestFourCC = aDesiredFourCC;
   212 			iDevSoundUtil->SeekUsingFourCCL(hwDevicePluginInterface, plugInArray, KPCM16FourCC, aDesiredFourCC, KNullString);
   213 			}
   214 		else 
   215 			{
   216 			User::Leave(KErrNotSupported);//invalid aMode cant set 4CC for tone
   217 			}
   218 		}
   219 	
   220 
   221 	if(plugInArray.Count() == 0)
   222 		{ // couldn't find Decoder only implementation, try to get Decoder/Encoder
   223 		iDevSoundUtil->SeekUsingFourCCL(hwDevicePluginInterface, plugInArray, aDesiredFourCC, aDesiredFourCC, KNullString);
   224 		if(plugInArray.Count() == 0)
   225 			User::Leave(KErrNotSupported);
   226 		}
   227 	implUid = plugInArray[0]->ImplementationUid(); // Just pick the first in the list
   228 
   229 #ifdef SYMBIAN_MULTIMEDIA_CODEC_API
   230 	CleanupStack::PopAndDestroy(2, &plugInArray) ;  //pluginArray, dataTypes
   231 #else
   232 	CleanupStack::PopAndDestroy() ;  //pluginArray
   233 #endif // SYMBIAN_MULTIMEDIA_CODEC_API
   234 	// If we made it here, there we have found implementation UID
   235 	InitializeL(aDevSoundObserver, implUid, aMode);
   236 	__ASSERT_DEBUG(!(iHasPolicy&&(iMode == EMMFDevSoundStatePlaying)), Panic(TMMFDevSoundSessionPolicyNotInvalidated)); 
   237 	}
   238 
   239 /*
   240  *
   241  *	Returns the supported Audio settings.
   242  *  
   243  *	@return	"TMMFCapabilities"
   244  *			Device settings.
   245  *
   246  */
   247 inline TMMFCapabilities CMMFDevSoundSvrImp::Capabilities()
   248 	{
   249 	return iDeviceCapabilities;
   250 	}
   251 
   252 /*
   253  *
   254  *	Returns the current audio settings.
   255  *  
   256  *	@return	"TMMFCapabilities"
   257  *			Device settings.
   258  *
   259  */
   260 inline TMMFCapabilities CMMFDevSoundSvrImp::Config() const
   261 	{
   262 	return iDeviceConfig;
   263 	}
   264 
   265 /*
   266  *
   267  *	Returns an integer representing the maximum volume.
   268  *
   269  *	This is the maximum value which can be passed to CMMFDevSoundProxy::SetVolume.
   270  *  
   271  *	@return	"TInt"
   272  *			The maximum volume. This value is platform dependent but is always
   273  *			greater than or equal to one.
   274  *
   275  */
   276 inline TInt CMMFDevSoundSvrImp::MaxVolume()
   277 	{
   278 	return iPlayFormatsSupported().iMaxVolume;
   279 	}
   280 
   281 /*
   282  *
   283  *	Returns an integer representing the current volume.
   284  * 
   285  *	@return	"TInt"
   286  *			The current volume level.
   287  *
   288  */
   289 inline TInt CMMFDevSoundSvrImp::Volume()
   290 	{
   291 	return iVolume;
   292 	}
   293 
   294 /*
   295  *
   296  *	Returns an integer representing the maximum gain.
   297  *
   298  *	This is the maximum value which can be passed to CMMFDevSoundProxy::SetGain.
   299  * 
   300  *	@return	"TInt"
   301  *			The maximum gain. This value is platform dependent but is always
   302  *			greater than or equal to one.
   303  *
   304  */
   305 inline TInt CMMFDevSoundSvrImp::MaxGain()
   306 	{
   307 	return iRecordFormatsSupported().iMaxVolume;//uses iMaxVolume for iMaxGain
   308 	}
   309 
   310 /*
   311  *
   312  *	Returns an integer representing the current gain.
   313  *
   314  *	@return	"TInt"
   315  *			The current gain level.
   316  *
   317  */
   318 inline TInt CMMFDevSoundSvrImp::Gain()
   319 	{
   320 	return iGain;
   321 	}
   322 
   323 /*
   324  *
   325  *	Returns the speaker balance set for playing.
   326  *
   327  *	Leaves on failure.
   328  *
   329  *	@param	"TInt& aLeftPrecentage"
   330  *			On return contains the left speaker volume percentage.
   331  *
   332  *	@param	"TInt& aRightPercentage"
   333  *			On return contains the right speaker volume percentage.
   334  *
   335  */
   336 inline void CMMFDevSoundSvrImp::GetPlayBalanceL(TInt& aLeftPercentage, TInt& aRightPercentage)
   337 	{
   338 	aLeftPercentage = iLeftPlayBalance;
   339 	aRightPercentage = iRightPlayBalance;
   340 	}
   341 
   342 /*
   343  *
   344  *	Returns the microphone gain balance set for recording.
   345  *
   346  *	Leaves on failure.
   347  *
   348  *	@param	"TInt& aLeftPercentage"
   349  *			On return contains the left microphone gain percentage.
   350  *
   351  *	@param	"TInt& aRightPercentage"
   352  *			On return contains the right microphone gain percentage.
   353  *
   354  */
   355 inline void CMMFDevSoundSvrImp::GetRecordBalanceL(TInt& aLeftPercentage, TInt& aRightPercentage)
   356 	{
   357 	aLeftPercentage = iLeftRecordBalance;
   358 	aRightPercentage = iRightRecordBalance;
   359 	}
   360 
   361 /*
   362  *
   363  *	Contine the process of recording. Once the buffer is filled with recorded
   364  *	data, the Observer gets reference to buffer along with callback
   365  *	BufferToBeEmptied(). After processing the buffer (copying over to a
   366  *	different buffer or writing to file) the client should call this
   367  *	method to continue recording process.
   368  *
   369  */
   370 inline TBool CMMFDevSoundSvrImp::RecordData(const RMmfIpcMessage& aMessage)
   371 	{
   372 	ASSERT(iDevSoundObserver);
   373 	if(iAudioPolicyPrioritySettings.iState != EMMFStateRecordData)
   374 		{
   375 		PanicClient(aMessage, EMMFDevSoundRecordDataWithoutInitialize);
   376 		return EFalse;
   377 		}
   378 	// Checkes if the client has a UserEnvironment capability
   379 	if (!aMessage.HasCapability(ECapabilityUserEnvironment))
   380 		{
   381 		iDevSoundObserver->RecordError(KErrPermissionDenied);
   382 		return ETrue;
   383 		}
   384 	if(iCMMFHwDevice)
   385 		{
   386 		if ((iMode == EMMFDevSoundStateRecording) && iHasPolicy)
   387 			{
   388 			iHwDeviceBuffer->Data().SetLength(iHwDeviceBuffer->RequestSize());
   389 			TInt error = iCMMFHwDevice->ThisHwBufferEmptied(*iHwDeviceBuffer);
   390 			if(error != KErrNone)
   391 				{
   392 				Error(error);
   393 				iCMMFHwDevice->Stop();
   394 				}
   395 
   396 			}
   397 		}
   398 	return ETrue;
   399 	}
   400 
   401 /*
   402  *
   403  *	Defines the number of times the audio is to be repeated during the tone
   404  *	playback operation.
   405  *
   406  *	A period of silence can follow each playing of tone. The tone playing can
   407  *	be repeated indefinitely.
   408  *
   409  *	@param	"TInt aRepeatCount"
   410  *			The number of times the tone, together with the trailing silence,
   411  *			is to be repeated. If this is set to KMdaRepeatForever, then the
   412  *			tone, together with the trailing silence, is repeated indefinitely
   413  *			or until Stop() is called. If this is set to zero, then the tone is
   414  *			not repeated.
   415  *
   416  *			Supported only during tone playing.
   417  *
   418  */
   419 inline void CMMFDevSoundSvrImp::SetToneRepeats(TInt aRepeatCount,
   420 				const TTimeIntervalMicroSeconds& aRepeatTrailingSilence)
   421 	{
   422 	iRepeatCount = aRepeatCount;
   423 	iRepeatTrailingSilence = aRepeatTrailingSilence;
   424 	}
   425 
   426 /*
   427  *
   428  *	Defines the priority settings that should be used for this instance.
   429  *
   430  *	@param	"const TMMFPrioritySettings& aPrioritySettings"
   431  *			An class type representing the client's priority, priority 
   432  *			preference and state.
   433  *
   434  */
   435 inline void CMMFDevSoundSvrImp::SetPrioritySettings(const TMMFPrioritySettings& aPrioritySettings)
   436 	{
   437 	iAudioPolicyPrioritySettings.iPref = aPrioritySettings.iPref;
   438 	iAudioPolicyPrioritySettings.iPriority = aPrioritySettings.iPriority;
   439 	}
   440 
   441 // Currently only support bitrate custom interface
   442 inline TAny* CMMFDevSoundSvrImp::CustomInterface(TUid aInterfaceId)
   443 	{
   444 	TAny* ptr = NULL;
   445 	if (iCMMFHwDevice)
   446 		{
   447 		ptr = iCMMFHwDevice->CustomInterface(aInterfaceId);	
   448 		}
   449 		
   450 	return ptr;	
   451 	}
   452 
   453 /*
   454  *
   455  *	Returns the number of available pre-defined tone sequences.
   456  *
   457  *	This is the number of fixed sequence supported by DevSound by default.
   458  *
   459  *	@return	"TInt"
   460  *			The fixed sequence count. This value is implementation dependent
   461  *			but is always greater than or equal to zero.
   462  *
   463  */
   464 inline TInt CMMFDevSoundSvrImp::FixedSequenceCount()
   465 	{
   466 	return iFixedSequences->Count();
   467 	}
   468 
   469 /*
   470  *
   471  *	Returns the name assigned to a specific pre-defined tone sequence.
   472  *
   473  *	This is the number of fixed sequence supported by DevSound by default.
   474  *
   475  *	The function raises a panic if sequence number specified invalid.
   476  *
   477  *	@return	"TDesC&"
   478  *			A reference to a Descriptor containing the fixed sequence
   479  *			name indexed by aSequenceNumber.
   480  *
   481  *	@param	"TInt aSequenceNumber"
   482  *			The index identifying the specific pre-defined tone sequence. Index
   483  *			values are relative to zero.
   484  *			This can be any value from zero to the value returned by a call to
   485  *			FixedSequenceCount() - 1.
   486  *			The function raises a panic if sequence number is not within this
   487  *			range.
   488  *
   489  *	@see	FixedSequenceCount()
   490  *
   491  */
   492 inline const TDesC& CMMFDevSoundSvrImp::FixedSequenceName(TInt aSequenceNumber)
   493 	{
   494 	ASSERT((aSequenceNumber >= 0)&&(aSequenceNumber < iFixedSequences->Count()));
   495 	return iDevSoundUtil->FixedSequenceName(aSequenceNumber);
   496 	}
   497 
   498 /*
   499  *
   500  *	Sets Id for this instance of DevSound
   501  *
   502  *	@param	"TInt aDevSoundId"
   503  *			Integer value assigned by Audio Policy Server
   504  *
   505  */
   506 inline void CMMFDevSoundSvrImp::SetDevSoundId(TInt aDevSoundId)
   507 	{
   508 	iDevSoundInfo.iDevSoundId = aDevSoundId;
   509 	}
   510 
   511 /*
   512  *
   513  *	Returns information about this DevSound instance.
   514  *
   515  *	This method is used by Audio Policy Server to make audio policy decisions.
   516  * 
   517  *	@return	"TMMFDevSoundinfo"
   518  *			A reference to TMMFDevSoundinfo object holding the current settings
   519  *			of this DevSound instance.
   520  *
   521  */
   522 inline TMMFDevSoundInfo CMMFDevSoundSvrImp::DevSoundInfo()
   523 	{
   524  	return iDevSoundInfo;
   525 	}
   526 
   527 
   528 /*
   529  *	Updates the total bytes played.
   530  *
   531  */
   532 inline void CMMFDevSoundSvrImp::UpdateBytesPlayed()
   533 	{
   534 	if (iPlayCustomInterface)
   535 		iPlayedBytesCount = iPlayCustomInterface->BytesPlayed();
   536 	}