mmlibs/mmfw/src/Plugin/AudioInput/MmfAudioInput.cpp
changeset 0 b8ed18f6c07b
equal deleted inserted replaced
-1:000000000000 0:b8ed18f6c07b
       
     1 // Copyright (c) 2002-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 "MmfAudioInput.h"
       
    17 #include <ecom/implementationproxy.h>
       
    18 #include <mmf/server/mmfformat.h>
       
    19 #include <mmf/plugin/mmfaudioiointerfaceuids.hrh>
       
    20 
       
    21 
       
    22 void Panic(TInt aPanicCode)
       
    23 	{
       
    24 	_LIT(KMMFAudioInputPanicCategory, "MMFAudioInput");
       
    25 	User::Panic(KMMFAudioInputPanicCategory, aPanicCode);
       
    26 	}
       
    27 
       
    28 /**
       
    29 Static standard SymbianOS 2 phase constuction method.
       
    30 
       
    31 Constucts this audio device.
       
    32 
       
    33 @return A pointer to a MDataSource returned on successful construction.
       
    34 */
       
    35 MDataSource* CMMFAudioInput::NewSourceL()
       
    36 	{
       
    37 	CMMFAudioInput* self = new (ELeave) CMMFAudioInput ;
       
    38 	CleanupStack::PushL(self);
       
    39 	self->ConstructL();
       
    40 	CleanupStack::Pop();
       
    41 	return  STATIC_CAST( MDataSource*, self );
       
    42 	}
       
    43 
       
    44 /**
       
    45 Standard SymbianOS ConstructL.
       
    46 
       
    47 Used to initialise member varibles with device specific behaviour.
       
    48 */
       
    49 void CMMFAudioInput::ConstructL()
       
    50 	{
       
    51 	iDataTypeCode = KMMFFourCCCodePCM16;
       
    52 	iActiveSchedulerWait = new(ELeave) CActiveSchedulerWait;
       
    53 	}
       
    54 
       
    55 /**
       
    56 Standard SymbianOS destructor.
       
    57 */
       
    58 CMMFAudioInput::~CMMFAudioInput()
       
    59 	{
       
    60 	delete iActiveSchedulerWait;
       
    61 	if (iMMFDevSound)
       
    62 		{
       
    63 		iMMFDevSound->Stop();
       
    64 		delete iMMFDevSound;
       
    65 		}
       
    66 	}
       
    67 
       
    68 
       
    69 /**
       
    70 Overridable constuctor specific to this datasource.
       
    71 
       
    72 @param  aInitData
       
    73         The initialisation data.
       
    74 */
       
    75 void CMMFAudioInput::ConstructSourceL( const TDesC8& /*aInitData*/ ) 
       
    76 	{
       
    77 	}
       
    78 
       
    79 /**
       
    80 @deprecated
       
    81 
       
    82 Gets audio from hardware device abstracted MMFDevsound (not used).
       
    83 
       
    84 @param  aBuffer
       
    85         The data to read in from a Hardware Device
       
    86 @param  aConsumer
       
    87         The MDataSink consuming the data contained in aBuffer.
       
    88 */
       
    89 void CMMFAudioInput::HWFillBufferL(CMMFBuffer* /*aBuffer*/, MDataSink* /*aConsumer*/)
       
    90 	{
       
    91 	}
       
    92 
       
    93 
       
    94 /**
       
    95 Gets audio from MMFDevsound.
       
    96 
       
    97 @pre
       
    98 iMMFDevSound must be loaded.
       
    99 
       
   100 @param  aBuffer
       
   101         The data to read in from a Devsound device.
       
   102 @param  aConsumer
       
   103         The MDataSink consuming the data contained in aBuffer.
       
   104 @param  aMediaId
       
   105         Type of data supplied - currently ignored.
       
   106 */
       
   107 void CMMFAudioInput::FillBufferL(CMMFBuffer* aBuffer, MDataSink* aConsumer, TMediaId /* aMediaId */)
       
   108 	{
       
   109 	iConsumer = aConsumer;
       
   110 
       
   111 	if (!iMMFDevSound)
       
   112 		Panic(EMMFAudioInputDevSoundNotLoaded);
       
   113 	
       
   114 	if ((iState == EPaused) && (iPausePending != EFalse) && (iFirstBufferRequested) )
       
   115   		{
       
   116   		User::Leave(KErrNotReady);
       
   117   		}
       
   118 
       
   119 	if ((aBuffer != NULL) && (!CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type())))
       
   120 		User::Leave(KErrNotSupported);
       
   121 
       
   122 	if (aConsumer == NULL)
       
   123 		User::Leave(KErrArgument);
       
   124 
       
   125 	//this is a one-shot "prime" funtion for MMFDevSound as first buffer is uninitialised
       
   126 	if (!iFirstBufferRequested)
       
   127 		{
       
   128 		iMMFDevSound->RecordInitL();
       
   129 		iFirstBufferRequested = ETrue;
       
   130 		return;
       
   131 		}
       
   132 
       
   133 	if (iState != EDevSoundReady && iState != EPaused)
       
   134 		{
       
   135 		User::Leave(KErrNotReady);
       
   136 		}
       
   137 
       
   138 	iMMFDevSound->RecordData();
       
   139 	}
       
   140 
       
   141 /**
       
   142 Indicates the data sink has emptied the buffer.
       
   143 
       
   144 Called by the data path's MDataSink when it has emptied the buffer.
       
   145 
       
   146 The default implementation is empty.
       
   147 
       
   148 @param  aBuffer
       
   149         The data buffer that has been emptied (not used).
       
   150 */
       
   151 void CMMFAudioInput::BufferEmptiedL(CMMFBuffer* /*aBuffer*/)
       
   152 	{
       
   153 	}
       
   154 
       
   155 
       
   156 /**
       
   157 Tests whether a source buffer can be created.
       
   158 
       
   159 The default imlpementation returns true.
       
   160 
       
   161 @return	A boolean indicating if the buffer can be made. ETrue if the buffer can be created, false
       
   162         otherwise.
       
   163 */
       
   164 TBool CMMFAudioInput::CanCreateSourceBuffer()
       
   165 	{
       
   166 	return ETrue;
       
   167 	}
       
   168 
       
   169 /**
       
   170 Creates a source buffer.
       
   171 
       
   172 Intended for asynchronous usage (buffers supplied by Devsound device)
       
   173 
       
   174 @param  aMediaId
       
   175 		The Media ID. Not used in the default implementation.
       
   176 @param  aReference
       
   177         A boolean indicating if MDataSource owns the buffer. ETrue if it does, EFalse if it does 
       
   178         not.
       
   179 
       
   180 @return The buffer created (this will always be NULL when asychronous).
       
   181 */
       
   182 CMMFBuffer* CMMFAudioInput::CreateSourceBufferL(TMediaId /*aMediaId*/, TBool &aReference)
       
   183 	{
       
   184 	CMMFDataBuffer* buf = NULL;
       
   185 
       
   186 	aReference = ETrue; // This is a reference from DevSound
       
   187 	return buf;
       
   188 	}
       
   189 
       
   190 /**
       
   191 Creates a source buffer.
       
   192 
       
   193 Intended for synchronous usage.
       
   194 
       
   195 @param  aMediaId
       
   196         The Media ID. Not used in the default implementation.
       
   197 
       
   198 @return The buffer created
       
   199 */
       
   200 CMMFBuffer* CMMFAudioInput::CreateSourceBufferL(TMediaId /*aMediaId*/)
       
   201 	{
       
   202 	CMMFDataBuffer* buf = CMMFDataBuffer::NewL(KAudioInputDefaultFrameSize);
       
   203 	return buf;
       
   204 	}
       
   205 
       
   206 
       
   207 /**
       
   208 Primes the source.
       
   209 
       
   210 This is a virtual function that each derived class must implement, but may be left blank for
       
   211 default behaviour.
       
   212 
       
   213 Overridable PrimeL method. Additional Prime method specific to this DataSource.
       
   214 */
       
   215 void CMMFAudioInput::SourcePrimeL()
       
   216 	{
       
   217 	iState = EDevSoundReady;
       
   218 	}
       
   219 
       
   220 /**
       
   221 Pauses the source.
       
   222 
       
   223 This is a virtual function that each derived class must implement, but may be left blank for default 
       
   224 behaviour.
       
   225 
       
   226 Overridable PauseL method. Additional Pause method specific to this DataSource.
       
   227 */
       
   228 void CMMFAudioInput::SourcePauseL()
       
   229 	{
       
   230 	if (iState == EDevSoundReady)
       
   231 		{//not waiting on a buffer being played so stop devsound now
       
   232 		iState = EPaused;
       
   233 		if (iFirstBufferRead)
       
   234 			{
       
   235 			if (!iMMFDevSound)
       
   236 				Panic(EMMFAudioInputDevSoundNotLoaded);
       
   237 			else
       
   238 				iMMFDevSound->Pause();
       
   239 			}
       
   240 		else
       
   241 			iPausePending = ETrue; // Wait for recording to get started.
       
   242 		}
       
   243 	//else if Devsound isn't ready then no point in stopping it
       
   244 	}
       
   245 
       
   246 
       
   247 /**
       
   248 Stops the source.
       
   249 
       
   250 This is a virtual function that each derived class must implement, but may be left blank for default 
       
   251 behaviour.
       
   252 
       
   253 Overridable StopL method. Additional Stop method specific to this DataSource.
       
   254 */
       
   255 void CMMFAudioInput::SourceStopL()
       
   256 	{
       
   257 	iStopped = ETrue;
       
   258 	// This is done in Audio Output as well, not sure whether its needed here or not.
       
   259 	// Pause will be called before SourceStopL() and pause will take care of closing
       
   260 	// DevSound
       
   261 	if (iState == EDevSoundReady  || iState == EPaused)
       
   262 		{//not waiting on a buffer being played so stop devsound now
       
   263 		iState = EIdle;
       
   264 		if (iFirstBufferRequested)
       
   265 			{
       
   266 			if (!iMMFDevSound)
       
   267 				Panic(EMMFAudioInputDevSoundNotLoaded);
       
   268 			else
       
   269 				{
       
   270 				iMMFDevSound->Stop();
       
   271 				}
       
   272 
       
   273 			iFirstBufferRequested = EFalse;
       
   274 			iFirstBufferRead = EFalse;
       
   275 			}
       
   276 		}
       
   277 	//else if Devsound isn't ready then no point in stopping it
       
   278 	}
       
   279 
       
   280 /**
       
   281 Plays the source.
       
   282 
       
   283 This is a virtual function that each derived class must implement, but may be left blank for default
       
   284 behaviour.
       
   285 
       
   286 Overridable PlayL method. Additional Play method specific to this DataSource.
       
   287 */
       
   288 void CMMFAudioInput::SourcePlayL()
       
   289 	{
       
   290 	}
       
   291 
       
   292 /**
       
   293 Logs on the source thread.
       
   294 
       
   295 Thread specific initialization procedure for this device. Runs automatically on thread construction.
       
   296 
       
   297 @param  aEventHandler
       
   298         The event handler.
       
   299 
       
   300 @return An error code indicating if the function call was successful. KErrNone on success, otherwise
       
   301         another of the system-wide error codes.
       
   302 */
       
   303 TInt CMMFAudioInput::SourceThreadLogon(MAsyncEventHandler& aEventHandler)
       
   304 	{
       
   305 	iEventHandler = &aEventHandler;
       
   306 	TInt err = KErrNone;
       
   307 	if (!iDevSoundLoaded)
       
   308 		TRAP(err, LoadL());
       
   309 	return err;
       
   310 	}
       
   311 
       
   312 /**
       
   313 Logs off the source thread.
       
   314 
       
   315 Thread specific destruction procedure for this device. Runs automatically on thread destruction.
       
   316 */
       
   317 void CMMFAudioInput::SourceThreadLogoff()
       
   318 	{
       
   319 	if(iMMFDevSound)
       
   320 		{
       
   321 		iMMFDevSound->Stop();
       
   322 		delete iMMFDevSound;
       
   323 		iMMFDevSound = NULL;
       
   324 		}
       
   325 	iDevSoundLoaded = EFalse;
       
   326 	iState = EIdle;
       
   327 	}
       
   328 
       
   329 /*
       
   330 @internaTechnology
       
   331 
       
   332 @pre
       
   333 dev sound should be created and loaded.
       
   334 */
       
   335 void CMMFAudioInput::ConfigDevSoundL()
       
   336 	{
       
   337 	//[precondition dev sound created ]
       
   338 	ASSERT( iMMFDevSound );
       
   339 
       
   340 	// Query DevSound capabilities and Try to use DevSound sample rate and 
       
   341 	// mono/stereo capability
       
   342 	TMMFCapabilities devSoundCaps = iMMFDevSound->Capabilities();
       
   343 	// get current config
       
   344 	TMMFCapabilities devSoundConfig = iMMFDevSound->Config();
       
   345 
       
   346 	// Default PCM16
       
   347 	devSoundConfig.iEncoding = EMMFSoundEncoding16BitPCM;
       
   348 
       
   349 	// 1 = Monophonic and 2 == Stereo
       
   350 	if (((iSinkChannels == 1) && (devSoundCaps.iChannels & EMMFMono)) ||
       
   351 		((iSinkChannels == 2) && (devSoundCaps.iChannels & EMMFStereo)))
       
   352 		devSoundConfig.iChannels = iSinkChannels;
       
   353 
       
   354 
       
   355 	// Check for std sample rates.
       
   356 	if ((iSinkSampleRate == 96000) && (devSoundCaps.iRate & EMMFSampleRate96000Hz))
       
   357 		devSoundConfig.iRate = EMMFSampleRate96000Hz;
       
   358 	else if ((iSinkSampleRate == 88200) && (devSoundCaps.iRate & EMMFSampleRate88200Hz))
       
   359 		devSoundConfig.iRate = EMMFSampleRate88200Hz;
       
   360 	else if ((iSinkSampleRate == 64000) && (devSoundCaps.iRate & EMMFSampleRate64000Hz))
       
   361 		devSoundConfig.iRate = EMMFSampleRate64000Hz;
       
   362 	else if ((iSinkSampleRate == 48000) && (devSoundCaps.iRate & EMMFSampleRate48000Hz))
       
   363 		devSoundConfig.iRate = EMMFSampleRate48000Hz;
       
   364 	else if ((iSinkSampleRate == 44100) && (devSoundCaps.iRate & EMMFSampleRate44100Hz))
       
   365 		devSoundConfig.iRate = EMMFSampleRate44100Hz;
       
   366 	else if ((iSinkSampleRate == 32000) && (devSoundCaps.iRate & EMMFSampleRate32000Hz))
       
   367 		devSoundConfig.iRate = EMMFSampleRate32000Hz;
       
   368 	else if ((iSinkSampleRate == 24000) && (devSoundCaps.iRate & EMMFSampleRate24000Hz))
       
   369 		devSoundConfig.iRate = EMMFSampleRate24000Hz;
       
   370 	else if ((iSinkSampleRate == 22050) && (devSoundCaps.iRate & EMMFSampleRate22050Hz))
       
   371 		devSoundConfig.iRate = EMMFSampleRate22050Hz;
       
   372 	else if ((iSinkSampleRate == 16000) && (devSoundCaps.iRate & EMMFSampleRate16000Hz))
       
   373 		devSoundConfig.iRate = EMMFSampleRate16000Hz;
       
   374 	else if ((iSinkSampleRate == 12000) && (devSoundCaps.iRate & EMMFSampleRate12000Hz))
       
   375 		devSoundConfig.iRate = EMMFSampleRate12000Hz;
       
   376 	else if ((iSinkSampleRate == 11025) && (devSoundCaps.iRate & EMMFSampleRate11025Hz))
       
   377 		devSoundConfig.iRate = EMMFSampleRate11025Hz;
       
   378 	else if ((iSinkSampleRate == 8000) && (devSoundCaps.iRate & EMMFSampleRate8000Hz))
       
   379 		devSoundConfig.iRate = EMMFSampleRate8000Hz; 
       
   380 	else 
       
   381 		{
       
   382 		// pick the maximum sample rate available
       
   383 		if (devSoundCaps.iRate & EMMFSampleRate96000Hz)
       
   384 			devSoundConfig.iRate = EMMFSampleRate96000Hz;
       
   385 		else if (devSoundCaps.iRate & EMMFSampleRate88200Hz)
       
   386 			devSoundConfig.iRate = EMMFSampleRate88200Hz;
       
   387 		else if (devSoundCaps.iRate & EMMFSampleRate64000Hz)
       
   388 			devSoundConfig.iRate = EMMFSampleRate64000Hz;
       
   389 		else if (devSoundCaps.iRate & EMMFSampleRate48000Hz)
       
   390 			devSoundConfig.iRate = EMMFSampleRate48000Hz;
       
   391 		else if (devSoundCaps.iRate & EMMFSampleRate44100Hz)
       
   392 			devSoundConfig.iRate = EMMFSampleRate44100Hz;
       
   393 		else if (devSoundCaps.iRate & EMMFSampleRate32000Hz)
       
   394 			devSoundConfig.iRate = EMMFSampleRate32000Hz;
       
   395 		else if (devSoundCaps.iRate & EMMFSampleRate24000Hz)
       
   396 			devSoundConfig.iRate = EMMFSampleRate24000Hz;
       
   397 		else if (devSoundCaps.iRate & EMMFSampleRate22050Hz)
       
   398 			devSoundConfig.iRate = EMMFSampleRate22050Hz;
       
   399 		else if (devSoundCaps.iRate & EMMFSampleRate16000Hz)
       
   400 			devSoundConfig.iRate = EMMFSampleRate16000Hz;
       
   401 		else if (devSoundCaps.iRate & EMMFSampleRate12000Hz)
       
   402 			devSoundConfig.iRate = EMMFSampleRate12000Hz;
       
   403 		else if (devSoundCaps.iRate & EMMFSampleRate11025Hz)
       
   404 			devSoundConfig.iRate = EMMFSampleRate11025Hz;
       
   405 		else if (devSoundCaps.iRate & EMMFSampleRate8000Hz)
       
   406 			devSoundConfig.iRate = EMMFSampleRate8000Hz;
       
   407 		else
       
   408 			ASSERT(EFalse); // if we don't support any sample rates, there is not much we can do
       
   409 		
       
   410 		}
       
   411 
       
   412 	iMMFDevSound->SetConfigL(devSoundConfig);
       
   413 	}
       
   414 
       
   415 /**
       
   416 Negotiates with the sink.
       
   417 
       
   418 Called if the source's setup depends on sink.
       
   419 
       
   420 @param  aSink
       
   421         The Data sink. Takes an MDataSink reference so a DataSource can negotiate with this
       
   422         MDataSource.
       
   423 */
       
   424 void CMMFAudioInput::NegotiateSourceL(MDataSink& aSink)
       
   425 	{
       
   426 	if (aSink.DataSinkType() == KUidMmfFormatEncode) 
       
   427 		{//sink is a clip so for now set sink settings to match sink
       
   428 		iSinkSampleRate = ((CMMFFormatEncode&)aSink).SampleRate(); 
       
   429 		iSinkChannels = ((CMMFFormatEncode&)aSink).NumChannels();
       
   430 		iSinkFourCC.Set(aSink.SinkDataTypeCode(TMediaId(KUidMediaTypeAudio)));
       
   431 
       
   432 		// if the sink's sample rate is undefined, try to obtain and use a
       
   433 		// default sample rate from the sink. If this is zero, use 8K
       
   434 		if (iSinkSampleRate == 0)
       
   435 			{
       
   436 			iSinkSampleRate = ((CMMFFormatEncode&)aSink).GetDefaultSampleRate(); 
       
   437 			if (iSinkSampleRate == 0)
       
   438 				iSinkSampleRate = 8000;
       
   439 			}
       
   440 		
       
   441 		}
       
   442 
       
   443 	if (iMMFDevSound == NULL)
       
   444   		User::Leave(KErrNotReady);
       
   445 
       
   446 	TMMFState prioritySettingsState = iPrioritySettings.iState; //should be EMMFStateRecording
       
   447 	//to use the GetSupportedOutputDatatypes but we'll save it just in case it's not
       
   448 	iPrioritySettings.iState = EMMFStateRecording; //if playing does not support any output data types
       
   449 	RArray<TFourCC> supportedDataTypes;
       
   450 	//note Output data types becuase if we are recording audio ie audio input
       
   451 	//the data is sent as an output from DevSound
       
   452 	TRAPD(err, iMMFDevSound->GetSupportedOutputDataTypesL(supportedDataTypes, iPrioritySettings));
       
   453 	iPrioritySettings.iState = prioritySettingsState;
       
   454 	if (err == KErrNone)
       
   455 		{
       
   456 		if (supportedDataTypes.Find(iSinkFourCC) == KErrNotFound)
       
   457 			{//the source fourCC code could not be found in the list of 
       
   458 			//data types supported by the Devsound therefor default to pcm16
       
   459 			iDataTypeCode = KMMFFourCCCodePCM16;	
       
   460 			}
       
   461 		else
       
   462 			{
       
   463 			//the DevSound does support the same datatype as the source 
       
   464 			//so set the fourcc to that of the source
       
   465 			iDataTypeCode = iSinkFourCC;
       
   466 			}
       
   467 		}
       
   468 	supportedDataTypes.Close();
       
   469 	if (err == KErrNotSupported)
       
   470 		{//if the Devsound does not support the GetSupportedOutputDataTypesL method
       
   471 		//then assume that the DevSound is pcm16 only
       
   472 		iDataTypeCode = KMMFFourCCCodePCM16;	
       
   473 		}
       
   474 	else if (err != KErrNone) //we had a real leave error from GetSupportedOuputDataTypesL
       
   475 		{
       
   476 		User::Leave(err);
       
   477 		}
       
   478 
       
   479     // Prevent defect when SourcePrimeL is called before NegotiateSourceL()
       
   480 	// since characterization is ambiguous
       
   481     if(iState == EDevSoundReady)
       
   482       {
       
   483       iState = EIdle;
       
   484       }
       
   485 
       
   486   	// moved from LoadL - fix for DEF037168 - AD
       
   487 	iMMFDevSound->InitializeL(*this, iDataTypeCode, EMMFStateRecording);
       
   488 
       
   489 	// In some implementations InitializeComplete is sent
       
   490 	// in context, so check before starting activeSchedulerWait.
       
   491 	if (iState != EDevSoundReady)
       
   492 		{
       
   493 		iInitializeState = KRequestPending;
       
   494 		iActiveSchedulerWait->Start();
       
   495 		}		
       
   496 	User::LeaveIfError(iInitializeState);
       
   497 
       
   498 	iMMFDevSound->SetPrioritySettings(iPrioritySettings);
       
   499 
       
   500 	// Attempt to configure DevSound to the same settings as the sink.
       
   501 	// Need to do this after calling CMMFDevSound::InitializeL() as
       
   502 	// this sets up the device capabilities 
       
   503 	// (returned by iMMFDevSound->Capabilities()).
       
   504 	ConfigDevSoundL();
       
   505 	}
       
   506 
       
   507 /**
       
   508 Sets the source's priority settings.
       
   509 
       
   510 @param  aPrioritySettings
       
   511         The source priority settings. Takes enumerations to determine audio record priority. Higher 
       
   512         numbers mean high priority (can interrupt lower priorities).
       
   513 */
       
   514 void CMMFAudioInput::SetSourcePrioritySettings(const TMMFPrioritySettings& aPrioritySettings)
       
   515 	{
       
   516 	iPrioritySettings = aPrioritySettings;
       
   517 	if (!iMMFDevSound)
       
   518 		Panic(EMMFAudioInputDevSoundNotLoaded);
       
   519 	else
       
   520 		iMMFDevSound->SetPrioritySettings(iPrioritySettings);
       
   521 	}
       
   522 
       
   523 
       
   524 /**
       
   525 Gets the data type code for the source specified by the media ID.
       
   526 
       
   527 @param  aMediaId
       
   528         An optional parameter to specifiy a specific stream when the datasource contains more than
       
   529         one stream of data.
       
   530 
       
   531 @return The 4CC of the data supplied by this source.
       
   532 */
       
   533 TFourCC CMMFAudioInput::SourceDataTypeCode(TMediaId /*aMediaId*/)
       
   534 	{
       
   535 	return iDataTypeCode;
       
   536 	}
       
   537 
       
   538 /**
       
   539 Sets the data type code for the source.
       
   540 
       
   541 @param  aSourceFourCC
       
   542         The 4CC of the data supplied by this source.
       
   543 @param  aMediaId
       
   544         The Media ID. An optional parameter to specifiy specific stream when datasource contains
       
   545         more than one stream of data.
       
   546 
       
   547 @return An error code indicating if the function call was successful. KErrNone on success, otherwise
       
   548         another of the system-wide error codes.
       
   549 */
       
   550 TInt CMMFAudioInput::SetSourceDataTypeCode(TFourCC aSourceFourCC, TMediaId /*aMediaId*/)
       
   551 	{
       
   552 	iDataTypeCode = aSourceFourCC;
       
   553 	return KErrNone;
       
   554 	}
       
   555 
       
   556 /**
       
   557 Gets the number of bytes played.
       
   558 
       
   559 @return	The number of bytes played. If 16-bit divide this number returned by 2 to get word length.
       
   560 */
       
   561 TInt CMMFAudioInput::BytesPlayed()
       
   562 	{
       
   563 	if (!iMMFDevSound)
       
   564 		Panic(EMMFAudioInputDevSoundNotLoaded);
       
   565 	return iMMFDevSound->SamplesPlayed();
       
   566 	}
       
   567 
       
   568 /**
       
   569 Returns the sound device.
       
   570 
       
   571 @pre
       
   572 Dev Sound should be loaded.
       
   573 
       
   574 Accessor function exposing public CMMFDevsound methods.
       
   575 
       
   576 @return A reference to a CMMFDevSound objector.
       
   577 */
       
   578 CMMFDevSound& CMMFAudioInput::SoundDevice()
       
   579 	{
       
   580 	if (!iMMFDevSound)
       
   581 		{
       
   582 		Panic(EMMFAudioInputDevSoundNotLoaded);
       
   583 		}
       
   584 	return *iMMFDevSound;
       
   585 	}
       
   586 
       
   587 
       
   588 /**
       
   589 @deprecated
       
   590 
       
   591 This method should not be used - it is provided to maintain SC with v7.0s.
       
   592 
       
   593 @param  aAudioType
       
   594         The 4CC of the data supplied by this source.
       
   595 */
       
   596 void CMMFAudioInput::SetDataTypeL(TFourCC aAudioType)
       
   597 	{
       
   598 	if (aAudioType != KMMFFourCCCodePCM16)
       
   599 		{
       
   600 		User::Leave(KErrNotSupported);
       
   601 		}
       
   602 	}	
       
   603 
       
   604 
       
   605 /**
       
   606 @deprecated
       
   607 
       
   608 This method should not be used - it is provided to maintain SC with v7.0s.
       
   609 
       
   610 @return The 4CC of the data supplied by this source.
       
   611 */
       
   612 TFourCC CMMFAudioInput::DataType() const
       
   613 	{
       
   614 	return KMMFFourCCCodePCM16;
       
   615 	}
       
   616 
       
   617 
       
   618 /**
       
   619 Loads audio device drivers and initialise this device.
       
   620 */
       
   621 void CMMFAudioInput::LoadL()
       
   622 	{
       
   623 	//[ do all the work that can fail first
       
   624 	// before we modify the internal state ]
       
   625 
       
   626 	iMMFDevSound = CMMFDevSound::NewL();
       
   627 	iFirstBufferRequested = EFalse;
       
   628 	iFirstBufferRead = EFalse;
       
   629 	if (iState != EDevSoundReady) 
       
   630 		{
       
   631 		iState = EIdle;
       
   632 		}
       
   633 
       
   634 	iDevSoundLoaded = ETrue;
       
   635 
       
   636 	//[ assert dev sound has been constructed]
       
   637 	ASSERT( iMMFDevSound );
       
   638 	ASSERT( iDevSoundLoaded );
       
   639     ASSERT( !iFirstBufferRead );
       
   640 	}
       
   641 
       
   642 void CMMFAudioInput::DeviceMessage(TUid /*aMessageType*/, const TDesC8& /* aMsg */)
       
   643 	{
       
   644 	}
       
   645 
       
   646 void CMMFAudioInput::InitializeComplete(TInt aError)
       
   647 	{
       
   648 	if (aError == KErrNone)
       
   649 		{
       
   650 		iState = EDevSoundReady;
       
   651 		}
       
   652 
       
   653 	if(iInitializeState == KRequestPending)
       
   654 		{
       
   655 		iInitializeState = aError;
       
   656 		iActiveSchedulerWait->AsyncStop();
       
   657 		}
       
   658 	}
       
   659 
       
   660 	
       
   661 /**
       
   662 ToneFinished MMFDevSoundObserver - should never get called.
       
   663 */
       
   664 void CMMFAudioInput::ToneFinished(TInt /*aError*/)
       
   665 	{
       
   666 	//we should never get here during a record session!
       
   667 	__ASSERT_DEBUG(EFalse,Panic(EMMFAudioInputPanicToneFinishedNotSupported));
       
   668 	}
       
   669 
       
   670 
       
   671 /**
       
   672 BuffferToBeEmptied MMFDevSoundObserver
       
   673 Called when stopped due to error.
       
   674 */
       
   675 void CMMFAudioInput::BufferToBeEmptied(CMMFBuffer* aBuffer)
       
   676 	{
       
   677 	iDevSoundBuf = aBuffer;
       
   678 
       
   679 	if (iFirstBufferRequested)
       
   680 		{
       
   681 		if (iPausePending)
       
   682 			{
       
   683 			aBuffer->SetLastBuffer(ETrue);
       
   684 			iPausePending = EFalse;
       
   685 			}
       
   686 
       
   687 #ifdef _DEBUG
       
   688 		TRAPD(err, iConsumer->BufferFilledL(aBuffer));
       
   689 		__ASSERT_DEBUG(!err, Panic(err));
       
   690 #else
       
   691 		TRAP_IGNORE(iConsumer->BufferFilledL(aBuffer));
       
   692 #endif
       
   693 
       
   694 		iFirstBufferRead = ETrue;
       
   695 		}
       
   696 	}	
       
   697 
       
   698 
       
   699 /**
       
   700 RecordError MMFDevSoundObserver
       
   701 Called when stopped due to error.
       
   702 */
       
   703 void CMMFAudioInput::RecordError(TInt aError)
       
   704 	{
       
   705 	//[  two event categories will be used
       
   706 	// which mirrors the datapath response ]
       
   707 
       
   708 	//[ record the error ]
       
   709 	iMMFDevsoundError = aError;
       
   710 	TMMFEvent event( KMMFEventCategoryPlaybackComplete, aError);
       
   711 	
       
   712 	//[ send the event to the client.
       
   713 	SendEventToClient(event);    
       
   714 	
       
   715 	// clear flags if there is an error.
       
   716 	iPausePending = EFalse;
       
   717 
       
   718 	//[ we are not going to stop devsound ]
       
   719 	}
       
   720 
       
   721 
       
   722 /**
       
   723 BufferToBeFilled MMFDevSoundObserver - should never get called.
       
   724 */
       
   725 void CMMFAudioInput::BufferToBeFilled(CMMFBuffer* /*aBuffer*/)
       
   726 	{
       
   727 	//we should never get here during a play session!
       
   728 	__ASSERT_DEBUG(EFalse, Panic(EMMFAudioInputPanicPlayerDataUsedNotSupported));
       
   729 	}
       
   730 
       
   731 
       
   732 /**
       
   733 PlayError MMFDevSoundObserver - should never get called.
       
   734 */
       
   735 void CMMFAudioInput::PlayError(TInt /*aError*/)
       
   736 	{
       
   737 	//we should never get here during a record session!
       
   738 	__ASSERT_DEBUG(EFalse, Panic(EMMFAudioInputPanicPlayErrorNotSupported));
       
   739 	}
       
   740 
       
   741 
       
   742 /**
       
   743 ConvertError MMFDevSoundObserver - should never get called.
       
   744 */
       
   745 void CMMFAudioInput::ConvertError(TInt /*aError*/)
       
   746 	{
       
   747 	}
       
   748 
       
   749 
       
   750 void CMMFAudioInput::SendEventToClient(const TMMFEvent& aEvent)
       
   751 	{
       
   752 	iEventHandler->SendEventToClient(aEvent);
       
   753 	}
       
   754 
       
   755 // _________________________________________________________________________
       
   756 // Exported proxy for instantiation method resolution
       
   757 // Define the interface UIDs
       
   758 
       
   759 const TImplementationProxy ImplementationTable[] = 
       
   760 	{
       
   761 		IMPLEMENTATION_PROXY_ENTRY(KMmfUidAudioInputInterface,	CMMFAudioInput::NewSourceL)
       
   762 	};
       
   763 
       
   764 EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
       
   765 	{
       
   766 	aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
       
   767 
       
   768 	return ImplementationTable;
       
   769 	}
       
   770