--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/devsound/devsoundrefplugin/tsrc/a3fcistubextn/a3fcistubextn.cpp Fri Oct 08 19:40:43 2010 +0100
@@ -0,0 +1,308 @@
+// 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 "a3fcistubextn.h"
+#include <ecom/ecom.h>
+#include <ecom/implementationproxy.h>
+#include "a3fcistubextn.hrh"
+
+#include <a3f/maudiocontext.h>
+#include <a3f/maudiostream.h>
+#include <a3f/maudioprocessingunit.h>
+#include <a3f/maudiogaincontrol.h>
+#include <a3f/audioprocessingunittypeuids.h>
+
+//
+#include "a3fbackdooraccess.h"
+#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
+#include <mmf/common/mmfipcserver.h>
+#endif
+
+
+// __________________________________________________________________________
+// Client-side extension
+
+MDevSoundCIClientExtension* CA3fClientCiStubExtn::NewL()
+ {
+ CA3fClientCiStubExtn* self = new (ELeave) CA3fClientCiStubExtn;
+ return self;
+ }
+
+CA3fClientCiStubExtn::~CA3fClientCiStubExtn()
+ {
+ delete iDummyBuffer;
+ REComSession::DestroyedImplementation(iKey);
+ }
+
+TInt CA3fClientCiStubExtn::Setup(MCustomCommand& aCustomCommand)
+ {
+ iCommand = &aCustomCommand;
+ iDummyBuffer=KNullDesC().Alloc(); // dummy buffer simulates some allocs
+ if (!iDummyBuffer)
+ {
+ return KErrNoMemory;
+ }
+ return KErrNone;
+ }
+
+TInt CA3fClientCiStubExtn::CustomInterfaceExtension(TUid aUid, TAny*& aInterface)
+ {
+ if (aUid==KUidTestSetVolIf)
+ {
+ MTestSetVolIf* interface = this;
+ aInterface = interface;
+ return KErrNone;
+ }
+ return KErrNotSupported;
+ }
+
+void CA3fClientCiStubExtn::Release()
+ {
+ delete this;
+ }
+
+void CA3fClientCiStubExtn::PassDestructorKey(TUid aDestructorKey)
+ {
+ iKey = aDestructorKey;
+ }
+
+TInt CA3fClientCiStubExtn::SetVol(TInt aVol)
+ {
+ // the key here is the destination package, which represets SetVol. Apart from value
+ // the rest of the parameters can be ignored
+ TPckgBuf<TInt> volumePkg (aVol);
+ TMMFMessageDestinationPckg setVolDest (TMMFMessageDestination(KUidTestSetVolIf, 0));
+ TInt result = iCommand->CustomCommandSync(setVolDest, ETestSetVolIfSetVolCommand, volumePkg, KNullDesC8);
+ return result;
+ }
+
+TInt CA3fClientCiStubExtn::Vol(TInt aMaxVol)
+ {
+ // again the key is is the destination package
+ TPckgBuf<TInt> maxVolPkg (aMaxVol);
+ TMMFMessageDestinationPckg setVolDest (TMMFMessageDestination(KUidTestSetVolIf, 0));
+ TInt result = iCommand->CustomCommandSync(setVolDest, ETestSetVolIfVolCommand, maxVolPkg, KNullDesC8);
+ return result;
+ }
+
+// __________________________________________________________________________
+// Server-side extension
+
+MDevSoundCIServerExtension* CA3fServerCiStubExtn::NewL()
+ {
+ CA3fServerCiStubExtn* self = new (ELeave) CA3fServerCiStubExtn;
+ return self;
+ }
+
+CA3fServerCiStubExtn::~CA3fServerCiStubExtn()
+ {
+ delete iDummyBuffer;
+ delete iSetVol;
+ REComSession::DestroyedImplementation(iKey);
+ }
+
+TInt CA3fServerCiStubExtn::Setup(MCustomInterface& aCustomInterface)
+ {
+ iInterface = &aCustomInterface;
+ iDummyBuffer=KNullDesC().Alloc(); // dummy buffer simulates some allocs
+ if (!iDummyBuffer)
+ {
+ return KErrNoMemory;
+ }
+ return KErrNone;
+ }
+
+TInt CA3fServerCiStubExtn::HandleMessageL(const RMmfIpcMessage& aMessage)
+ {
+ TMMFMessageDestinationPckg destinationPckg;
+ MmfMessageUtil::ReadL(aMessage, 0, destinationPckg);
+ if (destinationPckg().InterfaceId()==KUidTestSetVolIf)
+ {
+ CSetVol* volHandler = CSetVol::NewL(*iInterface);
+ CleanupStack::PushL(volHandler);
+ TInt result = volHandler->HandleMessageL(aMessage);
+ CleanupStack::Pop(volHandler);
+ return result;
+ }
+
+ return KErrNotSupported;
+ }
+
+void CA3fServerCiStubExtn::Release()
+ {
+ delete this;
+ }
+
+void CA3fServerCiStubExtn::PassDestructorKey(TUid aDestructorKey)
+ {
+ iKey = aDestructorKey;
+ }
+
+// CSetVol
+
+CSetVol* CSetVol::NewL(MCustomInterface& aCustomInterface)
+ {
+ CSetVol* self = new (ELeave) CSetVol(aCustomInterface);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+CSetVol::CSetVol(MCustomInterface& aCustomInterface):
+ iInterface(&aCustomInterface)
+ {
+ // do nothing
+ }
+
+void CSetVol::ConstructL()
+ {
+ iWait = new (ELeave) CActiveSchedulerWait();
+ }
+
+CSetVol::~CSetVol()
+ {
+ delete iWait;
+ }
+
+TInt CSetVol::HandleMessageL(const RMmfIpcMessage& aMessage)
+ {
+ switch (aMessage.Function())
+ {
+ case ETestSetVolIfSetVolCommand:
+ {
+ TPckgBuf<TInt> volPckg;
+ MmfMessageUtil::ReadL(aMessage, 1, volPckg);
+ UpdateA3fPointers(); // grab pointers to context, stream etc
+ SetVolumeL(volPckg());
+
+ User::LeaveIfError(iContext->RegisterAudioContextObserver(*this));
+
+ TInt error = iContext->Commit();
+ if (!error)
+ {
+ iError = KErrNone;
+ iWait->Start();
+ error = iError;
+ }
+ (void) iContext->UnregisterAudioContextObserver(*this);
+
+ aMessage.Complete(error);
+ return KErrNone; // KErrNone says we've handled the message
+ }
+ case ETestSetVolIfVolCommand:
+ {
+ TPckgBuf<TInt> maxVolPckg;
+ MmfMessageUtil::ReadL(aMessage, 1, maxVolPckg);
+ UpdateA3fPointers(); // grab pointers to context, stream etc
+ TInt result = VolumeL(maxVolPckg());
+ aMessage.Complete(result);
+ return KErrNone; // KErrNone says we've handled the message
+ }
+ default:
+ return KErrArgument;
+ }
+ }
+
+void CSetVol::UpdateA3fPointers()
+ {
+ MA3FBackdoorAccessIf* backdoor =
+ static_cast<MA3FBackdoorAccessIf*>(iInterface->CustomInterface(KA3FBackdoorAccessIfUid));
+ if (backdoor)
+ {
+ iContext = backdoor->AudioContext();
+ iStream = backdoor->AudioStream();
+ iGain = backdoor->ProcessingUnit(KUidAudioGainControl);
+ }
+ else
+ {
+ iContext = NULL;
+ iStream = NULL;
+ iGain = NULL;
+ }
+ }
+
+void CSetVol::SetVolumeL(TInt aVolume)
+ {
+ RArray<TAudioChannelGain> channelGains;
+ CleanupClosePushL(channelGains);
+ TAudioChannelGain left;
+ TAudioChannelGain right;
+ left.iLocation = TAudioChannelGain::ELeft;
+ right.iLocation = TAudioChannelGain::ERight;
+ left.iGain = right.iGain = aVolume;
+ User::LeaveIfError(channelGains.Append(left)); // assumed element 0 in rest of code
+ User::LeaveIfError(channelGains.Append(right)); // assumed element 1 in rest of code
+
+ MAudioGainControl* gainControl = static_cast<MAudioGainControl*>(iGain->Interface(KUidAudioGainControl));
+ User::LeaveIfError(gainControl->SetGain(channelGains));
+ CleanupStack::PopAndDestroy(&channelGains);
+ }
+
+TInt CSetVol::VolumeL(TInt aMaxVolume)
+ {
+ RArray<TAudioChannelGain> channelGains;
+ CleanupClosePushL(channelGains);
+ TInt maxGain;
+
+ MAudioGainControl* gainControl = static_cast<MAudioGainControl*>(iGain->Interface(KUidAudioGainControl));
+ User::LeaveIfError(gainControl->GetGain(channelGains));
+ User::LeaveIfError(gainControl->GetMaxGain(maxGain));
+
+ TInt basicVolume = (channelGains[0].iGain + channelGains[1].iGain) / 2;
+ TInt result = basicVolume * aMaxVolume / maxGain; // scale to 0 to maxVolume
+
+ CleanupStack::PopAndDestroy(&channelGains);
+ return result;
+ }
+
+void CSetVol::ContextEvent(TUid aEvent, TInt aError)
+ {
+ if (aEvent==KUidA3FContextUpdateComplete || aEvent==KUidA3FContextAbort)
+ {
+ // we are going to assume the SetGain() works and use the end of
+ // the ContextEvent. Really should observe the gain itself
+ if (aError)
+ {
+ iError = aError;
+ }
+ iWait->AsyncStop();
+ }
+ }
+
+//
+// ImplementationTable
+//
+
+const TImplementationProxy ImplementationTable[] =
+ {
+ IMPLEMENTATION_PROXY_ENTRY(KUidA3fClientCiStubExtn, CA3fClientCiStubExtn::NewL),
+ IMPLEMENTATION_PROXY_ENTRY(KUidA3fServerCiStubExtn, CA3fServerCiStubExtn::NewL),
+ };
+
+
+//
+// ImplementationGroupProxy
+//
+//
+
+EXPORT_C const TImplementationProxy* ImplementationGroupProxy(TInt& aTableCount)
+ {
+ aTableCount = sizeof(ImplementationTable) / sizeof(TImplementationProxy);
+
+ return ImplementationTable;
+ }
+
+