--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/audiostubs/devsoundextensions_stubs/mmfdevsoundadaptation_stub/src/MmfHwDeviceStub.cpp Thu Jan 14 07:14:53 2010 +0200
@@ -0,0 +1,493 @@
+/*
+* Copyright (c) 2002-2005 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Audio Stubs -
+*
+*/
+
+
+
+// INCLUDE FILES
+#include "MmfHwDeviceStub.h"
+#ifdef _DEBUG
+#include "e32debug.h"
+
+#define DEBPRN0(str) RDebug::Print(str, this)
+#define DEBPRN1(str, val1) RDebug::Print(str, this, val1)
+#define DEBPRN2(str, val1, val2) RDebug::Print(str, this, val1, val2)
+#else
+#define DEBPRN0(str)
+#define DEBPRN1(str, val1)
+#define DEBPRN2(str, val1, val2)
+#endif //_DEBUG
+
+// CONSTANTS
+const TUint KBufferLength1 = 0x1000;
+const TUint KBufferLength2 = 0x1000;
+//const TUint KBufferLength2 = 0x1800; // for creating second buffer with different length than the first buffer.
+const TUint KTimerDuration = 200000;
+
+#ifdef __WINSCW__
+_LIT(KSample1,"C:\\sample1.wav");
+#else
+_LIT(KSample1,"Z:\\system\\data\\DevSoundAdaptationStub\\sample1.wav");
+#endif // __WINSCW__
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CMMFHwDeviceStub::CMMFHwDeviceStub
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CMMFHwDeviceStub::CMMFHwDeviceStub()
+: CActive(EPriorityNormal), iHwDeviceState(EHWDeviceIdle), iCurPlayBuffer(NULL),
+ iCurRecdBuffer(NULL)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+// -----------------------------------------------------------------------------
+// CMMFHwDeviceStub::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CMMFHwDeviceStub::ConstructL()
+ {
+ DEBPRN0(_L("CMMFHwDeviceStub[0x%x]::ConstructL:BEGIN"));
+ // Create timer
+ User::LeaveIfError(iTimer.CreateLocal());
+ DEBPRN0(_L("CMMFHwDeviceStub[0x%x]::ConstructL:END"));
+ }
+
+// -----------------------------------------------------------------------------
+// CMMFHwDeviceStub::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CMMFHwDeviceStub* CMMFHwDeviceStub::NewL()
+ {
+ CMMFHwDeviceStub* self = new (ELeave)CMMFHwDeviceStub;
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CMMFHwDeviceStub::~CMMFHwDeviceStub
+// Destructor
+// -----------------------------------------------------------------------------
+//
+CMMFHwDeviceStub::~CMMFHwDeviceStub()
+ {
+ DEBPRN0(_L("CMMFHwDeviceStub[0x%x]::~CMMFHwDeviceStub:BEGIN"));
+ // Cancel A/O and close the timer
+ Cancel();
+ iTimer.Close();
+
+ // Delete buffers
+ delete iPlayBuffer1;
+ delete iPlayBuffer2;
+ delete iRecdBuffer1;
+ delete iRecdBuffer2;
+
+ DEBPRN0(_L("CMMFHwDeviceStub[0x%x]::~CMMFHwDeviceStub:END"));
+ }
+
+//-----------------------------------------------------------------------------
+// CMMFHwDeviceStub::Start
+// Starts playback/record based on aFuncCmd
+// (other items were commented in a header).
+//-----------------------------------------------------------------------------
+TInt CMMFHwDeviceStub::Start(TDeviceFunc aFuncCmd, TDeviceFlow /*aFlowCmd*/)
+ {
+ DEBPRN0(_L("CMMFHwDeviceStub[0x%x]::Start:BEGIN"));
+ TInt status(KErrNone);
+ switch(aFuncCmd)
+ {
+ case EDevDecode:
+ iCurPlayBuffer = NULL;
+
+ // Initialize buffers
+ TRAP(status, InitializePlayBufferL());
+ if (status != KErrNone)
+ return status;
+
+ // Reset buffers rendered count to zero only if not pause-continue
+ if (iHwDeviceState == EHWDeviceIdle)
+ iCount = 0;
+ // Initialize attributes
+ iHwDeviceState = EHWDevicePlay;
+ iLastBufferReceived = EFalse;
+ // If not already active, launch timer
+ if (!IsActive())
+ {
+ iTimer.After(iStatus,TTimeIntervalMicroSeconds32(KTimerDuration) );
+ SetActive();
+ }
+ break;
+ case EDevEncode:
+ iCurRecdBuffer = NULL;
+
+ // Initialize buffers
+ TRAP(status, InitializeRecdBufferL());
+ if (status != KErrNone)
+ return status;
+
+ // Reset buffers rendered count to zero only if not pause-continue
+ if (iHwDeviceState == EHWDeviceIdle)
+ iCount = 0;
+ // Initialize attributes
+ iHwDeviceState = EHWDeviceRecord;
+ // If not already active, launch timer
+ if (!IsActive())
+ {
+ iTimer.After(iStatus,TTimeIntervalMicroSeconds32(KTimerDuration) );
+ SetActive();
+ }
+ break;
+ default:
+ status = KErrNotSupported;
+ break;
+ };
+ DEBPRN0(_L("CMMFHwDeviceStub[0x%x]::Start:END"));
+ return status;
+ }
+
+//-----------------------------------------------------------------------------
+// CMMFHwDeviceStub::Stop
+// Stops current operation.
+// (other items were commented in a header).
+//-----------------------------------------------------------------------------
+TInt CMMFHwDeviceStub::Stop()
+ {
+ DEBPRN0(_L("CMMFHwDeviceStub[0x%x]::Stop"));
+ TInt status(KErrNone);
+ // Cancel any outstanding requests
+ Cancel();
+ // Reset attributes
+ iHwDeviceState = EHWDeviceIdle;
+ iLastBufferReceived = EFalse;
+ iCurPlayBuffer = NULL;
+ iCurRecdBuffer = NULL;
+ // Notify observer Stopped
+ iObserver->Stopped();
+ return status;
+ }
+
+//-----------------------------------------------------------------------------
+// CMMFHwDeviceStub::Pause
+// Pauses current operation.
+// (other items were commented in a header).
+//-----------------------------------------------------------------------------
+TInt CMMFHwDeviceStub::Pause()
+ {
+ DEBPRN0(_L("CMMFHwDeviceStub[0x%x]::Pause"));
+ TInt status(KErrNone);
+
+ // Fix to WAV recording issue.
+ // Proper way to stop this A/O is by letting the data path to call back
+ // Stop() after detecting last buffer.
+// Cancel();
+ return status;
+ }
+
+//-----------------------------------------------------------------------------
+// CMMFHwDeviceStub::Init
+// Initializes CMMFHwDevice.
+// (other items were commented in a header).
+//-----------------------------------------------------------------------------
+TInt CMMFHwDeviceStub::Init(THwDeviceInitParams& aDevInfo)
+ {
+ DEBPRN0(_L("CMMFHwDeviceStub[0x%x]::Init"));
+ TInt status(KErrNone);
+ iObserver = aDevInfo.iHwDeviceObserver;
+ return status;
+ }
+
+//-----------------------------------------------------------------------------
+// CMMFHwDeviceStub::CustomInterface
+// Returns a pointer to CustomInterface.
+// (other items were commented in a header).
+//-----------------------------------------------------------------------------
+TAny* CMMFHwDeviceStub::CustomInterface(TUid /*aInterfaceId*/)
+ {
+ return NULL;
+ }
+
+//-----------------------------------------------------------------------------
+// CMMFHwDeviceStub::ThisHwBufferFilled
+// Returns a pointer to CustomInterface.
+// (other items were commented in a header).
+//-----------------------------------------------------------------------------
+TInt CMMFHwDeviceStub::ThisHwBufferFilled(CMMFBuffer& aFillBufferPtr)
+ {
+ DEBPRN2(_L("CMMFHwDeviceStub[0x%x]::ThisHwBufferFilled:Addr[0x%x]Count[%d]"), iCurPlayBuffer, ++iCount);
+ TInt status(KErrNotReady);
+ if (iHwDeviceState == EHWDevicePlay)
+ {
+ status = KErrNone;
+ if (aFillBufferPtr.LastBuffer())
+ {
+ iLastBufferReceived = ETrue;
+ DEBPRN0(_L("CMMFHwDeviceStub[0x%x]::ThisHwBufferFilled[LastBuffer]"));
+ }
+
+ // If not already active, launch timer
+ if (!IsActive())
+ {
+ iTimer.After(iStatus,TTimeIntervalMicroSeconds32(KTimerDuration) );
+ SetActive();
+ }
+ }
+ return status;
+ }
+
+//-----------------------------------------------------------------------------
+// CMMFHwDeviceStub::ThisHwBufferEmptied
+// Called by client when data is available during recording.
+// (other items were commented in a header).
+//-----------------------------------------------------------------------------
+TInt CMMFHwDeviceStub::ThisHwBufferEmptied(CMMFBuffer& aEmptyBufferPtr)
+ {
+ DEBPRN1(_L("CMMFHwDeviceStub[0x%x]::ThisHwBufferEmptied[%d]"), ++iCount);
+ TInt status(KErrNotReady);
+ if (iHwDeviceState == EHWDeviceRecord)
+ {
+ status = KErrNone;
+
+ // Fix to WAV recording issue.
+ // In case of real DevSound adaptation implementation, the
+ // CMMFSwCodecRecordDataPath sets the last buffer parameter when no
+ // more data is in the buffer to process. In case of the stub, this
+ // never gets set as the s/w codec is not involved - we are simply
+ // copying same fixed 4k block of data over and over again. So, on
+ // pause or stop we need to indicate to the data path that we no
+ // longer need processing of data by manually setting last buffer
+ // parameter and resetting requested data size to 0.
+ if (aEmptyBufferPtr.LastBuffer())
+ {
+ iRecdBuffer1->SetLastBuffer(ETrue);
+ iRecdBuffer1->SetRequestSizeL(0);
+ iRecdBuffer2->SetLastBuffer(ETrue);
+ iRecdBuffer2->SetRequestSizeL(0);
+ }
+
+ // If not already active, launch timer
+ if (!IsActive())
+ {
+ iTimer.After(iStatus,TTimeIntervalMicroSeconds32(KTimerDuration) );
+ SetActive();
+ }
+ }
+
+ return status;
+ }
+
+//-----------------------------------------------------------------------------
+// CMMFHwDeviceStub::SetConfig
+// Configures CMMFHwDevice.
+// (other items were commented in a header).
+//-----------------------------------------------------------------------------
+TInt CMMFHwDeviceStub::SetConfig(TTaskConfig& /*aConfig*/)
+ {
+ DEBPRN0(_L("CMMFHwDeviceStub[0x%x]::SetConfig"));
+ TInt status(KErrNone);
+ return status;
+ }
+
+//-----------------------------------------------------------------------------
+// CMMFHwDeviceStub::StopAndDeleteCodec
+// Stops and deletes codec.
+// (other items were commented in a header).
+//-----------------------------------------------------------------------------
+TInt CMMFHwDeviceStub::StopAndDeleteCodec()
+ {
+ DEBPRN0(_L("CMMFHwDeviceStub[0x%x]::StopAndDeleteCodec"));
+ TInt status(KErrNone);
+ Stop();
+ return status;
+ }
+
+//-----------------------------------------------------------------------------
+// CMMFHwDeviceStub::DeleteCodec
+// Deletes codec.
+// (other items were commented in a header).
+//-----------------------------------------------------------------------------
+TInt CMMFHwDeviceStub::DeleteCodec()
+ {
+ DEBPRN0(_L("CMMFHwDeviceStub[0x%x]::DeleteCodec"));
+ TInt status(KErrNone);
+ Stop();
+ return status;
+ }
+
+
+//-----------------------------------------------------------------------------
+// CMMFHwDeviceStub::RunL
+// Called by CActive object framework when local timer times out.
+// (other items were commented in a header).
+//-----------------------------------------------------------------------------
+void CMMFHwDeviceStub::RunL()
+ {
+ DEBPRN1(_L("CMMFHwDeviceStub[0x%x]::RunL:iHwDevState[%d]"), iHwDeviceState);
+ switch(iHwDeviceState)
+ {
+ case EHWDevicePlay:
+ // If last buffer is received, send error
+ if (iLastBufferReceived)
+ {
+ iObserver->Error(KErrUnderflow);
+ Stop();
+ }
+ else
+ {
+ SetActivePlayBufferL();
+ iObserver->FillThisHwBuffer(*iCurPlayBuffer);
+ }
+ break;
+ case EHWDeviceRecord:
+ SetActiveRecdBufferL();
+ iObserver->EmptyThisHwBuffer(*iCurRecdBuffer);
+ break;
+ default:
+ break;
+ }
+ }
+
+//-----------------------------------------------------------------------------
+// CMMFHwDeviceStub::DoCancel
+// From CActive. Called by Framework when this instance is active and is
+// cancelled
+//-----------------------------------------------------------------------------
+void CMMFHwDeviceStub::DoCancel()
+ {
+ DEBPRN0(_L("CMMFHwDeviceStub[0x%x]::DoCancel"));
+ iTimer.Cancel();
+ }
+
+//-----------------------------------------------------------------------------
+// CMMFHwDeviceStub::Error
+// From CActive. Called by Framework when RunL Leaves
+//-----------------------------------------------------------------------------
+TInt CMMFHwDeviceStub::Error(TInt /*aError*/)
+ {
+ return KErrNone;
+ }
+
+//-----------------------------------------------------------------------------
+// CMMFHwDeviceStub::InitializePlayBufferL
+// Initializes buffer(s) used for playback
+//-----------------------------------------------------------------------------
+void CMMFHwDeviceStub::InitializePlayBufferL()
+ {
+ if (!iPlayBuffer1)
+ {
+ // Create buffers
+ iPlayBuffer1 = CMMFDataBuffer::NewL(KBufferLength1);
+ }
+ if (!iPlayBuffer2)
+ {
+ // Create buffers
+ iPlayBuffer2 = CMMFDataBuffer::NewL(KBufferLength2);
+ }
+ }
+
+//-----------------------------------------------------------------------------
+// CMMFHwDeviceStub::InitializeRecdBufferL
+// Initializes buffer(s) used for recording
+//-----------------------------------------------------------------------------
+void CMMFHwDeviceStub::InitializeRecdBufferL()
+ {
+ if (!iRecdBuffer1)
+ {
+ DEBPRN0(_L("CMMFHwDeviceStub[0x%x]::InitializeRecdBufferL:Creating buffer..."));
+ // Create buffers
+ iRecdBuffer1 = CMMFDataBuffer::NewL(KBufferLength1);
+ }
+
+ if (!iRecdBuffer2)
+ {
+ DEBPRN0(_L("CMMFHwDeviceStub[0x%x]::InitializeRecdBufferL:Creating buffer..."));
+ // Create buffers
+ iRecdBuffer2 = CMMFDataBuffer::NewL(KBufferLength2);
+ }
+
+ iPosition = 0;
+
+ }
+
+//-----------------------------------------------------------------------------
+// CMMFHwDeviceStub::SetActiveRecdBufferL
+// Reads data from the input file to the buffer
+//-----------------------------------------------------------------------------
+void CMMFHwDeviceStub::SetActiveRecdBufferL()
+ {
+ if ( !iCurRecdBuffer || ( iCurRecdBuffer == iRecdBuffer2 ) )
+ {
+ iCurRecdBuffer = iRecdBuffer1;
+ }
+ else
+ {
+ iCurRecdBuffer = iRecdBuffer2;
+ }
+
+ if ( !iCurRecdBuffer->LastBuffer() )
+ {
+ RFs rFs;
+ RFile rFile;
+ User::LeaveIfError(rFs.Connect());
+ User::LeaveIfError(rFile.Open(rFs, KSample1, EFileRead));
+
+ TInt size;
+ User::LeaveIfError(rFile.Size(size));
+ TInt bufLength( iCurRecdBuffer->Data().MaxLength() );
+ if (iPosition > (size - bufLength))
+ {
+ iPosition = 0; //rewind file position index to the beginning
+ }
+ // Assumption, file size is more than iCurRecdBuffer->Data().MaxLength()
+ User::LeaveIfError(rFile.Read(iPosition,
+ iCurRecdBuffer->Data(),
+ bufLength) );
+ iCurRecdBuffer->SetRequestSizeL(bufLength);
+ iCurRecdBuffer->SetLastBuffer(EFalse);
+ rFile.Close();
+ rFs.Close();
+
+ iPosition += bufLength;
+ }
+ }
+
+//-----------------------------------------------------------------------------
+// CMMFHwDeviceStub::SetActivePlayBufferL
+// Reads data from the input file to the buffer
+//-----------------------------------------------------------------------------
+void CMMFHwDeviceStub::SetActivePlayBufferL()
+ {
+ if ( !iCurPlayBuffer || ( iCurPlayBuffer == iPlayBuffer2 ) )
+ {
+ iCurPlayBuffer = iPlayBuffer1;
+ }
+ else
+ {
+ iCurPlayBuffer = iPlayBuffer2;
+ }
+ iCurPlayBuffer->SetRequestSizeL(iCurPlayBuffer->Data().MaxLength());
+ iCurPlayBuffer->Data().SetLength(0);
+ iCurPlayBuffer->SetLastBuffer(EFalse);
+ }
+
+//End of File