1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/mm/mmlibs/mmfw/src/Plugin/AudioInput/MmfAudioInput.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,770 @@
1.4 +// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +#include "MmfAudioInput.h"
1.20 +#include <ecom/implementationproxy.h>
1.21 +#include <mmf/server/mmfformat.h>
1.22 +#include <mmf/plugin/mmfaudioiointerfaceuids.hrh>
1.23 +
1.24 +
1.25 +void Panic(TInt aPanicCode)
1.26 + {
1.27 + _LIT(KMMFAudioInputPanicCategory, "MMFAudioInput");
1.28 + User::Panic(KMMFAudioInputPanicCategory, aPanicCode);
1.29 + }
1.30 +
1.31 +/**
1.32 +Static standard SymbianOS 2 phase constuction method.
1.33 +
1.34 +Constucts this audio device.
1.35 +
1.36 +@return A pointer to a MDataSource returned on successful construction.
1.37 +*/
1.38 +MDataSource* CMMFAudioInput::NewSourceL()
1.39 + {
1.40 + CMMFAudioInput* self = new (ELeave) CMMFAudioInput ;
1.41 + CleanupStack::PushL(self);
1.42 + self->ConstructL();
1.43 + CleanupStack::Pop();
1.44 + return STATIC_CAST( MDataSource*, self );
1.45 + }
1.46 +
1.47 +/**
1.48 +Standard SymbianOS ConstructL.
1.49 +
1.50 +Used to initialise member varibles with device specific behaviour.
1.51 +*/
1.52 +void CMMFAudioInput::ConstructL()
1.53 + {
1.54 + iDataTypeCode = KMMFFourCCCodePCM16;
1.55 + iActiveSchedulerWait = new(ELeave) CActiveSchedulerWait;
1.56 + }
1.57 +
1.58 +/**
1.59 +Standard SymbianOS destructor.
1.60 +*/
1.61 +CMMFAudioInput::~CMMFAudioInput()
1.62 + {
1.63 + delete iActiveSchedulerWait;
1.64 + if (iMMFDevSound)
1.65 + {
1.66 + iMMFDevSound->Stop();
1.67 + delete iMMFDevSound;
1.68 + }
1.69 + }
1.70 +
1.71 +
1.72 +/**
1.73 +Overridable constuctor specific to this datasource.
1.74 +
1.75 +@param aInitData
1.76 + The initialisation data.
1.77 +*/
1.78 +void CMMFAudioInput::ConstructSourceL( const TDesC8& /*aInitData*/ )
1.79 + {
1.80 + }
1.81 +
1.82 +/**
1.83 +@deprecated
1.84 +
1.85 +Gets audio from hardware device abstracted MMFDevsound (not used).
1.86 +
1.87 +@param aBuffer
1.88 + The data to read in from a Hardware Device
1.89 +@param aConsumer
1.90 + The MDataSink consuming the data contained in aBuffer.
1.91 +*/
1.92 +void CMMFAudioInput::HWFillBufferL(CMMFBuffer* /*aBuffer*/, MDataSink* /*aConsumer*/)
1.93 + {
1.94 + }
1.95 +
1.96 +
1.97 +/**
1.98 +Gets audio from MMFDevsound.
1.99 +
1.100 +@pre
1.101 +iMMFDevSound must be loaded.
1.102 +
1.103 +@param aBuffer
1.104 + The data to read in from a Devsound device.
1.105 +@param aConsumer
1.106 + The MDataSink consuming the data contained in aBuffer.
1.107 +@param aMediaId
1.108 + Type of data supplied - currently ignored.
1.109 +*/
1.110 +void CMMFAudioInput::FillBufferL(CMMFBuffer* aBuffer, MDataSink* aConsumer, TMediaId /* aMediaId */)
1.111 + {
1.112 + iConsumer = aConsumer;
1.113 +
1.114 + if (!iMMFDevSound)
1.115 + Panic(EMMFAudioInputDevSoundNotLoaded);
1.116 +
1.117 + if ((iState == EPaused) && (iPausePending != EFalse) && (iFirstBufferRequested) )
1.118 + {
1.119 + User::Leave(KErrNotReady);
1.120 + }
1.121 +
1.122 + if ((aBuffer != NULL) && (!CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type())))
1.123 + User::Leave(KErrNotSupported);
1.124 +
1.125 + if (aConsumer == NULL)
1.126 + User::Leave(KErrArgument);
1.127 +
1.128 + //this is a one-shot "prime" funtion for MMFDevSound as first buffer is uninitialised
1.129 + if (!iFirstBufferRequested)
1.130 + {
1.131 + iMMFDevSound->RecordInitL();
1.132 + iFirstBufferRequested = ETrue;
1.133 + return;
1.134 + }
1.135 +
1.136 + if (iState != EDevSoundReady && iState != EPaused)
1.137 + {
1.138 + User::Leave(KErrNotReady);
1.139 + }
1.140 +
1.141 + iMMFDevSound->RecordData();
1.142 + }
1.143 +
1.144 +/**
1.145 +Indicates the data sink has emptied the buffer.
1.146 +
1.147 +Called by the data path's MDataSink when it has emptied the buffer.
1.148 +
1.149 +The default implementation is empty.
1.150 +
1.151 +@param aBuffer
1.152 + The data buffer that has been emptied (not used).
1.153 +*/
1.154 +void CMMFAudioInput::BufferEmptiedL(CMMFBuffer* /*aBuffer*/)
1.155 + {
1.156 + }
1.157 +
1.158 +
1.159 +/**
1.160 +Tests whether a source buffer can be created.
1.161 +
1.162 +The default imlpementation returns true.
1.163 +
1.164 +@return A boolean indicating if the buffer can be made. ETrue if the buffer can be created, false
1.165 + otherwise.
1.166 +*/
1.167 +TBool CMMFAudioInput::CanCreateSourceBuffer()
1.168 + {
1.169 + return ETrue;
1.170 + }
1.171 +
1.172 +/**
1.173 +Creates a source buffer.
1.174 +
1.175 +Intended for asynchronous usage (buffers supplied by Devsound device)
1.176 +
1.177 +@param aMediaId
1.178 + The Media ID. Not used in the default implementation.
1.179 +@param aReference
1.180 + A boolean indicating if MDataSource owns the buffer. ETrue if it does, EFalse if it does
1.181 + not.
1.182 +
1.183 +@return The buffer created (this will always be NULL when asychronous).
1.184 +*/
1.185 +CMMFBuffer* CMMFAudioInput::CreateSourceBufferL(TMediaId /*aMediaId*/, TBool &aReference)
1.186 + {
1.187 + CMMFDataBuffer* buf = NULL;
1.188 +
1.189 + aReference = ETrue; // This is a reference from DevSound
1.190 + return buf;
1.191 + }
1.192 +
1.193 +/**
1.194 +Creates a source buffer.
1.195 +
1.196 +Intended for synchronous usage.
1.197 +
1.198 +@param aMediaId
1.199 + The Media ID. Not used in the default implementation.
1.200 +
1.201 +@return The buffer created
1.202 +*/
1.203 +CMMFBuffer* CMMFAudioInput::CreateSourceBufferL(TMediaId /*aMediaId*/)
1.204 + {
1.205 + CMMFDataBuffer* buf = CMMFDataBuffer::NewL(KAudioInputDefaultFrameSize);
1.206 + return buf;
1.207 + }
1.208 +
1.209 +
1.210 +/**
1.211 +Primes the source.
1.212 +
1.213 +This is a virtual function that each derived class must implement, but may be left blank for
1.214 +default behaviour.
1.215 +
1.216 +Overridable PrimeL method. Additional Prime method specific to this DataSource.
1.217 +*/
1.218 +void CMMFAudioInput::SourcePrimeL()
1.219 + {
1.220 + iState = EDevSoundReady;
1.221 + }
1.222 +
1.223 +/**
1.224 +Pauses the source.
1.225 +
1.226 +This is a virtual function that each derived class must implement, but may be left blank for default
1.227 +behaviour.
1.228 +
1.229 +Overridable PauseL method. Additional Pause method specific to this DataSource.
1.230 +*/
1.231 +void CMMFAudioInput::SourcePauseL()
1.232 + {
1.233 + if (iState == EDevSoundReady)
1.234 + {//not waiting on a buffer being played so stop devsound now
1.235 + iState = EPaused;
1.236 + if (iFirstBufferRead)
1.237 + {
1.238 + if (!iMMFDevSound)
1.239 + Panic(EMMFAudioInputDevSoundNotLoaded);
1.240 + else
1.241 + iMMFDevSound->Pause();
1.242 + }
1.243 + else
1.244 + iPausePending = ETrue; // Wait for recording to get started.
1.245 + }
1.246 + //else if Devsound isn't ready then no point in stopping it
1.247 + }
1.248 +
1.249 +
1.250 +/**
1.251 +Stops the source.
1.252 +
1.253 +This is a virtual function that each derived class must implement, but may be left blank for default
1.254 +behaviour.
1.255 +
1.256 +Overridable StopL method. Additional Stop method specific to this DataSource.
1.257 +*/
1.258 +void CMMFAudioInput::SourceStopL()
1.259 + {
1.260 + iStopped = ETrue;
1.261 + // This is done in Audio Output as well, not sure whether its needed here or not.
1.262 + // Pause will be called before SourceStopL() and pause will take care of closing
1.263 + // DevSound
1.264 + if (iState == EDevSoundReady || iState == EPaused)
1.265 + {//not waiting on a buffer being played so stop devsound now
1.266 + iState = EIdle;
1.267 + if (iFirstBufferRequested)
1.268 + {
1.269 + if (!iMMFDevSound)
1.270 + Panic(EMMFAudioInputDevSoundNotLoaded);
1.271 + else
1.272 + {
1.273 + iMMFDevSound->Stop();
1.274 + }
1.275 +
1.276 + iFirstBufferRequested = EFalse;
1.277 + iFirstBufferRead = EFalse;
1.278 + }
1.279 + }
1.280 + //else if Devsound isn't ready then no point in stopping it
1.281 + }
1.282 +
1.283 +/**
1.284 +Plays the source.
1.285 +
1.286 +This is a virtual function that each derived class must implement, but may be left blank for default
1.287 +behaviour.
1.288 +
1.289 +Overridable PlayL method. Additional Play method specific to this DataSource.
1.290 +*/
1.291 +void CMMFAudioInput::SourcePlayL()
1.292 + {
1.293 + }
1.294 +
1.295 +/**
1.296 +Logs on the source thread.
1.297 +
1.298 +Thread specific initialization procedure for this device. Runs automatically on thread construction.
1.299 +
1.300 +@param aEventHandler
1.301 + The event handler.
1.302 +
1.303 +@return An error code indicating if the function call was successful. KErrNone on success, otherwise
1.304 + another of the system-wide error codes.
1.305 +*/
1.306 +TInt CMMFAudioInput::SourceThreadLogon(MAsyncEventHandler& aEventHandler)
1.307 + {
1.308 + iEventHandler = &aEventHandler;
1.309 + TInt err = KErrNone;
1.310 + if (!iDevSoundLoaded)
1.311 + TRAP(err, LoadL());
1.312 + return err;
1.313 + }
1.314 +
1.315 +/**
1.316 +Logs off the source thread.
1.317 +
1.318 +Thread specific destruction procedure for this device. Runs automatically on thread destruction.
1.319 +*/
1.320 +void CMMFAudioInput::SourceThreadLogoff()
1.321 + {
1.322 + if(iMMFDevSound)
1.323 + {
1.324 + iMMFDevSound->Stop();
1.325 + delete iMMFDevSound;
1.326 + iMMFDevSound = NULL;
1.327 + }
1.328 + iDevSoundLoaded = EFalse;
1.329 + iState = EIdle;
1.330 + }
1.331 +
1.332 +/*
1.333 +@internaTechnology
1.334 +
1.335 +@pre
1.336 +dev sound should be created and loaded.
1.337 +*/
1.338 +void CMMFAudioInput::ConfigDevSoundL()
1.339 + {
1.340 + //[precondition dev sound created ]
1.341 + ASSERT( iMMFDevSound );
1.342 +
1.343 + // Query DevSound capabilities and Try to use DevSound sample rate and
1.344 + // mono/stereo capability
1.345 + TMMFCapabilities devSoundCaps = iMMFDevSound->Capabilities();
1.346 + // get current config
1.347 + TMMFCapabilities devSoundConfig = iMMFDevSound->Config();
1.348 +
1.349 + // Default PCM16
1.350 + devSoundConfig.iEncoding = EMMFSoundEncoding16BitPCM;
1.351 +
1.352 + // 1 = Monophonic and 2 == Stereo
1.353 + if (((iSinkChannels == 1) && (devSoundCaps.iChannels & EMMFMono)) ||
1.354 + ((iSinkChannels == 2) && (devSoundCaps.iChannels & EMMFStereo)))
1.355 + devSoundConfig.iChannels = iSinkChannels;
1.356 +
1.357 +
1.358 + // Check for std sample rates.
1.359 + if ((iSinkSampleRate == 96000) && (devSoundCaps.iRate & EMMFSampleRate96000Hz))
1.360 + devSoundConfig.iRate = EMMFSampleRate96000Hz;
1.361 + else if ((iSinkSampleRate == 88200) && (devSoundCaps.iRate & EMMFSampleRate88200Hz))
1.362 + devSoundConfig.iRate = EMMFSampleRate88200Hz;
1.363 + else if ((iSinkSampleRate == 64000) && (devSoundCaps.iRate & EMMFSampleRate64000Hz))
1.364 + devSoundConfig.iRate = EMMFSampleRate64000Hz;
1.365 + else if ((iSinkSampleRate == 48000) && (devSoundCaps.iRate & EMMFSampleRate48000Hz))
1.366 + devSoundConfig.iRate = EMMFSampleRate48000Hz;
1.367 + else if ((iSinkSampleRate == 44100) && (devSoundCaps.iRate & EMMFSampleRate44100Hz))
1.368 + devSoundConfig.iRate = EMMFSampleRate44100Hz;
1.369 + else if ((iSinkSampleRate == 32000) && (devSoundCaps.iRate & EMMFSampleRate32000Hz))
1.370 + devSoundConfig.iRate = EMMFSampleRate32000Hz;
1.371 + else if ((iSinkSampleRate == 24000) && (devSoundCaps.iRate & EMMFSampleRate24000Hz))
1.372 + devSoundConfig.iRate = EMMFSampleRate24000Hz;
1.373 + else if ((iSinkSampleRate == 22050) && (devSoundCaps.iRate & EMMFSampleRate22050Hz))
1.374 + devSoundConfig.iRate = EMMFSampleRate22050Hz;
1.375 + else if ((iSinkSampleRate == 16000) && (devSoundCaps.iRate & EMMFSampleRate16000Hz))
1.376 + devSoundConfig.iRate = EMMFSampleRate16000Hz;
1.377 + else if ((iSinkSampleRate == 12000) && (devSoundCaps.iRate & EMMFSampleRate12000Hz))
1.378 + devSoundConfig.iRate = EMMFSampleRate12000Hz;
1.379 + else if ((iSinkSampleRate == 11025) && (devSoundCaps.iRate & EMMFSampleRate11025Hz))
1.380 + devSoundConfig.iRate = EMMFSampleRate11025Hz;
1.381 + else if ((iSinkSampleRate == 8000) && (devSoundCaps.iRate & EMMFSampleRate8000Hz))
1.382 + devSoundConfig.iRate = EMMFSampleRate8000Hz;
1.383 + else
1.384 + {
1.385 + // pick the maximum sample rate available
1.386 + if (devSoundCaps.iRate & EMMFSampleRate96000Hz)
1.387 + devSoundConfig.iRate = EMMFSampleRate96000Hz;
1.388 + else if (devSoundCaps.iRate & EMMFSampleRate88200Hz)
1.389 + devSoundConfig.iRate = EMMFSampleRate88200Hz;
1.390 + else if (devSoundCaps.iRate & EMMFSampleRate64000Hz)
1.391 + devSoundConfig.iRate = EMMFSampleRate64000Hz;
1.392 + else if (devSoundCaps.iRate & EMMFSampleRate48000Hz)
1.393 + devSoundConfig.iRate = EMMFSampleRate48000Hz;
1.394 + else if (devSoundCaps.iRate & EMMFSampleRate44100Hz)
1.395 + devSoundConfig.iRate = EMMFSampleRate44100Hz;
1.396 + else if (devSoundCaps.iRate & EMMFSampleRate32000Hz)
1.397 + devSoundConfig.iRate = EMMFSampleRate32000Hz;
1.398 + else if (devSoundCaps.iRate & EMMFSampleRate24000Hz)
1.399 + devSoundConfig.iRate = EMMFSampleRate24000Hz;
1.400 + else if (devSoundCaps.iRate & EMMFSampleRate22050Hz)
1.401 + devSoundConfig.iRate = EMMFSampleRate22050Hz;
1.402 + else if (devSoundCaps.iRate & EMMFSampleRate16000Hz)
1.403 + devSoundConfig.iRate = EMMFSampleRate16000Hz;
1.404 + else if (devSoundCaps.iRate & EMMFSampleRate12000Hz)
1.405 + devSoundConfig.iRate = EMMFSampleRate12000Hz;
1.406 + else if (devSoundCaps.iRate & EMMFSampleRate11025Hz)
1.407 + devSoundConfig.iRate = EMMFSampleRate11025Hz;
1.408 + else if (devSoundCaps.iRate & EMMFSampleRate8000Hz)
1.409 + devSoundConfig.iRate = EMMFSampleRate8000Hz;
1.410 + else
1.411 + ASSERT(EFalse); // if we don't support any sample rates, there is not much we can do
1.412 +
1.413 + }
1.414 +
1.415 + iMMFDevSound->SetConfigL(devSoundConfig);
1.416 + }
1.417 +
1.418 +/**
1.419 +Negotiates with the sink.
1.420 +
1.421 +Called if the source's setup depends on sink.
1.422 +
1.423 +@param aSink
1.424 + The Data sink. Takes an MDataSink reference so a DataSource can negotiate with this
1.425 + MDataSource.
1.426 +*/
1.427 +void CMMFAudioInput::NegotiateSourceL(MDataSink& aSink)
1.428 + {
1.429 + if (aSink.DataSinkType() == KUidMmfFormatEncode)
1.430 + {//sink is a clip so for now set sink settings to match sink
1.431 + iSinkSampleRate = ((CMMFFormatEncode&)aSink).SampleRate();
1.432 + iSinkChannels = ((CMMFFormatEncode&)aSink).NumChannels();
1.433 + iSinkFourCC.Set(aSink.SinkDataTypeCode(TMediaId(KUidMediaTypeAudio)));
1.434 +
1.435 + // if the sink's sample rate is undefined, try to obtain and use a
1.436 + // default sample rate from the sink. If this is zero, use 8K
1.437 + if (iSinkSampleRate == 0)
1.438 + {
1.439 + iSinkSampleRate = ((CMMFFormatEncode&)aSink).GetDefaultSampleRate();
1.440 + if (iSinkSampleRate == 0)
1.441 + iSinkSampleRate = 8000;
1.442 + }
1.443 +
1.444 + }
1.445 +
1.446 + if (iMMFDevSound == NULL)
1.447 + User::Leave(KErrNotReady);
1.448 +
1.449 + TMMFState prioritySettingsState = iPrioritySettings.iState; //should be EMMFStateRecording
1.450 + //to use the GetSupportedOutputDatatypes but we'll save it just in case it's not
1.451 + iPrioritySettings.iState = EMMFStateRecording; //if playing does not support any output data types
1.452 + RArray<TFourCC> supportedDataTypes;
1.453 + //note Output data types becuase if we are recording audio ie audio input
1.454 + //the data is sent as an output from DevSound
1.455 + TRAPD(err, iMMFDevSound->GetSupportedOutputDataTypesL(supportedDataTypes, iPrioritySettings));
1.456 + iPrioritySettings.iState = prioritySettingsState;
1.457 + if (err == KErrNone)
1.458 + {
1.459 + if (supportedDataTypes.Find(iSinkFourCC) == KErrNotFound)
1.460 + {//the source fourCC code could not be found in the list of
1.461 + //data types supported by the Devsound therefor default to pcm16
1.462 + iDataTypeCode = KMMFFourCCCodePCM16;
1.463 + }
1.464 + else
1.465 + {
1.466 + //the DevSound does support the same datatype as the source
1.467 + //so set the fourcc to that of the source
1.468 + iDataTypeCode = iSinkFourCC;
1.469 + }
1.470 + }
1.471 + supportedDataTypes.Close();
1.472 + if (err == KErrNotSupported)
1.473 + {//if the Devsound does not support the GetSupportedOutputDataTypesL method
1.474 + //then assume that the DevSound is pcm16 only
1.475 + iDataTypeCode = KMMFFourCCCodePCM16;
1.476 + }
1.477 + else if (err != KErrNone) //we had a real leave error from GetSupportedOuputDataTypesL
1.478 + {
1.479 + User::Leave(err);
1.480 + }
1.481 +
1.482 + // Prevent defect when SourcePrimeL is called before NegotiateSourceL()
1.483 + // since characterization is ambiguous
1.484 + if(iState == EDevSoundReady)
1.485 + {
1.486 + iState = EIdle;
1.487 + }
1.488 +
1.489 + // moved from LoadL - fix for DEF037168 - AD
1.490 + iMMFDevSound->InitializeL(*this, iDataTypeCode, EMMFStateRecording);
1.491 +
1.492 + // In some implementations InitializeComplete is sent
1.493 + // in context, so check before starting activeSchedulerWait.
1.494 + if (iState != EDevSoundReady)
1.495 + {
1.496 + iInitializeState = KRequestPending;
1.497 + iActiveSchedulerWait->Start();
1.498 + }
1.499 + User::LeaveIfError(iInitializeState);
1.500 +
1.501 + iMMFDevSound->SetPrioritySettings(iPrioritySettings);
1.502 +
1.503 + // Attempt to configure DevSound to the same settings as the sink.
1.504 + // Need to do this after calling CMMFDevSound::InitializeL() as
1.505 + // this sets up the device capabilities
1.506 + // (returned by iMMFDevSound->Capabilities()).
1.507 + ConfigDevSoundL();
1.508 + }
1.509 +
1.510 +/**
1.511 +Sets the source's priority settings.
1.512 +
1.513 +@param aPrioritySettings
1.514 + The source priority settings. Takes enumerations to determine audio record priority. Higher
1.515 + numbers mean high priority (can interrupt lower priorities).
1.516 +*/
1.517 +void CMMFAudioInput::SetSourcePrioritySettings(const TMMFPrioritySettings& aPrioritySettings)
1.518 + {
1.519 + iPrioritySettings = aPrioritySettings;
1.520 + if (!iMMFDevSound)
1.521 + Panic(EMMFAudioInputDevSoundNotLoaded);
1.522 + else
1.523 + iMMFDevSound->SetPrioritySettings(iPrioritySettings);
1.524 + }
1.525 +
1.526 +
1.527 +/**
1.528 +Gets the data type code for the source specified by the media ID.
1.529 +
1.530 +@param aMediaId
1.531 + An optional parameter to specifiy a specific stream when the datasource contains more than
1.532 + one stream of data.
1.533 +
1.534 +@return The 4CC of the data supplied by this source.
1.535 +*/
1.536 +TFourCC CMMFAudioInput::SourceDataTypeCode(TMediaId /*aMediaId*/)
1.537 + {
1.538 + return iDataTypeCode;
1.539 + }
1.540 +
1.541 +/**
1.542 +Sets the data type code for the source.
1.543 +
1.544 +@param aSourceFourCC
1.545 + The 4CC of the data supplied by this source.
1.546 +@param aMediaId
1.547 + The Media ID. An optional parameter to specifiy specific stream when datasource contains
1.548 + more than one stream of data.
1.549 +
1.550 +@return An error code indicating if the function call was successful. KErrNone on success, otherwise
1.551 + another of the system-wide error codes.
1.552 +*/
1.553 +TInt CMMFAudioInput::SetSourceDataTypeCode(TFourCC aSourceFourCC, TMediaId /*aMediaId*/)
1.554 + {
1.555 + iDataTypeCode = aSourceFourCC;
1.556 + return KErrNone;
1.557 + }
1.558 +
1.559 +/**
1.560 +Gets the number of bytes played.
1.561 +
1.562 +@return The number of bytes played. If 16-bit divide this number returned by 2 to get word length.
1.563 +*/
1.564 +TInt CMMFAudioInput::BytesPlayed()
1.565 + {
1.566 + if (!iMMFDevSound)
1.567 + Panic(EMMFAudioInputDevSoundNotLoaded);
1.568 + return iMMFDevSound->SamplesPlayed();
1.569 + }
1.570 +
1.571 +/**
1.572 +Returns the sound device.
1.573 +
1.574 +@pre
1.575 +Dev Sound should be loaded.
1.576 +
1.577 +Accessor function exposing public CMMFDevsound methods.
1.578 +
1.579 +@return A reference to a CMMFDevSound objector.
1.580 +*/
1.581 +CMMFDevSound& CMMFAudioInput::SoundDevice()
1.582 + {
1.583 + if (!iMMFDevSound)
1.584 + {
1.585 + Panic(EMMFAudioInputDevSoundNotLoaded);
1.586 + }
1.587 + return *iMMFDevSound;
1.588 + }
1.589 +
1.590 +
1.591 +/**
1.592 +@deprecated
1.593 +
1.594 +This method should not be used - it is provided to maintain SC with v7.0s.
1.595 +
1.596 +@param aAudioType
1.597 + The 4CC of the data supplied by this source.
1.598 +*/
1.599 +void CMMFAudioInput::SetDataTypeL(TFourCC aAudioType)
1.600 + {
1.601 + if (aAudioType != KMMFFourCCCodePCM16)
1.602 + {
1.603 + User::Leave(KErrNotSupported);
1.604 + }
1.605 + }
1.606 +
1.607 +
1.608 +/**
1.609 +@deprecated
1.610 +
1.611 +This method should not be used - it is provided to maintain SC with v7.0s.
1.612 +
1.613 +@return The 4CC of the data supplied by this source.
1.614 +*/
1.615 +TFourCC CMMFAudioInput::DataType() const
1.616 + {
1.617 + return KMMFFourCCCodePCM16;
1.618 + }
1.619 +
1.620 +
1.621 +/**
1.622 +Loads audio device drivers and initialise this device.
1.623 +*/
1.624 +void CMMFAudioInput::LoadL()
1.625 + {
1.626 + //[ do all the work that can fail first
1.627 + // before we modify the internal state ]
1.628 +
1.629 + iMMFDevSound = CMMFDevSound::NewL();
1.630 + iFirstBufferRequested = EFalse;
1.631 + iFirstBufferRead = EFalse;
1.632 + if (iState != EDevSoundReady)
1.633 + {
1.634 + iState = EIdle;
1.635 + }
1.636 +
1.637 + iDevSoundLoaded = ETrue;
1.638 +
1.639 + //[ assert dev sound has been constructed]
1.640 + ASSERT( iMMFDevSound );
1.641 + ASSERT( iDevSoundLoaded );
1.642 + ASSERT( !iFirstBufferRead );
1.643 + }
1.644 +
1.645 +void CMMFAudioInput::DeviceMessage(TUid /*aMessageType*/, const TDesC8& /* aMsg */)
1.646 + {
1.647 + }
1.648 +
1.649 +void CMMFAudioInput::InitializeComplete(TInt aError)
1.650 + {
1.651 + if (aError == KErrNone)
1.652 + {
1.653 + iState = EDevSoundReady;
1.654 + }
1.655 +
1.656 + if(iInitializeState == KRequestPending)
1.657 + {
1.658 + iInitializeState = aError;
1.659 + iActiveSchedulerWait->AsyncStop();
1.660 + }
1.661 + }
1.662 +
1.663 +
1.664 +/**
1.665 +ToneFinished MMFDevSoundObserver - should never get called.
1.666 +*/
1.667 +void CMMFAudioInput::ToneFinished(TInt /*aError*/)
1.668 + {
1.669 + //we should never get here during a record session!
1.670 + __ASSERT_DEBUG(EFalse,Panic(EMMFAudioInputPanicToneFinishedNotSupported));
1.671 + }
1.672 +
1.673 +
1.674 +/**
1.675 +BuffferToBeEmptied MMFDevSoundObserver
1.676 +Called when stopped due to error.
1.677 +*/
1.678 +void CMMFAudioInput::BufferToBeEmptied(CMMFBuffer* aBuffer)
1.679 + {
1.680 + iDevSoundBuf = aBuffer;
1.681 +
1.682 + if (iFirstBufferRequested)
1.683 + {
1.684 + if (iPausePending)
1.685 + {
1.686 + aBuffer->SetLastBuffer(ETrue);
1.687 + iPausePending = EFalse;
1.688 + }
1.689 +
1.690 +#ifdef _DEBUG
1.691 + TRAPD(err, iConsumer->BufferFilledL(aBuffer));
1.692 + __ASSERT_DEBUG(!err, Panic(err));
1.693 +#else
1.694 + TRAP_IGNORE(iConsumer->BufferFilledL(aBuffer));
1.695 +#endif
1.696 +
1.697 + iFirstBufferRead = ETrue;
1.698 + }
1.699 + }
1.700 +
1.701 +
1.702 +/**
1.703 +RecordError MMFDevSoundObserver
1.704 +Called when stopped due to error.
1.705 +*/
1.706 +void CMMFAudioInput::RecordError(TInt aError)
1.707 + {
1.708 + //[ two event categories will be used
1.709 + // which mirrors the datapath response ]
1.710 +
1.711 + //[ record the error ]
1.712 + iMMFDevsoundError = aError;
1.713 + TMMFEvent event( KMMFEventCategoryPlaybackComplete, aError);
1.714 +
1.715 + //[ send the event to the client.
1.716 + SendEventToClient(event);
1.717 +
1.718 + // clear flags if there is an error.
1.719 + iPausePending = EFalse;
1.720 +
1.721 + //[ we are not going to stop devsound ]
1.722 + }
1.723 +
1.724 +
1.725 +/**
1.726 +BufferToBeFilled MMFDevSoundObserver - should never get called.
1.727 +*/
1.728 +void CMMFAudioInput::BufferToBeFilled(CMMFBuffer* /*aBuffer*/)
1.729 + {
1.730 + //we should never get here during a play session!
1.731 + __ASSERT_DEBUG(EFalse, Panic(EMMFAudioInputPanicPlayerDataUsedNotSupported));
1.732 + }
1.733 +
1.734 +
1.735 +/**
1.736 +PlayError MMFDevSoundObserver - should never get called.
1.737 +*/
1.738 +void CMMFAudioInput::PlayError(TInt /*aError*/)
1.739 + {
1.740 + //we should never get here during a record session!
1.741 + __ASSERT_DEBUG(EFalse, Panic(EMMFAudioInputPanicPlayErrorNotSupported));
1.742 + }
1.743 +
1.744 +
1.745 +/**
1.746 +ConvertError MMFDevSoundObserver - should never get called.
1.747 +*/
1.748 +void CMMFAudioInput::ConvertError(TInt /*aError*/)
1.749 + {
1.750 + }
1.751 +
1.752 +
1.753 +void CMMFAudioInput::SendEventToClient(const TMMFEvent& aEvent)
1.754 + {
1.755 + iEventHandler->SendEventToClient(aEvent);
1.756 + }
1.757 +
1.758 +// _________________________________________________________________________
1.759 +// Exported proxy for instantiation method resolution
1.760 +// Define the interface UIDs
1.761 +
1.762 +const TImplementationProxy ImplementationTable[] =
1.763 + {
1.764 + IMPLEMENTATION_PROXY_ENTRY(KMmfUidAudioInputInterface, CMMFAudioInput::NewSourceL)
1.765 + };
1.766 +
1.767 +EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
1.768 + {
1.769 + aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
1.770 +
1.771 + return ImplementationTable;
1.772 + }
1.773 +