os/mm/mmlibs/mmfw/src/Plugin/AudioInput/MmfAudioInput.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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