sl@0: // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include "MmfAudioInput.h" sl@0: #include sl@0: #include sl@0: #include sl@0: sl@0: sl@0: void Panic(TInt aPanicCode) sl@0: { sl@0: _LIT(KMMFAudioInputPanicCategory, "MMFAudioInput"); sl@0: User::Panic(KMMFAudioInputPanicCategory, aPanicCode); sl@0: } sl@0: sl@0: /** sl@0: Static standard SymbianOS 2 phase constuction method. sl@0: sl@0: Constucts this audio device. sl@0: sl@0: @return A pointer to a MDataSource returned on successful construction. sl@0: */ sl@0: MDataSource* CMMFAudioInput::NewSourceL() sl@0: { sl@0: CMMFAudioInput* self = new (ELeave) CMMFAudioInput ; sl@0: CleanupStack::PushL(self); sl@0: self->ConstructL(); sl@0: CleanupStack::Pop(); sl@0: return STATIC_CAST( MDataSource*, self ); sl@0: } sl@0: sl@0: /** sl@0: Standard SymbianOS ConstructL. sl@0: sl@0: Used to initialise member varibles with device specific behaviour. sl@0: */ sl@0: void CMMFAudioInput::ConstructL() sl@0: { sl@0: iDataTypeCode = KMMFFourCCCodePCM16; sl@0: iActiveSchedulerWait = new(ELeave) CActiveSchedulerWait; sl@0: } sl@0: sl@0: /** sl@0: Standard SymbianOS destructor. sl@0: */ sl@0: CMMFAudioInput::~CMMFAudioInput() sl@0: { sl@0: delete iActiveSchedulerWait; sl@0: if (iMMFDevSound) sl@0: { sl@0: iMMFDevSound->Stop(); sl@0: delete iMMFDevSound; sl@0: } sl@0: } sl@0: sl@0: sl@0: /** sl@0: Overridable constuctor specific to this datasource. sl@0: sl@0: @param aInitData sl@0: The initialisation data. sl@0: */ sl@0: void CMMFAudioInput::ConstructSourceL( const TDesC8& /*aInitData*/ ) sl@0: { sl@0: } sl@0: sl@0: /** sl@0: @deprecated sl@0: sl@0: Gets audio from hardware device abstracted MMFDevsound (not used). sl@0: sl@0: @param aBuffer sl@0: The data to read in from a Hardware Device sl@0: @param aConsumer sl@0: The MDataSink consuming the data contained in aBuffer. sl@0: */ sl@0: void CMMFAudioInput::HWFillBufferL(CMMFBuffer* /*aBuffer*/, MDataSink* /*aConsumer*/) sl@0: { sl@0: } sl@0: sl@0: sl@0: /** sl@0: Gets audio from MMFDevsound. sl@0: sl@0: @pre sl@0: iMMFDevSound must be loaded. sl@0: sl@0: @param aBuffer sl@0: The data to read in from a Devsound device. sl@0: @param aConsumer sl@0: The MDataSink consuming the data contained in aBuffer. sl@0: @param aMediaId sl@0: Type of data supplied - currently ignored. sl@0: */ sl@0: void CMMFAudioInput::FillBufferL(CMMFBuffer* aBuffer, MDataSink* aConsumer, TMediaId /* aMediaId */) sl@0: { sl@0: iConsumer = aConsumer; sl@0: sl@0: if (!iMMFDevSound) sl@0: Panic(EMMFAudioInputDevSoundNotLoaded); sl@0: sl@0: if ((iState == EPaused) && (iPausePending != EFalse) && (iFirstBufferRequested) ) sl@0: { sl@0: User::Leave(KErrNotReady); sl@0: } sl@0: sl@0: if ((aBuffer != NULL) && (!CMMFBuffer::IsSupportedDataBuffer(aBuffer->Type()))) sl@0: User::Leave(KErrNotSupported); sl@0: sl@0: if (aConsumer == NULL) sl@0: User::Leave(KErrArgument); sl@0: sl@0: //this is a one-shot "prime" funtion for MMFDevSound as first buffer is uninitialised sl@0: if (!iFirstBufferRequested) sl@0: { sl@0: iMMFDevSound->RecordInitL(); sl@0: iFirstBufferRequested = ETrue; sl@0: return; sl@0: } sl@0: sl@0: if (iState != EDevSoundReady && iState != EPaused) sl@0: { sl@0: User::Leave(KErrNotReady); sl@0: } sl@0: sl@0: iMMFDevSound->RecordData(); sl@0: } sl@0: sl@0: /** sl@0: Indicates the data sink has emptied the buffer. sl@0: sl@0: Called by the data path's MDataSink when it has emptied the buffer. sl@0: sl@0: The default implementation is empty. sl@0: sl@0: @param aBuffer sl@0: The data buffer that has been emptied (not used). sl@0: */ sl@0: void CMMFAudioInput::BufferEmptiedL(CMMFBuffer* /*aBuffer*/) sl@0: { sl@0: } sl@0: sl@0: sl@0: /** sl@0: Tests whether a source buffer can be created. sl@0: sl@0: The default imlpementation returns true. sl@0: sl@0: @return A boolean indicating if the buffer can be made. ETrue if the buffer can be created, false sl@0: otherwise. sl@0: */ sl@0: TBool CMMFAudioInput::CanCreateSourceBuffer() sl@0: { sl@0: return ETrue; sl@0: } sl@0: sl@0: /** sl@0: Creates a source buffer. sl@0: sl@0: Intended for asynchronous usage (buffers supplied by Devsound device) sl@0: sl@0: @param aMediaId sl@0: The Media ID. Not used in the default implementation. sl@0: @param aReference sl@0: A boolean indicating if MDataSource owns the buffer. ETrue if it does, EFalse if it does sl@0: not. sl@0: sl@0: @return The buffer created (this will always be NULL when asychronous). sl@0: */ sl@0: CMMFBuffer* CMMFAudioInput::CreateSourceBufferL(TMediaId /*aMediaId*/, TBool &aReference) sl@0: { sl@0: CMMFDataBuffer* buf = NULL; sl@0: sl@0: aReference = ETrue; // This is a reference from DevSound sl@0: return buf; sl@0: } sl@0: sl@0: /** sl@0: Creates a source buffer. sl@0: sl@0: Intended for synchronous usage. sl@0: sl@0: @param aMediaId sl@0: The Media ID. Not used in the default implementation. sl@0: sl@0: @return The buffer created sl@0: */ sl@0: CMMFBuffer* CMMFAudioInput::CreateSourceBufferL(TMediaId /*aMediaId*/) sl@0: { sl@0: CMMFDataBuffer* buf = CMMFDataBuffer::NewL(KAudioInputDefaultFrameSize); sl@0: return buf; sl@0: } sl@0: sl@0: sl@0: /** sl@0: Primes the source. sl@0: sl@0: This is a virtual function that each derived class must implement, but may be left blank for sl@0: default behaviour. sl@0: sl@0: Overridable PrimeL method. Additional Prime method specific to this DataSource. sl@0: */ sl@0: void CMMFAudioInput::SourcePrimeL() sl@0: { sl@0: iState = EDevSoundReady; sl@0: } sl@0: sl@0: /** sl@0: Pauses the source. sl@0: sl@0: This is a virtual function that each derived class must implement, but may be left blank for default sl@0: behaviour. sl@0: sl@0: Overridable PauseL method. Additional Pause method specific to this DataSource. sl@0: */ sl@0: void CMMFAudioInput::SourcePauseL() sl@0: { sl@0: if (iState == EDevSoundReady) sl@0: {//not waiting on a buffer being played so stop devsound now sl@0: iState = EPaused; sl@0: if (iFirstBufferRead) sl@0: { sl@0: if (!iMMFDevSound) sl@0: Panic(EMMFAudioInputDevSoundNotLoaded); sl@0: else sl@0: iMMFDevSound->Pause(); sl@0: } sl@0: else sl@0: iPausePending = ETrue; // Wait for recording to get started. sl@0: } sl@0: //else if Devsound isn't ready then no point in stopping it sl@0: } sl@0: sl@0: sl@0: /** sl@0: Stops the source. sl@0: sl@0: This is a virtual function that each derived class must implement, but may be left blank for default sl@0: behaviour. sl@0: sl@0: Overridable StopL method. Additional Stop method specific to this DataSource. sl@0: */ sl@0: void CMMFAudioInput::SourceStopL() sl@0: { sl@0: iStopped = ETrue; sl@0: // This is done in Audio Output as well, not sure whether its needed here or not. sl@0: // Pause will be called before SourceStopL() and pause will take care of closing sl@0: // DevSound sl@0: if (iState == EDevSoundReady || iState == EPaused) sl@0: {//not waiting on a buffer being played so stop devsound now sl@0: iState = EIdle; sl@0: if (iFirstBufferRequested) sl@0: { sl@0: if (!iMMFDevSound) sl@0: Panic(EMMFAudioInputDevSoundNotLoaded); sl@0: else sl@0: { sl@0: iMMFDevSound->Stop(); sl@0: } sl@0: sl@0: iFirstBufferRequested = EFalse; sl@0: iFirstBufferRead = EFalse; sl@0: } sl@0: } sl@0: //else if Devsound isn't ready then no point in stopping it sl@0: } sl@0: sl@0: /** sl@0: Plays the source. sl@0: sl@0: This is a virtual function that each derived class must implement, but may be left blank for default sl@0: behaviour. sl@0: sl@0: Overridable PlayL method. Additional Play method specific to this DataSource. sl@0: */ sl@0: void CMMFAudioInput::SourcePlayL() sl@0: { sl@0: } sl@0: sl@0: /** sl@0: Logs on the source thread. sl@0: sl@0: Thread specific initialization procedure for this device. Runs automatically on thread construction. sl@0: sl@0: @param aEventHandler sl@0: The event handler. sl@0: sl@0: @return An error code indicating if the function call was successful. KErrNone on success, otherwise sl@0: another of the system-wide error codes. sl@0: */ sl@0: TInt CMMFAudioInput::SourceThreadLogon(MAsyncEventHandler& aEventHandler) sl@0: { sl@0: iEventHandler = &aEventHandler; sl@0: TInt err = KErrNone; sl@0: if (!iDevSoundLoaded) sl@0: TRAP(err, LoadL()); sl@0: return err; sl@0: } sl@0: sl@0: /** sl@0: Logs off the source thread. sl@0: sl@0: Thread specific destruction procedure for this device. Runs automatically on thread destruction. sl@0: */ sl@0: void CMMFAudioInput::SourceThreadLogoff() sl@0: { sl@0: if(iMMFDevSound) sl@0: { sl@0: iMMFDevSound->Stop(); sl@0: delete iMMFDevSound; sl@0: iMMFDevSound = NULL; sl@0: } sl@0: iDevSoundLoaded = EFalse; sl@0: iState = EIdle; sl@0: } sl@0: sl@0: /* sl@0: @internaTechnology sl@0: sl@0: @pre sl@0: dev sound should be created and loaded. sl@0: */ sl@0: void CMMFAudioInput::ConfigDevSoundL() sl@0: { sl@0: //[precondition dev sound created ] sl@0: ASSERT( iMMFDevSound ); sl@0: sl@0: // Query DevSound capabilities and Try to use DevSound sample rate and sl@0: // mono/stereo capability sl@0: TMMFCapabilities devSoundCaps = iMMFDevSound->Capabilities(); sl@0: // get current config sl@0: TMMFCapabilities devSoundConfig = iMMFDevSound->Config(); sl@0: sl@0: // Default PCM16 sl@0: devSoundConfig.iEncoding = EMMFSoundEncoding16BitPCM; sl@0: sl@0: // 1 = Monophonic and 2 == Stereo sl@0: if (((iSinkChannels == 1) && (devSoundCaps.iChannels & EMMFMono)) || sl@0: ((iSinkChannels == 2) && (devSoundCaps.iChannels & EMMFStereo))) sl@0: devSoundConfig.iChannels = iSinkChannels; sl@0: sl@0: sl@0: // Check for std sample rates. sl@0: if ((iSinkSampleRate == 96000) && (devSoundCaps.iRate & EMMFSampleRate96000Hz)) sl@0: devSoundConfig.iRate = EMMFSampleRate96000Hz; sl@0: else if ((iSinkSampleRate == 88200) && (devSoundCaps.iRate & EMMFSampleRate88200Hz)) sl@0: devSoundConfig.iRate = EMMFSampleRate88200Hz; sl@0: else if ((iSinkSampleRate == 64000) && (devSoundCaps.iRate & EMMFSampleRate64000Hz)) sl@0: devSoundConfig.iRate = EMMFSampleRate64000Hz; sl@0: else if ((iSinkSampleRate == 48000) && (devSoundCaps.iRate & EMMFSampleRate48000Hz)) sl@0: devSoundConfig.iRate = EMMFSampleRate48000Hz; sl@0: else if ((iSinkSampleRate == 44100) && (devSoundCaps.iRate & EMMFSampleRate44100Hz)) sl@0: devSoundConfig.iRate = EMMFSampleRate44100Hz; sl@0: else if ((iSinkSampleRate == 32000) && (devSoundCaps.iRate & EMMFSampleRate32000Hz)) sl@0: devSoundConfig.iRate = EMMFSampleRate32000Hz; sl@0: else if ((iSinkSampleRate == 24000) && (devSoundCaps.iRate & EMMFSampleRate24000Hz)) sl@0: devSoundConfig.iRate = EMMFSampleRate24000Hz; sl@0: else if ((iSinkSampleRate == 22050) && (devSoundCaps.iRate & EMMFSampleRate22050Hz)) sl@0: devSoundConfig.iRate = EMMFSampleRate22050Hz; sl@0: else if ((iSinkSampleRate == 16000) && (devSoundCaps.iRate & EMMFSampleRate16000Hz)) sl@0: devSoundConfig.iRate = EMMFSampleRate16000Hz; sl@0: else if ((iSinkSampleRate == 12000) && (devSoundCaps.iRate & EMMFSampleRate12000Hz)) sl@0: devSoundConfig.iRate = EMMFSampleRate12000Hz; sl@0: else if ((iSinkSampleRate == 11025) && (devSoundCaps.iRate & EMMFSampleRate11025Hz)) sl@0: devSoundConfig.iRate = EMMFSampleRate11025Hz; sl@0: else if ((iSinkSampleRate == 8000) && (devSoundCaps.iRate & EMMFSampleRate8000Hz)) sl@0: devSoundConfig.iRate = EMMFSampleRate8000Hz; sl@0: else sl@0: { sl@0: // pick the maximum sample rate available sl@0: if (devSoundCaps.iRate & EMMFSampleRate96000Hz) sl@0: devSoundConfig.iRate = EMMFSampleRate96000Hz; sl@0: else if (devSoundCaps.iRate & EMMFSampleRate88200Hz) sl@0: devSoundConfig.iRate = EMMFSampleRate88200Hz; sl@0: else if (devSoundCaps.iRate & EMMFSampleRate64000Hz) sl@0: devSoundConfig.iRate = EMMFSampleRate64000Hz; sl@0: else if (devSoundCaps.iRate & EMMFSampleRate48000Hz) sl@0: devSoundConfig.iRate = EMMFSampleRate48000Hz; sl@0: else if (devSoundCaps.iRate & EMMFSampleRate44100Hz) sl@0: devSoundConfig.iRate = EMMFSampleRate44100Hz; sl@0: else if (devSoundCaps.iRate & EMMFSampleRate32000Hz) sl@0: devSoundConfig.iRate = EMMFSampleRate32000Hz; sl@0: else if (devSoundCaps.iRate & EMMFSampleRate24000Hz) sl@0: devSoundConfig.iRate = EMMFSampleRate24000Hz; sl@0: else if (devSoundCaps.iRate & EMMFSampleRate22050Hz) sl@0: devSoundConfig.iRate = EMMFSampleRate22050Hz; sl@0: else if (devSoundCaps.iRate & EMMFSampleRate16000Hz) sl@0: devSoundConfig.iRate = EMMFSampleRate16000Hz; sl@0: else if (devSoundCaps.iRate & EMMFSampleRate12000Hz) sl@0: devSoundConfig.iRate = EMMFSampleRate12000Hz; sl@0: else if (devSoundCaps.iRate & EMMFSampleRate11025Hz) sl@0: devSoundConfig.iRate = EMMFSampleRate11025Hz; sl@0: else if (devSoundCaps.iRate & EMMFSampleRate8000Hz) sl@0: devSoundConfig.iRate = EMMFSampleRate8000Hz; sl@0: else sl@0: ASSERT(EFalse); // if we don't support any sample rates, there is not much we can do sl@0: sl@0: } sl@0: sl@0: iMMFDevSound->SetConfigL(devSoundConfig); sl@0: } sl@0: sl@0: /** sl@0: Negotiates with the sink. sl@0: sl@0: Called if the source's setup depends on sink. sl@0: sl@0: @param aSink sl@0: The Data sink. Takes an MDataSink reference so a DataSource can negotiate with this sl@0: MDataSource. sl@0: */ sl@0: void CMMFAudioInput::NegotiateSourceL(MDataSink& aSink) sl@0: { sl@0: if (aSink.DataSinkType() == KUidMmfFormatEncode) sl@0: {//sink is a clip so for now set sink settings to match sink sl@0: iSinkSampleRate = ((CMMFFormatEncode&)aSink).SampleRate(); sl@0: iSinkChannels = ((CMMFFormatEncode&)aSink).NumChannels(); sl@0: iSinkFourCC.Set(aSink.SinkDataTypeCode(TMediaId(KUidMediaTypeAudio))); sl@0: sl@0: // if the sink's sample rate is undefined, try to obtain and use a sl@0: // default sample rate from the sink. If this is zero, use 8K sl@0: if (iSinkSampleRate == 0) sl@0: { sl@0: iSinkSampleRate = ((CMMFFormatEncode&)aSink).GetDefaultSampleRate(); sl@0: if (iSinkSampleRate == 0) sl@0: iSinkSampleRate = 8000; sl@0: } sl@0: sl@0: } sl@0: sl@0: if (iMMFDevSound == NULL) sl@0: User::Leave(KErrNotReady); sl@0: sl@0: TMMFState prioritySettingsState = iPrioritySettings.iState; //should be EMMFStateRecording sl@0: //to use the GetSupportedOutputDatatypes but we'll save it just in case it's not sl@0: iPrioritySettings.iState = EMMFStateRecording; //if playing does not support any output data types sl@0: RArray supportedDataTypes; sl@0: //note Output data types becuase if we are recording audio ie audio input sl@0: //the data is sent as an output from DevSound sl@0: TRAPD(err, iMMFDevSound->GetSupportedOutputDataTypesL(supportedDataTypes, iPrioritySettings)); sl@0: iPrioritySettings.iState = prioritySettingsState; sl@0: if (err == KErrNone) sl@0: { sl@0: if (supportedDataTypes.Find(iSinkFourCC) == KErrNotFound) sl@0: {//the source fourCC code could not be found in the list of sl@0: //data types supported by the Devsound therefor default to pcm16 sl@0: iDataTypeCode = KMMFFourCCCodePCM16; sl@0: } sl@0: else sl@0: { sl@0: //the DevSound does support the same datatype as the source sl@0: //so set the fourcc to that of the source sl@0: iDataTypeCode = iSinkFourCC; sl@0: } sl@0: } sl@0: supportedDataTypes.Close(); sl@0: if (err == KErrNotSupported) sl@0: {//if the Devsound does not support the GetSupportedOutputDataTypesL method sl@0: //then assume that the DevSound is pcm16 only sl@0: iDataTypeCode = KMMFFourCCCodePCM16; sl@0: } sl@0: else if (err != KErrNone) //we had a real leave error from GetSupportedOuputDataTypesL sl@0: { sl@0: User::Leave(err); sl@0: } sl@0: sl@0: // Prevent defect when SourcePrimeL is called before NegotiateSourceL() sl@0: // since characterization is ambiguous sl@0: if(iState == EDevSoundReady) sl@0: { sl@0: iState = EIdle; sl@0: } sl@0: sl@0: // moved from LoadL - fix for DEF037168 - AD sl@0: iMMFDevSound->InitializeL(*this, iDataTypeCode, EMMFStateRecording); sl@0: sl@0: // In some implementations InitializeComplete is sent sl@0: // in context, so check before starting activeSchedulerWait. sl@0: if (iState != EDevSoundReady) sl@0: { sl@0: iInitializeState = KRequestPending; sl@0: iActiveSchedulerWait->Start(); sl@0: } sl@0: User::LeaveIfError(iInitializeState); sl@0: sl@0: iMMFDevSound->SetPrioritySettings(iPrioritySettings); sl@0: sl@0: // Attempt to configure DevSound to the same settings as the sink. sl@0: // Need to do this after calling CMMFDevSound::InitializeL() as sl@0: // this sets up the device capabilities sl@0: // (returned by iMMFDevSound->Capabilities()). sl@0: ConfigDevSoundL(); sl@0: } sl@0: sl@0: /** sl@0: Sets the source's priority settings. sl@0: sl@0: @param aPrioritySettings sl@0: The source priority settings. Takes enumerations to determine audio record priority. Higher sl@0: numbers mean high priority (can interrupt lower priorities). sl@0: */ sl@0: void CMMFAudioInput::SetSourcePrioritySettings(const TMMFPrioritySettings& aPrioritySettings) sl@0: { sl@0: iPrioritySettings = aPrioritySettings; sl@0: if (!iMMFDevSound) sl@0: Panic(EMMFAudioInputDevSoundNotLoaded); sl@0: else sl@0: iMMFDevSound->SetPrioritySettings(iPrioritySettings); sl@0: } sl@0: sl@0: sl@0: /** sl@0: Gets the data type code for the source specified by the media ID. sl@0: sl@0: @param aMediaId sl@0: An optional parameter to specifiy a specific stream when the datasource contains more than sl@0: one stream of data. sl@0: sl@0: @return The 4CC of the data supplied by this source. sl@0: */ sl@0: TFourCC CMMFAudioInput::SourceDataTypeCode(TMediaId /*aMediaId*/) sl@0: { sl@0: return iDataTypeCode; sl@0: } sl@0: sl@0: /** sl@0: Sets the data type code for the source. sl@0: sl@0: @param aSourceFourCC sl@0: The 4CC of the data supplied by this source. sl@0: @param aMediaId sl@0: The Media ID. An optional parameter to specifiy specific stream when datasource contains sl@0: more than one stream of data. sl@0: sl@0: @return An error code indicating if the function call was successful. KErrNone on success, otherwise sl@0: another of the system-wide error codes. sl@0: */ sl@0: TInt CMMFAudioInput::SetSourceDataTypeCode(TFourCC aSourceFourCC, TMediaId /*aMediaId*/) sl@0: { sl@0: iDataTypeCode = aSourceFourCC; sl@0: return KErrNone; sl@0: } sl@0: sl@0: /** sl@0: Gets the number of bytes played. sl@0: sl@0: @return The number of bytes played. If 16-bit divide this number returned by 2 to get word length. sl@0: */ sl@0: TInt CMMFAudioInput::BytesPlayed() sl@0: { sl@0: if (!iMMFDevSound) sl@0: Panic(EMMFAudioInputDevSoundNotLoaded); sl@0: return iMMFDevSound->SamplesPlayed(); sl@0: } sl@0: sl@0: /** sl@0: Returns the sound device. sl@0: sl@0: @pre sl@0: Dev Sound should be loaded. sl@0: sl@0: Accessor function exposing public CMMFDevsound methods. sl@0: sl@0: @return A reference to a CMMFDevSound objector. sl@0: */ sl@0: CMMFDevSound& CMMFAudioInput::SoundDevice() sl@0: { sl@0: if (!iMMFDevSound) sl@0: { sl@0: Panic(EMMFAudioInputDevSoundNotLoaded); sl@0: } sl@0: return *iMMFDevSound; sl@0: } sl@0: sl@0: sl@0: /** sl@0: @deprecated sl@0: sl@0: This method should not be used - it is provided to maintain SC with v7.0s. sl@0: sl@0: @param aAudioType sl@0: The 4CC of the data supplied by this source. sl@0: */ sl@0: void CMMFAudioInput::SetDataTypeL(TFourCC aAudioType) sl@0: { sl@0: if (aAudioType != KMMFFourCCCodePCM16) sl@0: { sl@0: User::Leave(KErrNotSupported); sl@0: } sl@0: } sl@0: sl@0: sl@0: /** sl@0: @deprecated sl@0: sl@0: This method should not be used - it is provided to maintain SC with v7.0s. sl@0: sl@0: @return The 4CC of the data supplied by this source. sl@0: */ sl@0: TFourCC CMMFAudioInput::DataType() const sl@0: { sl@0: return KMMFFourCCCodePCM16; sl@0: } sl@0: sl@0: sl@0: /** sl@0: Loads audio device drivers and initialise this device. sl@0: */ sl@0: void CMMFAudioInput::LoadL() sl@0: { sl@0: //[ do all the work that can fail first sl@0: // before we modify the internal state ] sl@0: sl@0: iMMFDevSound = CMMFDevSound::NewL(); sl@0: iFirstBufferRequested = EFalse; sl@0: iFirstBufferRead = EFalse; sl@0: if (iState != EDevSoundReady) sl@0: { sl@0: iState = EIdle; sl@0: } sl@0: sl@0: iDevSoundLoaded = ETrue; sl@0: sl@0: //[ assert dev sound has been constructed] sl@0: ASSERT( iMMFDevSound ); sl@0: ASSERT( iDevSoundLoaded ); sl@0: ASSERT( !iFirstBufferRead ); sl@0: } sl@0: sl@0: void CMMFAudioInput::DeviceMessage(TUid /*aMessageType*/, const TDesC8& /* aMsg */) sl@0: { sl@0: } sl@0: sl@0: void CMMFAudioInput::InitializeComplete(TInt aError) sl@0: { sl@0: if (aError == KErrNone) sl@0: { sl@0: iState = EDevSoundReady; sl@0: } sl@0: sl@0: if(iInitializeState == KRequestPending) sl@0: { sl@0: iInitializeState = aError; sl@0: iActiveSchedulerWait->AsyncStop(); sl@0: } sl@0: } sl@0: sl@0: sl@0: /** sl@0: ToneFinished MMFDevSoundObserver - should never get called. sl@0: */ sl@0: void CMMFAudioInput::ToneFinished(TInt /*aError*/) sl@0: { sl@0: //we should never get here during a record session! sl@0: __ASSERT_DEBUG(EFalse,Panic(EMMFAudioInputPanicToneFinishedNotSupported)); sl@0: } sl@0: sl@0: sl@0: /** sl@0: BuffferToBeEmptied MMFDevSoundObserver sl@0: Called when stopped due to error. sl@0: */ sl@0: void CMMFAudioInput::BufferToBeEmptied(CMMFBuffer* aBuffer) sl@0: { sl@0: iDevSoundBuf = aBuffer; sl@0: sl@0: if (iFirstBufferRequested) sl@0: { sl@0: if (iPausePending) sl@0: { sl@0: aBuffer->SetLastBuffer(ETrue); sl@0: iPausePending = EFalse; sl@0: } sl@0: sl@0: #ifdef _DEBUG sl@0: TRAPD(err, iConsumer->BufferFilledL(aBuffer)); sl@0: __ASSERT_DEBUG(!err, Panic(err)); sl@0: #else sl@0: TRAP_IGNORE(iConsumer->BufferFilledL(aBuffer)); sl@0: #endif sl@0: sl@0: iFirstBufferRead = ETrue; sl@0: } sl@0: } sl@0: sl@0: sl@0: /** sl@0: RecordError MMFDevSoundObserver sl@0: Called when stopped due to error. sl@0: */ sl@0: void CMMFAudioInput::RecordError(TInt aError) sl@0: { sl@0: //[ two event categories will be used sl@0: // which mirrors the datapath response ] sl@0: sl@0: //[ record the error ] sl@0: iMMFDevsoundError = aError; sl@0: TMMFEvent event( KMMFEventCategoryPlaybackComplete, aError); sl@0: sl@0: //[ send the event to the client. sl@0: SendEventToClient(event); sl@0: sl@0: // clear flags if there is an error. sl@0: iPausePending = EFalse; sl@0: sl@0: //[ we are not going to stop devsound ] sl@0: } sl@0: sl@0: sl@0: /** sl@0: BufferToBeFilled MMFDevSoundObserver - should never get called. sl@0: */ sl@0: void CMMFAudioInput::BufferToBeFilled(CMMFBuffer* /*aBuffer*/) sl@0: { sl@0: //we should never get here during a play session! sl@0: __ASSERT_DEBUG(EFalse, Panic(EMMFAudioInputPanicPlayerDataUsedNotSupported)); sl@0: } sl@0: sl@0: sl@0: /** sl@0: PlayError MMFDevSoundObserver - should never get called. sl@0: */ sl@0: void CMMFAudioInput::PlayError(TInt /*aError*/) sl@0: { sl@0: //we should never get here during a record session! sl@0: __ASSERT_DEBUG(EFalse, Panic(EMMFAudioInputPanicPlayErrorNotSupported)); sl@0: } sl@0: sl@0: sl@0: /** sl@0: ConvertError MMFDevSoundObserver - should never get called. sl@0: */ sl@0: void CMMFAudioInput::ConvertError(TInt /*aError*/) sl@0: { sl@0: } sl@0: sl@0: sl@0: void CMMFAudioInput::SendEventToClient(const TMMFEvent& aEvent) sl@0: { sl@0: iEventHandler->SendEventToClient(aEvent); sl@0: } sl@0: sl@0: // _________________________________________________________________________ sl@0: // Exported proxy for instantiation method resolution sl@0: // Define the interface UIDs sl@0: sl@0: const TImplementationProxy ImplementationTable[] = sl@0: { sl@0: IMPLEMENTATION_PROXY_ENTRY(KMmfUidAudioInputInterface, CMMFAudioInput::NewSourceL) sl@0: }; sl@0: sl@0: EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount) sl@0: { sl@0: aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy); sl@0: sl@0: return ImplementationTable; sl@0: } sl@0: