bsptemplate/asspandvariant/template_variant/specific/soundsc_rx.cpp
changeset 0 a41df078684a
--- /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; i<KTemplateMaxRxDmaRequests; i++)
+		{
+		if (iDmaRequest[i])
+			delete iDmaRequest[i];
+		}
+	
+	// Close the DMA channel.
+	if (iDmaChannel)
+		iDmaChannel->Close();
+	}
+	
+/**
+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; i<KTemplateMaxRxDmaRequests; i++)
+			{
+			iDmaRequest[i] = new DTemplateSoundScRxDmaRequest(*iDmaChannel,this);
+			if (iDmaRequest[i] == NULL)
+				{
+				r=KErrNoMemory;
+				break;
+				}
+			}
+		}
+	
+	__KTRACE_SND(Kern::Printf("<DTemplateSoundScRxPdd::DoCreate - %d",r));
+	return(r);
+	}
+	
+/**
+Return the DFC queue to be used by this record device.
+@return The DFC queue to use.
+*/	
+TDfcQue* DTemplateSoundScRxPdd::DfcQ(TInt /*aUnit*/)
+	{
+	return(iPhysicalDevice->iDfcQ);
+	}
+		
+/** 
+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::SetConfig - %d",r));
+	return(r);
+	}
+	
+/**
+Called from the LDD to set the record level.
+@param aVolume The record level to be set - a value in the range 0 to 255. The value 255 equates 
+	   to the maximum record level and each value below this equates to a 0.5dB step below it.
+@return KErrNone if successful, otherwise one of the other system wide error codes.
+*/
+TInt DTemplateSoundScRxPdd::SetVolume(TInt aVolume)
+	{
+	__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::StartTransfer - %d",r));
+    return(r);
+	}
+
+/**
+Called from the LDD to initiate the recording of a portion of data from the audio device.
+When the transfer is complete, the PDD signals this event using the LDD function RecordCallback().
+@param aTransferID A value assigned by the LDD to allow it to uniquely identify a particular transfer fragment.
+@param aLinAddr The linear address within the shared chunk for storing the recorded data.
+@param aPhysAddr The physical address within the shared chunk for storing the recorded data.
+@param aNumBytes The number of bytes to be recorded. 
+@return KErrNone if the transfer has been initiated successfully;
+  		KErrNotReady if the device is unable to accept the transfer for the moment;
+		otherwise one of the other system-wide error codes.
+*/
+TInt DTemplateSoundScRxPdd::TransferData(TUint aTransferID,TLinAddr aLinAddr,TPhysAddr /*aPhysAddr*/,TInt aNumBytes)
+	{
+	__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::TransferData - %d",r));	
+	return(r);
+	}
+
+/**
+Called from the LDD to terminate the recording of a data from the device and to release any resources necessary for
+recording.
+The LDD will leave the audio device capturing record data even when there are no record requests pending from the client.
+Transfer will only be terminated when the client either issues RSoundSc::CancelRecordData() or closes the channel. Once
+this function had been called, the LDD will not issue  any further TransferData() commands without first issueing a
+StartTransfer() command.
+*/
+void DTemplateSoundScRxPdd::StopTransfer()
+	{
+	__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;
+	}
+