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