sl@0: // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0: // All rights reserved.
sl@0: // This component and the accompanying materials are made available
sl@0: // under the terms of "Eclipse Public License v1.0"
sl@0: // which accompanies this distribution, and is available
sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0: //
sl@0: // Initial Contributors:
sl@0: // Nokia Corporation - initial contribution.
sl@0: //
sl@0: // Contributors:
sl@0: //
sl@0: // Description:
sl@0: //
sl@0: 
sl@0: #include "MmfBtPcm16ToPcm16HwDevice.h"
sl@0: #include "../../MmfBtFileDependencyUtil.h"
sl@0: 
sl@0: /**
sl@0:  *
sl@0:  *	Returns the created hw device for passing audio through audio.
sl@0:  *  for the wins implementation this would always be pcm16 although
sl@0:  *  this is effectively a null hw device that will pass any datatype through
sl@0:  *	@return	"CMMFPcm16ToPcm16HwDevice"
sl@0:  *
sl@0:  */
sl@0: CMMFPcm16ToPcm16HwDevice* CMMFPcm16ToPcm16HwDevice::NewL()
sl@0: 	{
sl@0:     CMMFPcm16ToPcm16HwDevice* self = new (ELeave) CMMFPcm16ToPcm16HwDevice();
sl@0: 	CleanupStack::PushL(self);
sl@0: 	self->ConstructL();
sl@0: 	CleanupStack::Pop(self);
sl@0: 	return self;
sl@0: 	}
sl@0: 
sl@0: /**
sl@0:  *
sl@0:  *	Second phase constructor.
sl@0:  *
sl@0:  */
sl@0: void CMMFPcm16ToPcm16HwDevice::ConstructL()
sl@0: 	{
sl@0:     iCodec = new (ELeave) CMMFPcm16ToPcm16Codec();
sl@0: 	static_cast<CMMFPcm16ToPcm16Codec*>(iCodec)->SetHwDevice(this);
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: *
sl@0: * ~CMMFPcm16ToPcm16HwDevice
sl@0: *
sl@0: **/
sl@0: CMMFPcm16ToPcm16HwDevice::~CMMFPcm16ToPcm16HwDevice()
sl@0: 	{
sl@0: 	}
sl@0: 
sl@0: /**
sl@0: *
sl@0: * Codec
sl@0: * @return CMMFSwCodec&
sl@0: **/
sl@0: CMMFSwCodec& CMMFPcm16ToPcm16HwDevice::Codec()
sl@0: 	{
sl@0: 	return *iCodec;
sl@0: 	}
sl@0: 
sl@0: 
sl@0: 
sl@0: 
sl@0: 
sl@0: /**
sl@0: *
sl@0: * ProcessL
sl@0: * @param aSrc Source Buffer
sl@0: * @param aDest Destintion Buffer
sl@0: * @return CMMFSwCodec::TCodecProcessResult
sl@0: *
sl@0: **/
sl@0: CMMFSwCodec::TCodecProcessResult CMMFPcm16ToPcm16Codec::ProcessL(const CMMFBuffer& /*aSource*/, CMMFBuffer& /*aDest*/)
sl@0: 	{//no processing required for null codec
sl@0: 	User::Leave(KErrNotSupported); 
sl@0: 	//to keep compiler happy
sl@0: 	TCodecProcessResult result;
sl@0: 	result.iCodecProcessStatus = TCodecProcessResult::EEndOfData;
sl@0: 	result.iSrcBytesProcessed = 0;
sl@0: 	result.iDstBytesAdded = 0;
sl@0: 	return result;
sl@0: 	};
sl@0: 
sl@0: 
sl@0: TUint CMMFPcm16ToPcm16Codec::SourceBufferSize()
sl@0: 	{
sl@0: 	if (!iBufferSize) 
sl@0: 		iBufferSize = iHwDevice->CalculateBufferSize();
sl@0: 	return iBufferSize;
sl@0: 	}
sl@0: 
sl@0: 
sl@0: TUint CMMFPcm16ToPcm16Codec::SinkBufferSize()
sl@0: 	{
sl@0: 	if (!iBufferSize) 
sl@0: 		iBufferSize = iHwDevice->CalculateBufferSize();
sl@0: 	return iBufferSize;
sl@0: 	}
sl@0: 
sl@0: void CMMFPcm16ToPcm16Codec::SetHwDevice(CMMFPcm16ToPcm16HwDevice* aHwDevice)
sl@0: 	{
sl@0: 	iHwDevice = aHwDevice;
sl@0: 	}
sl@0: 
sl@0: TUint CMMFPcm16ToPcm16HwDevice::CalculateBufferSize()
sl@0: 	{
sl@0: 	TUint sampleRate = 0;
sl@0: 	TUint channels = 0;
sl@0: 	TInt useBufferOfSize = 0;
sl@0: 	TInt minBufferSize = 0;
sl@0: 	TInt maxBufferSize = 0;
sl@0: 
sl@0: 	if (iPlayCustomInterface)
sl@0: 		{
sl@0: 		sampleRate = iSampleRate;
sl@0: 		channels = iChannels;	
sl@0: /*		if ((sampleRate) && (channels))
sl@0: 			{
sl@0: 			RMdaDevSound::TSoundFormatsSupportedBuf playFormatsSupported;
sl@0: 			if (iDataPath->Device().Handle())
sl@0: 				{
sl@0: 				iDataPath->Device().PlayFormatsSupported(playFormatsSupported);
sl@0: 				minBufferSize = playFormatsSupported().iMinBufferSize;
sl@0: 				maxBufferSize = playFormatsSupported().iMaxBufferSize;
sl@0: 				}
sl@0: 			else
sl@0: 				{//try to get handle
sl@0: 				TInt err = iDataPath->Device().Open();
sl@0: 				if (err == KErrNone)
sl@0: 					{
sl@0: 					iDataPath->Device().PlayFormatsSupported(playFormatsSupported);
sl@0: 					minBufferSize = playFormatsSupported().iMinBufferSize;
sl@0: 					maxBufferSize = playFormatsSupported().iMaxBufferSize;
sl@0: 					iDataPath->Device().Close();
sl@0: 					}
sl@0: 				}
sl@0: 			}
sl@0: */		}
sl@0: 	if ((iRecordCustomInterface) && (!sampleRate) && (!channels))
sl@0: 		{ //must be record
sl@0: 		sampleRate = iSampleRate;
sl@0: 		channels = iChannels;
sl@0: /*		if ((sampleRate) && (channels))
sl@0: 			{//get max and min supported buffer sizes supported by hw
sl@0: 			RMdaDevSound::TSoundFormatsSupportedBuf recordFormatsSupported;
sl@0: 			if (iDataPath->Device().Handle())
sl@0: 				{
sl@0: 				iDataPath->Device().RecordFormatsSupported(recordFormatsSupported);
sl@0: 				minBufferSize = recordFormatsSupported().iMinBufferSize;
sl@0: 				maxBufferSize = recordFormatsSupported().iMaxBufferSize;
sl@0: 				}
sl@0: 			else
sl@0: 				{//try to get handle
sl@0: 				TInt err = iDataPath->Device().Open();
sl@0: 				if (err == KErrNone)
sl@0: 					{
sl@0: 					iDataPath->Device().RecordFormatsSupported(recordFormatsSupported);
sl@0: 					minBufferSize = recordFormatsSupported().iMinBufferSize;
sl@0: 					maxBufferSize = recordFormatsSupported().iMaxBufferSize;
sl@0: 					iDataPath->Device().Close();
sl@0: 					}
sl@0: 				}
sl@0: 			}
sl@0: */		}
sl@0: //	else convert so not applicable
sl@0: 
sl@0: 	if ((sampleRate) && (channels))
sl@0: 		{
sl@0: 		// Buffer size = (SampleRate * BytesPerSample * Channels) / 4
sl@0: 		useBufferOfSize = ((sampleRate * 2 * channels)/KDevSoundFramesPerSecond + (KDevSoundDeltaFrameSize-1)) &~ (KDevSoundDeltaFrameSize-1);
sl@0: 		//clamp buffer to desired limits
sl@0: 		if(useBufferOfSize < KDevSoundMinFrameSize) 
sl@0: 			useBufferOfSize = KDevSoundMinFrameSize;
sl@0: 		else if(useBufferOfSize > KDevSoundMaxFrameSize) 
sl@0: 			useBufferOfSize = KDevSoundMaxFrameSize;
sl@0: 
sl@0: 		//clamp buffer to limits of hardware
sl@0: 		if (maxBufferSize)
sl@0: 			{//buffer size limits have been set by sound driver
sl@0: 			 //check we are within the limits
sl@0: 			if(useBufferOfSize < minBufferSize)
sl@0: 				useBufferOfSize = minBufferSize;
sl@0: 			else if(useBufferOfSize > maxBufferSize)
sl@0: 				useBufferOfSize = maxBufferSize;
sl@0: 			}
sl@0: 		}
sl@0: 	else
sl@0: 		{
sl@0: 		useBufferOfSize = KPCM16ToPCM16BufferSize;
sl@0: 		}
sl@0: 
sl@0: 	return useBufferOfSize;
sl@0: 	}