diff -r 000000000000 -r a41df078684a bsptemplate/asspandvariant/template_variant/specific/soundsc_tx.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bsptemplate/asspandvariant/template_variant/specific/soundsc_tx.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,553 @@ +// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "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: +// template\template_variant\specific\soundsc_tx.cpp +// Implementation of the Template playback shared chunk sound physical device driver (PDD). +// This file is part of the Template Base port +// +// + +/** + @file +*/ + +#include "soundsc_plat.h" + +// TO DO: (mandatory) +// Declare a name for this driver. The format of this name should be +// "SoundSc.xxxx" where xxxx is the variant name. +_LIT(KSoundScPddName,"SoundSc.Template"); + +// Definitions for the kernel thread created for this sound driver. +_LIT(KSoundScDriverThreadName,"SoundDriverThread"); +const TInt KSoundScDriverThreadPriority=26; // One less than DFC thread 0 + +/** +Define a function at ordinal 0 which returns a new instance of a DPhysicalDevice-derived factory class. +*/ +DECLARE_STANDARD_PDD() + { + return new DTemplateSoundScPddFactory; + } + +/** +Constructor for the shared chunk sound PDD factory class. +*/ +DTemplateSoundScPddFactory::DTemplateSoundScPddFactory() + { + __KTRACE_SND(Kern::Printf(">DTemplateSoundScPddFactory::DTemplateSoundScPddFactory")); + +// iDfcQ=NULL; + + // Support units KSoundScTxUnit0 & KSoundScRxUnit0. + iUnitsMask=(1<DTemplateSoundScPddFactory::~DTemplateSoundScPddFactory")); + + // Destroy the kernel thread. + if (iDfcQ) + iDfcQ->Destroy(); + } + +/** +Second stage constructor for the shared chunk sound PDD factory class. +@return KErrNone if successful, otherwise one of the other system wide error codes. +*/ +TInt DTemplateSoundScPddFactory::Install() + { + TInt r=KErrNone; + if (iDfcQ==NULL) + { + // Create a new sound driver DFC queue (and associated kernel thread). + r=Kern::DynamicDfcQCreate(iDfcQ,KSoundScDriverThreadPriority,KSoundScDriverThreadName); + } + + if (r==KErrNone) + { + r=SetName(&KSoundScPddName); // Set the name of the driver object + } + + __KTRACE_SND(Kern::Printf("DTemplateSoundScPddFactory::Create")); + + // Create the appropriate PDD channel object. + TInt r=KErrNoMemory; + if (aUnit==KSoundScRxUnit0) + { + // Create a record PDD channel object + DTemplateSoundScRxPdd* pD=new DTemplateSoundScRxPdd; + aChannel=pD; + if (pD) + { + pD->iPhysicalDevice=this; + r=pD->DoCreate(); + } + } + + else + { + // Create a playback PDD channel object + DTemplateSoundScTxPdd* pD=new DTemplateSoundScTxPdd; + aChannel=pD; + if (pD) + { + pD->iPhysicalDevice=this; + r=pD->DoCreate(); + } + } + return(r); + } + + +/** +Constructor for the Template playback shared chunk sound driver physical device driver (PDD). +*/ +DTemplateSoundScTxPdd::DTemplateSoundScTxPdd() + { + __KTRACE_SND(Kern::Printf(">DTemplateSoundScTxPdd::DTemplateSoundScTxPdd")); + +// iDmaChan=NULL; +// iPendingPlay=0; +// iFlag=0; + } + +/** +Destructor for the Template playback shared chunk sound driver physical device driver (PDD). +*/ +DTemplateSoundScTxPdd::~DTemplateSoundScTxPdd() + { + // Delete the DMA request objects + for (TInt i=0; iClose(); + } + +/** +Second stage constructor for the Template playback shared chunk sound driver physical device driver (PDD). +Note that this constructor is called before the second stage constructor for the LDD so it is not +possible to call methods on the LDD here. +@return KErrNone if successful, otherwise one of the other system wide error codes. +*/ +TInt DTemplateSoundScTxPdd::DoCreate() + { + __KTRACE_SND(Kern::Printf(">DTemplateSoundScTxPdd::DoCreate")); + + SetCaps(); // Setup the capabilities of this device. + + // Setup a DMA channel for playback + // TO DO: (mandatory) + // Setup the DMA channel information for this play device. + TDmaChannel::SCreateInfo info; +// info.iCookie=??? + info.iDfcQ=DfcQ(KSoundScTxUnit0); +// info.iDfcPriority=??? + info.iDesCount=KTemplateMaxTxDmaRequests; + // coverity[uninit_use_in_call] + // The values info.iCookie and info.iDfcPriority are to be initialized when implemented + TInt r=TDmaChannel::Open(info,iDmaChannel); + + // Create the DMA request objects for use with the DMA channel. + if (r==KErrNone) + { + for (TInt i=0; iiDfcQ); + } + +/** +Called from the LDD to return the shared chunk create information to be used by this play device. +@param aChunkCreateInfo A chunk create info. object to be to be filled with the settings + required for this device. +*/ +void DTemplateSoundScTxPdd::GetChunkCreateInfo(TChunkCreateInfo& aChunkCreateInfo) + { + __KTRACE_SND(Kern::Printf(">DTemplateSoundScTxPdd::GetChunkCreateInfo")); + + // TO DO: (mandatory) + // Setup the shared chunk create information in aChunkCreateInfo for this play device. + aChunkCreateInfo.iType=TChunkCreateInfo::ESharedKernelMultiple; +// aChunkCreateInfo.iMapAttr=??? + aChunkCreateInfo.iOwnsMemory=ETrue; // Using RAM pages. + aChunkCreateInfo.iDestroyedDfc=NULL; // No chunk destroy DFC. + } + +/** +Called from the LDD to return the capabilities of this device. +@param aCapsBuf A packaged TSoundFormatsSupportedV02 object to be filled with the play + capabilities of this device. This descriptor is in kernel memory and can be accessed directly. +@see TSoundFormatsSupportedV02. +*/ +void DTemplateSoundScTxPdd::Caps(TDes8& aCapsBuf) const + { + __KTRACE_SND(Kern::Printf(">DTemplateSoundScTxPdd::Caps")); + + // Copy iCaps back. + TPtrC8 ptr((const TUint8*)&iCaps,sizeof(iCaps)); + aCapsBuf.FillZ(aCapsBuf.MaxLength()); + aCapsBuf=ptr.Left(Min(ptr.Length(),aCapsBuf.MaxLength())); + } + +/** +Called from the LDD to return the maximum transfer length in bytes that this device can support in a single data transfer. +@return The maximum transfer length in bytes. +*/ +TInt DTemplateSoundScTxPdd::MaxTransferLen() const + { + return(KTemplateMaxTxDmaTransferLen); + } + +/** +Called from the LDD to configure or reconfigure the device using the the configuration supplied. +@param aConfigBuf A packaged TCurrentSoundFormatV02 object which contains the new configuration settings. + This descriptor is in kernel memory and can be accessed directly. +@return KErrNone if successful, otherwise one of the other system wide error codes. +@see TCurrentSoundFormatV02. +*/ +TInt DTemplateSoundScTxPdd::SetConfig(const TDesC8& aConfigBuf) + { + __KTRACE_SND(Kern::Printf(">DTemplateSoundScTxPdd::SetConfig")); + + // Read the new configuration from the LDD. + TCurrentSoundFormatV02 config; + TPtr8 ptr((TUint8*)&config,sizeof(config)); + Kern::InfoCopy(ptr,aConfigBuf); + + // TO DO: (mandatory) + // Apply the specified audio configuration to the audio device. + TInt r=KErrNone; + + __KTRACE_SND(Kern::Printf("DTemplateSoundScTxPdd::SetVolume")); + + // TO DO: (mandatory) + // Set the specified play volume on the audio device. + TInt r=KErrNone; + + return(r); + } + +/** +Called from the LDD to prepare the audio device for playback. +@return KErrNone if successful, otherwise one of the other system wide error codes. +*/ +TInt DTemplateSoundScTxPdd::StartTransfer() + { + __KTRACE_SND(Kern::Printf(">DTemplateSoundScTxPdd::StartTransfer")); + + // TO DO: (mandatory) + // Prepare the audio device for playback. + TInt r=KErrNone; + + __KTRACE_SND(Kern::Printf("DTemplateSoundScTxPdd::TransferData(ID:%xH,Addr:%xH,Len:%d)",aLinAddr,aNumBytes)); + + TInt r=KErrNone; + + // Check that we can accept the request + if (iPendingPlay>=KTemplateMaxTxDmaRequests) + r=KErrNotReady; + else + { + // Start a DMA transfer. + iDmaRequest[iFlag]->iTransferID=aTransferID; + iDmaRequest[iFlag]->iTransferSize=aNumBytes; + // TO DO: (mandatory) + // Supply the DMA destination information. + TUint32 dest=0; // ??? + r=iDmaRequest[iFlag]->Fragment(aLinAddr,dest,aNumBytes,KDmaMemSrc|KDmaIncSrc,0); + if (r==KErrNone) + { + iDmaRequest[iFlag]->Queue(); + iPendingPlay++; + if ((++iFlag)>=KTemplateMaxTxDmaRequests) + iFlag=0; + + // TO DO: (mandatory) + // Start the audio device transfering data. + } + } + + __KTRACE_SND(Kern::Printf("DTemplateSoundScTxPdd::StopTransfer")); + + // Stop the DMA channel. + iDmaChannel->CancelAll(); + iFlag=0; + iPendingPlay=0; + + // TO DO: (mandatory) + // Stop the audio device transfering data. + } + +/** +Called from the LDD to halt the playback of data to the sound device but not to release any resources necessary for +playback. +If possible, any active transfer should be suspended in such a way that it can be resumed later - starting from next +sample following the one last played. +@return KErrNone if successful, otherwise one of the other system wide error codes. +*/ +TInt DTemplateSoundScTxPdd::PauseTransfer() + { + __KTRACE_SND(Kern::Printf(">DTemplateSoundScTxPdd::PauseTransfer")); + + // TO DO: (mandatory) + // Halt playback on the audio device. + TInt r=KErrNone; + + return(r); + } + +/** +Called from the LDD to resume the playback of data to the sound device following a request to halt playback. +If possible, any transfer which was active when the device was halted should be resumed - starting from next sample +following the one last played. Once complete, it should be reported using PlayCallback() +as normal. +@return KErrNone if successful, otherwise one of the other system wide error codes. +*/ +TInt DTemplateSoundScTxPdd::ResumeTransfer() + { + __KTRACE_SND(Kern::Printf(">DTemplateSoundScTxPdd::ResumeTransfer")); + + // TO DO: (mandatory) + // Resume playback on the audio device. + TInt r=KErrNone; + + return(r); + } + +/** +Called from the LDD to power up the sound device when the channel is first opened and if ever the phone is brought out +of standby mode. +@return KErrNone if successful, otherwise one of the other system wide error codes. +*/ +TInt DTemplateSoundScTxPdd::PowerUp() + { + // TO DO: (mandatory) + // Power up the audio device. + + return(KErrNone); + } + +/** +Called from the LDD to power down the sound device when the channel is closed and just before the phone powers down when +being turned off or going into standby. +*/ +void DTemplateSoundScTxPdd::PowerDown() + { + // TO DO: (mandatory) + // Power down the audio device. + } + +/** +Called from the LDD to handle a custom configuration request. +@param aFunction A number identifying the request. +@param aParam A 32-bit value passed to the driver. Its meaning depends on the request. +@return KErrNone if successful, otherwise one of the other system wide error codes. +*/ +TInt DTemplateSoundScTxPdd::CustomConfig(TInt /*aFunction*/,TAny* /*aParam*/) + { + return(KErrNotSupported); + } + +/** +Called from the LDD to find out how many microseconds of data have been played. This is called +in the context of the DFC thread. +@param aTimeTransferred A reference to a variable into which to place the number of microseconds of audio. +@param aStatus The current status of this channel +@return KErrNone if time is valid or KErrNotSupported. +*/ +TInt DTemplateSoundScTxPdd::TimeTransferred(TInt64& aTimeTransferred, TInt aStatus) + { + return(KErrNotSupported); + } + +/** +Called each time a playback DMA transfer completes - from the DMA callback function in the sound thread's DFC context. +@param aTransferID The transfer ID of the DMA transfer. +@param aTransferResult The result of the DMA transfer. +@param aBytesTransferred The number of bytes transferred. +*/ +void DTemplateSoundScTxPdd::PlayCallback(TUint aTransferID,TInt aTransferResult,TInt aBytesTransferred) + { + __KTRACE_SND(Kern::Printf(">DTemplateSoundScTxPdd::PlayCallback")); + + iPendingPlay--; + + Ldd()->PlayCallback(aTransferID,aTransferResult,aBytesTransferred); + } + +/** +Initialise the data member DTemplateSoundScTxPdd::iCaps with the play capabilities of this audio playback device. +*/ +void DTemplateSoundScTxPdd::SetCaps() + { + __KTRACE_SND(Kern::Printf(">DTemplateSoundScTxPdd::SetCaps")); + + // The data transfer direction for this unit is play. + iCaps.iDirection=ESoundDirPlayback; + + // TO DO: (mandatory) + // Setup the rest of the capabilities structure DTemplateSoundScTxPdd::iCaps with the capabilities of this + // audio playback device. + } + +/** +Constructor for a shared chunk sound driver playback DMA request. +*/ +DTemplateSoundScTxDmaRequest::DTemplateSoundScTxDmaRequest(TDmaChannel& aChannel,DTemplateSoundScTxPdd* aPdd,TInt aMaxTransferSize) + : DDmaRequest(aChannel,DTemplateSoundScTxDmaRequest::DmaService,this,aMaxTransferSize), + iPdd(aPdd) + {} + +/** +DMA tx service routine. Called in the sound thread's DFC context by the s/w DMA controller. +@param aResult Status of DMA transfer. +@param aArg Argument passed to DMA controller. +*/ +void DTemplateSoundScTxDmaRequest::DmaService(TResult aResult, TAny* aArg) + { + __KTRACE_SND(Kern::Printf(">SndTxDmaService - %d",aResult)); + DTemplateSoundScTxDmaRequest& req=*(DTemplateSoundScTxDmaRequest*)aArg; + + TInt res=KErrNone; + TInt bytesTransferred=req.iTransferSize; + if (aResult!=DDmaRequest::EOk) + { + res=KErrCorrupt; + bytesTransferred=0; + } + + // Inform the LDD of the result of the transfer. + req.iPdd->PlayCallback(req.iTransferID,res,bytesTransferred); + return; + } +