--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/omxil/mmilapi/unittest/test_plugins/dummypcmrenderer/dummypcmrenderer.cpp Wed Sep 01 12:38:50 2010 +0100
@@ -0,0 +1,532 @@
+// Copyright (c) 2008-2009 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:
+//
+
+#include "dummypcmrenderer.h"
+#include "iltestuids.hrh"
+#include "tilstructtypes.h"
+#include <ecom/implementationproxy.h>
+#include <mmf/server/mmfdatabuffer.h>
+
+
+#define KDummyPCM16FormatUid 0x10111126 //dummy
+
+const TInt KBufferSize = 16384; // we need 16k to hold a pcm packet
+
+const TInt KDefaultSampleRate = 8000;
+const TInt KDefaultNumberChannels = 1;
+
+const TInt KInputPortIndex = 0;
+
+
+// ------------------------------------------------------------------------------------------
+// CDummyPcmRenderer::CInputPort Implementation
+
+CDummyPcmRenderer::CInputPort::CInputPort(CDummyPcmRenderer& aParent)
+ : CActive(EPriorityNormal),
+ iParent(aParent),
+ iSampleRate(KDefaultSampleRate),
+ iChannels(KDefaultNumberChannels),
+ iBufferSize(KBufferSize)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+CDummyPcmRenderer::CInputPort::~CInputPort()
+ {
+ Cancel();
+ iBuffers.Close();
+ }
+
+CDummyPcmRenderer::CInputPort* CDummyPcmRenderer::CInputPort::NewL(CDummyPcmRenderer& aParent)
+ {
+ CInputPort* self = new (ELeave) CInputPort(aParent);
+ return self;
+ }
+
+TInt CDummyPcmRenderer::CInputPort::FillThisBuffer(CMMFBuffer& /*aInputBuffer*/)
+ {
+ return KErrNotSupported;
+ }
+
+TInt CDummyPcmRenderer::CInputPort::EmptyThisBuffer(const CMMFBuffer& aInputBuffer)
+ {
+ TInt err = iBuffers.Append(&aInputBuffer);
+ if (err == KErrNone)
+ {
+ TILComponentState state;
+ if (iParent.GetState(state) != KErrNone)
+ {
+ return EComponentInvalid;
+ }
+ if (state == EComponentExecuting && !IsActive())
+ {
+ SetActive();
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete(status, KErrNone);
+ }
+ }
+ return err;
+ }
+
+TInt CDummyPcmRenderer::CInputPort::TunnelRequest(MILComponentPortIf* aPort)
+ {
+ TILComponentState state;
+ if (iParent.GetState(state) != KErrNone)
+ {
+ return EComponentInvalid;
+ }
+ if (( state != EComponentLoaded) && (!iStopped))
+ {
+ return EComponentInvalid;
+ }
+
+ if (iPortConnectedTo)
+ {
+ // the port is already connected, return an error
+ return EPortAlreadyTunnelled;
+ }
+ iPortConnectedTo = const_cast<MILComponentPortIf*>(aPort);
+ return KErrNone;
+ }
+
+TInt CDummyPcmRenderer::CInputPort::DisconnectTunnel(MILComponentPortIf* /*aPort*/)
+ {
+ return KErrNotSupported;
+ }
+
+TInt CDummyPcmRenderer::CInputPort::PortIndex() const
+ {
+ return KInputPortIndex;
+ }
+
+TPortDirection CDummyPcmRenderer::CInputPort::PortDirection() const
+ {
+ return EDirInput;
+ }
+
+
+CMMFBuffer* CDummyPcmRenderer::CInputPort::CreateBufferL(TInt /*aBufferSize*/)
+ {
+ User::Leave(KErrNotSupported);
+ return NULL;
+ }
+
+TInt CDummyPcmRenderer::CInputPort::UseBuffer(CMMFBuffer& /*aBuffer*/)
+ {
+ return KErrNotSupported;
+ }
+
+TInt CDummyPcmRenderer::CInputPort::FreeBuffer(CMMFBuffer* /*aBuffer*/)
+ {
+ return KErrNotSupported;
+ }
+
+TInt CDummyPcmRenderer::CInputPort::FlushPort()
+ {
+ return KErrNotSupported;
+ }
+
+TInt CDummyPcmRenderer::CInputPort::EnablePort()
+ {
+ return KErrNotSupported;
+ }
+
+TInt CDummyPcmRenderer::CInputPort::DisablePort()
+ {
+ return KErrNotSupported;
+ }
+
+MILComponentIf* CDummyPcmRenderer::CInputPort::PortComponent() const
+ {
+ return &iParent;
+ }
+
+void CDummyPcmRenderer::CInputPort::SetVolume(TUint aVolume)
+ {
+ iVolume = aVolume;
+ }
+
+TUint CDummyPcmRenderer::CInputPort::Volume()
+ {
+ return iVolume;
+ }
+
+TUint CDummyPcmRenderer::CInputPort::BytesPlayed()
+ {
+ return iBytesPlayed;
+ }
+
+void CDummyPcmRenderer::CInputPort::SetVolumeRamp(const TTimeIntervalMicroSeconds& aRampDuration)
+ {
+ iRampDuration = aRampDuration;
+ }
+
+TTimeIntervalMicroSeconds& CDummyPcmRenderer::CInputPort::VolumeRamp()
+ {
+ return iRampDuration;
+ }
+
+TInt CDummyPcmRenderer::CInputPort::SampleRate()
+ {
+ return iSampleRate;
+ }
+
+TInt CDummyPcmRenderer::CInputPort::Channels()
+ {
+ return iChannels;
+ }
+
+TUint32 CDummyPcmRenderer::CInputPort::BufferSize() const
+ {
+ return iBufferSize;
+ }
+
+void CDummyPcmRenderer::CInputPort::Execute()
+ {
+ if (!IsActive() && iBuffers.Count()>0)
+ {
+ SetActive();
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete(status, KErrNone);
+ }
+ }
+
+void CDummyPcmRenderer::CInputPort::Pause()
+ {
+ if (iParent.SoundDevice().Handle())
+ {
+ iParent.SoundDevice().PausePlayBuffer();
+ }
+ }
+
+void CDummyPcmRenderer::CInputPort::Stop()
+ {
+ Cancel();
+ }
+
+void CDummyPcmRenderer::CInputPort::RunL()
+ {
+
+ if (iCurrentBuffer != NULL)
+ {
+ // If we've been signalled with a buffer, callback that we've completed the writing of the
+ // buffer
+ if (iParent.Observer())
+ {
+ iParent.Observer()->BufferDelivered(this, iCurrentBuffer);
+ if (iCurrentBuffer->LastBuffer())
+ {
+ TILEvent thisEvent;
+ thisEvent.iEvent = EEventBufferFlag;
+ thisEvent.iData1 = PortIndex();
+ thisEvent.iData2 = static_cast<TUint32>(KErrUnderflow);
+ iParent.Observer()->MsgFromILComponent(&iParent, thisEvent);
+ iParent.SoundDevice().Close();
+ }
+ }
+ iCurrentBuffer = NULL;
+ }
+
+ // only process the next buffer if there is no error
+ // error callbacks were handled in the previous block
+ if (iStatus == KErrNone)
+ {
+ if (iBuffers.Count()>0)
+ {
+ iCurrentBuffer = iBuffers[0];
+ iBuffers.Remove(0);
+
+ if (CMMFBuffer::IsSupportedDataBuffer(iCurrentBuffer->Type()))
+ {
+ TDes8& aBufferDes = (static_cast<CMMFDataBuffer*>(iCurrentBuffer))->Data();
+ iStatus = KRequestPending;
+ iParent.SoundDevice().PlayData(iStatus, aBufferDes);
+ SetActive();
+ }
+ }
+ }
+ else
+ {
+ // In the real implementation here should be sending an error event back to the client
+ }
+ }
+
+void CDummyPcmRenderer::CInputPort::DoCancel()
+ {
+ if (iParent.SoundDevice().Handle())
+ {
+ iParent.SoundDevice().CancelPlayData();
+ iParent.SoundDevice().FlushPlayBuffer();
+ }
+ }
+
+// ------------------------------------------------------------------------------------------
+// CDummyPcmRenderer Implementation
+
+CDummyPcmRenderer::CDummyPcmRenderer()
+ {
+ }
+
+CDummyPcmRenderer::~CDummyPcmRenderer()
+ {
+ delete iInputPort;
+ iSoundDevice.Close();
+ }
+
+CDummyPcmRenderer* CDummyPcmRenderer::NewL()
+ {
+ CDummyPcmRenderer* self = new (ELeave) CDummyPcmRenderer;
+ return self;
+ }
+
+void CDummyPcmRenderer::CreateComponentL(const TDesC8& /*aComponentName*/, MILIfObserver& aComponentIfObserver)
+ {
+ iObserver = &aComponentIfObserver;
+ iInputPort = CInputPort::NewL(*this);
+ iState = EComponentLoaded;
+ }
+
+void CDummyPcmRenderer::CreateComponentL(const TUid& /*aUid*/, MILIfObserver& /*aComponentIfObserver*/)
+ {
+ User::LeaveIfError(KErrNotSupported);
+ };
+
+void CDummyPcmRenderer::ReleaseComponent()
+ {
+ delete this;
+ }
+
+TInt CDummyPcmRenderer::GetComponentInputPorts(RPointerArray<MILComponentPortIf>& aComponentPorts) const
+ {
+ return aComponentPorts.Append(iInputPort);
+ }
+
+TInt CDummyPcmRenderer::GetComponentOutputPorts(RPointerArray<MILComponentPortIf>& /*aComponentPorts*/) const
+ {
+ return KErrNotSupported;
+ }
+
+TInt CDummyPcmRenderer::SetConfig(const TILStruct& aConfig, const MILComponentPortIf* /*aComponentPort*/)
+ {
+ if (aConfig.Uid() == TUid::Uid(KUidMMFTTaskConfig))
+ {
+ const TTaskConfig* config = TILTaskConfig::GetStructure(aConfig);
+ ASSERT(config);
+ iInputPort->iSampleRate = config->iRate;
+ iInputPort->iChannels = (config->iStereoMode & ETaskMono)? 1 : 2;
+ iInputPort->iInterleaved = (config->iStereoMode & ETaskInterleaved)?ETrue : EFalse;
+ return KErrNone;
+ }
+
+ return KErrNotSupported;
+ }
+
+TInt CDummyPcmRenderer::GetConfig(TILStruct& /*aConfig*/, const MILComponentPortIf* /*aComponentPort*/) const
+ {
+ return KErrNotSupported;
+ }
+
+TInt CDummyPcmRenderer::Initialize()
+ {
+ ASSERT(iObserver);
+
+ TILEvent thisEvent;
+ thisEvent.iEvent = EEventCmdComplete;
+ thisEvent.iData1 = ECommandStateSet;
+ thisEvent.iData2 = EComponentIdle;
+ iObserver->MsgFromILComponent(this, thisEvent);
+
+ iState = EComponentIdle;
+ return KErrNone;
+ }
+
+TInt CDummyPcmRenderer::UnInitialize()
+ {
+ ASSERT(iObserver);
+
+ TILEvent thisEvent;
+ thisEvent.iEvent = EEventCmdComplete;
+ thisEvent.iData1 = ECommandStateSet;
+ thisEvent.iData2 = EComponentLoaded;
+ iObserver->MsgFromILComponent(this, thisEvent);
+
+ iState = EComponentLoaded;
+ return KErrNone;
+ }
+
+TInt CDummyPcmRenderer::Execute()
+ {
+ ASSERT(iObserver);
+ TInt err = KErrNone;
+ if(!iSoundDevice.Handle())
+ {
+ err = iSoundDevice.Open();
+ }
+
+ RMdaDevSound::TCurrentSoundFormatBuf buf;
+ if (err == KErrNone)
+ {
+ if(iState == EComponentPaused)
+ {
+ iSoundDevice.ResumePlaying();
+ }
+ else
+ {
+ // Set play format (for input port)
+ iSoundDevice.GetPlayFormat(buf);
+ buf().iRate = iInputPort->SampleRate();
+ buf().iChannels = iInputPort->Channels();
+ buf().iBufferSize = KBufferSize;
+ buf().iEncoding = RMdaDevSound::EMdaSoundEncoding16BitPCM;
+ err = iSoundDevice.SetPlayFormat(buf);
+ }
+ }
+ iState = EComponentExecuting;
+
+ TILEvent thisEvent;
+ thisEvent.iEvent = EEventCmdComplete;
+ thisEvent.iData1 = ECommandStateSet;
+ thisEvent.iData2 = EComponentExecuting;
+ iObserver->MsgFromILComponent(this, thisEvent);
+
+ return err;
+ }
+
+TInt CDummyPcmRenderer::Pause()
+ {
+ iState = EComponentPaused;
+ iInputPort->Pause();
+ return KErrNone;
+ }
+
+TInt CDummyPcmRenderer::Stop()
+ {
+ if(iState == EComponentExecuting || iState == EComponentPaused)
+ {
+ // Cancel and flush the device driver
+ iInputPort->Stop();
+
+ TILEvent thisEvent;
+ thisEvent.iEvent = EEventCmdComplete;
+ thisEvent.iData1 = ECommandStateSet;
+ thisEvent.iData2 = EComponentIdle;
+ iObserver->MsgFromILComponent(this, thisEvent);
+
+ iState = EComponentIdle;
+
+ // Close the sound device
+ iSoundDevice.Close();
+
+ return KErrNone;
+ }
+ else
+ {
+ // invalid state
+ return EComponentInvalid;
+ }
+ }
+
+TInt CDummyPcmRenderer::GetState(TILComponentState& aState) const
+ {
+ aState = iState;
+ return KErrNone;
+ }
+
+TInt CDummyPcmRenderer::SendCommand(const TILCommand& /*aCommand*/)
+ {
+ return KErrNotSupported;
+ }
+
+TInt CDummyPcmRenderer::FlushAllPorts()
+ {
+ return KErrNotSupported;
+ }
+
+TInt CDummyPcmRenderer::ComponentRoleEnum(TPtr8& /*aComponentRole*/, TUint32 /*aIndex*/) const
+ {
+ return KErrNotSupported;
+ }
+
+TInt CDummyPcmRenderer::GetComponentVersion(TILComponentVersion& /*aVersion*/) const
+ {
+ return KErrNotSupported;
+ }
+
+TInt CDummyPcmRenderer::SetComponentIfRole(const TDesC8& /*aComponentRole*/)
+ {
+ return KErrNotSupported;
+ }
+
+TInt CDummyPcmRenderer::GetComponentIfRole(TDes8& /*aComponentRole*/) const
+ {
+ return KErrNotSupported;
+ }
+
+TInt CDummyPcmRenderer::SetComponentIfRole(const TUid& /*aFormat*/)
+ {
+ // This interface is specific writen to support only this PCM renderer role
+ return KErrNotSupported;
+ }
+
+TInt CDummyPcmRenderer::GetComponentIfRole(TUid& aFormat) const
+ {
+ aFormat = TUid::Uid(KDummyPCM16FormatUid);
+ return KErrNone;
+ }
+
+TAny* CDummyPcmRenderer::CustomInterface(TUid aUid)
+ {
+ if (aUid.iUid == KMmfPlaySettingsCustomInterface)
+ {
+ return static_cast<MPlayCustomInterface*>(iInputPort);
+ }
+ return NULL;
+ }
+
+TInt CDummyPcmRenderer::SetExtConfig(const TDesC8& /*aParameterName*/, const TILStruct& /*aConfig*/, const MILComponentPortIf* /*aComponentPort*/)
+ {
+ return KErrNotSupported;
+ }
+
+TInt CDummyPcmRenderer::GetExtConfig(const TDesC8& /*aParameterName*/, TILStruct& /*aConfig*/, const MILComponentPortIf* /*aComponentPort*/) const
+ {
+ return KErrNotSupported;
+ }
+
+
+MILIfObserver* CDummyPcmRenderer::Observer() const
+ {
+ return iObserver;
+ }
+
+RMdaDevSound& CDummyPcmRenderer::SoundDevice()
+ {
+ return iSoundDevice;
+ }
+
+
+// ------------------------------------------------------------------------------------------
+// ECOM Implementation table entry
+
+const TImplementationProxy ImplementationTable[] =
+ {
+ IMPLEMENTATION_PROXY_ENTRY(KUidDummyPcmRendererMILIFPlugin, CDummyPcmRenderer::NewL),
+ };
+
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
+ {
+ aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
+ return ImplementationTable;
+ }