diff -r 000000000000 -r a41df078684a bsptemplate/asspandvariant/template_variant/specific/soundsc_rx.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bsptemplate/asspandvariant/template_variant/specific/soundsc_rx.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,427 @@ +// 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_rx.cpp +// Implementation of the Template record shared chunk sound physical device driver (PDD). +// This file is part of the Template Base port +// +// + +/** + @file +*/ + +#include "soundsc_plat.h" + + +/** +Constructor for the Template record shared chunk sound driver physical device driver (PDD). +*/ +DTemplateSoundScRxPdd::DTemplateSoundScRxPdd() + { + __KTRACE_SND(Kern::Printf(">DTemplateSoundScRxPdd::DTemplateSoundScRxPdd")); + +// iDmaChan=NULL; +// iPendingRecord=0; +// iFlag=0; + } + +/** +Destructor for the Template record shared chunk sound driver physical device driver (PDD). +*/ +DTemplateSoundScRxPdd::~DTemplateSoundScRxPdd() + { + // Delete the DMA request objects + for (TInt i=0; iClose(); + } + +/** +Second stage constructor for the Template record 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 DTemplateSoundScRxPdd::DoCreate() + { + __KTRACE_SND(Kern::Printf(">DTemplateSoundScRxPdd::DoCreate")); + + SetCaps(); // Setup the capabilities of this device. + + // Setup a DMA channel for record + // TO DO: (mandatory) + // Setup the DMA channel information for this record device. + TDmaChannel::SCreateInfo info; +// info.iCookie=??? + info.iDfcQ=DfcQ(KSoundScRxUnit0); +// info.iDfcPriority=??? + info.iDesCount=KTemplateMaxRxDmaRequests; + // 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 record device. +@param aChunkCreateInfo A chunk create info. object to be to be filled with the settings + required for this device. +*/ +void DTemplateSoundScRxPdd::GetChunkCreateInfo(TChunkCreateInfo& aChunkCreateInfo) + { + __KTRACE_SND(Kern::Printf(">DTemplateSoundScRxPdd::GetChunkCreateInfo")); + + // TO DO: (mandatory) + // Setup the shared chunk create information in aChunkCreateInfo for this record 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 record + capabilities of this device. This descriptor is in kernel memory and can be accessed directly. +@see TSoundFormatsSupportedV02. +*/ +void DTemplateSoundScRxPdd::Caps(TDes8& aCapsBuf) const + { + __KTRACE_SND(Kern::Printf(">DTemplateSoundScRxPdd::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 DTemplateSoundScRxPdd::MaxTransferLen() const + { + return(KTemplateMaxRxDmaTransferLen); + } + +/** +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 DTemplateSoundScRxPdd::SetConfig(const TDesC8& aConfigBuf) + { + __KTRACE_SND(Kern::Printf(">DTemplateSoundScRxPdd::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("DTemplateSoundScRxPdd::SetVolume")); + + // TO DO: (mandatory) + // Set the specified record volume on the audio device. + TInt r=KErrNone; + + return(r); + } + +/** +Called from the LDD to prepare the audio device for recording. +@return KErrNone if successful, otherwise one of the other system wide error codes. +*/ +TInt DTemplateSoundScRxPdd::StartTransfer() + { + __KTRACE_SND(Kern::Printf(">DTemplateSoundScRxPdd::StartTransfer")); + + // TO DO: (mandatory) + // Prepare the audio device for record. + TInt r=KErrNone; + + __KTRACE_SND(Kern::Printf("DTemplateSoundScRxPdd::TransferData(ID:%xH,Addr:%xH,Len:%d)",aLinAddr,aNumBytes)); + + TInt r=KErrNone; + + // Check that we can accept the request + if (iPendingRecord>=KTemplateMaxRxDmaRequests) + r=KErrNotReady; + else + { + // Start a DMA transfer. + iDmaRequest[iFlag]->iTransferID=aTransferID; + iDmaRequest[iFlag]->iTransferSize=aNumBytes; + // TO DO: (mandatory) + // Supply the DMA source information. + TUint32 src=0; // ??? + r=iDmaRequest[iFlag]->Fragment(src,aLinAddr,aNumBytes,KDmaMemDest|KDmaIncDest,0); + if (r==KErrNone) + { + iDmaRequest[iFlag]->Queue(); + iPendingRecord++; + if ((++iFlag)>=KTemplateMaxRxDmaRequests) + iFlag=0; + + // TO DO: (mandatory) + // Start the audio device transfering data. + } + } + + __KTRACE_SND(Kern::Printf("DTemplateSoundScRxPdd::StopTransfer")); + + // Stop the DMA channel. + iDmaChannel->CancelAll(); + iFlag=0; + iPendingRecord=0; + + // TO DO: (mandatory) + // Stop the audio device transfering data. + } + +/** +Called from the LDD to halt the recording of data from the sound device but not to release any resources necessary for +recording. +All active transfers should be aborted. When recording is halted the PDD signals this event with a single call of the LDD +function RecordCallback() - reporting back any partial data already received. If transfer is resumed later, the LDD will +issue a new TransferData() request to re-commence data transfer. +@return KErrNone if successful, otherwise one of the other system wide error codes. +*/ +TInt DTemplateSoundScRxPdd::PauseTransfer() + { + __KTRACE_SND(Kern::Printf(">DTemplateSoundScRxPdd::PauseTransfer")); + + // Stop the DMA channel. + iDmaChannel->CancelAll(); + + if (iPendingRecord) + { + // TO DO: (mandatory) + // Determine how much data was successfully transferred to the record buffer before transfer was aborted. + TInt byteCount=0; // ??? + Ldd()->RecordCallback(0,KErrNone,byteCount); // We can use a NULL transfer ID when pausing. + iPendingRecord=0; + } + iFlag=0; + + // TO DO: (mandatory) + // Halt recording on the audio device. + TInt r=KErrNone; + + return(r); + } + +/** +Called from the LDD to resume the recording of data from the sound device following a request to halt recording. +Any active transfer would have been aborted when the device was halted so its just a case of re-creating the same setup +acheived following StartTransfer(). +@return KErrNone if successful, otherwise one of the other system wide error codes. +*/ +TInt DTemplateSoundScRxPdd::ResumeTransfer() + { + __KTRACE_SND(Kern::Printf(">DTemplateSoundScRxPdd::ResumeTransfer")); + + // TO DO: (mandatory) + // Resume recording 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 DTemplateSoundScRxPdd::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 DTemplateSoundScRxPdd::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 DTemplateSoundScRxPdd::CustomConfig(TInt /*aFunction*/,TAny* /*aParam*/) + { + return(KErrNotSupported); + } + +/** +Called from the LDD to find out how many microseconds of data have been recorded. 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 DTemplateSoundScRxPdd::TimeTransferred(TInt64& aTimeTransferred, TInt aStatus) + { + return(KErrNotSupported); + } + +/** +Called each time a record 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 DTemplateSoundScRxPdd::RecordCallback(TUint aTransferID,TInt aTransferResult,TInt aBytesTransferred) + { + __KTRACE_SND(Kern::Printf(">DTemplateSoundScRxPdd::RecordCallback")); + + iPendingRecord--; + + Ldd()->RecordCallback(aTransferID,aTransferResult,aBytesTransferred); + } + +/** +Initialise the data member DTemplateSoundScRxPdd::iCaps with the record capabilities of this audio device. +*/ +void DTemplateSoundScRxPdd::SetCaps() + { + __KTRACE_SND(Kern::Printf(">DTemplateSoundScRxPdd::SetCaps")); + + // The data transfer direction for this unit is record. + iCaps.iDirection=ESoundDirRecord; + + // TO DO: (mandatory) + // Setup the rest of the capabilities structure DTemplateSoundScRxPdd::iCaps with the capabilities of this + // audio record device. + } + +/** +Constructor for a shared chunk sound driver record DMA request. +*/ +DTemplateSoundScRxDmaRequest::DTemplateSoundScRxDmaRequest(TDmaChannel& aChannel,DTemplateSoundScRxPdd* aPdd,TInt aMaxTransferSize) + : DDmaRequest(aChannel,DTemplateSoundScRxDmaRequest::DmaService,this,aMaxTransferSize), + iPdd(aPdd) + {} + +/** +DMA rx 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 DTemplateSoundScRxDmaRequest::DmaService(TResult aResult, TAny* aArg) + { + __KTRACE_SND(Kern::Printf(">SndRxDmaService - %d",aResult)); + DTemplateSoundScRxDmaRequest& req=*(DTemplateSoundScRxDmaRequest*)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->RecordCallback(req.iTransferID,res,bytesTransferred); + return; + } +