mmlibs/mmfw/tsrc/mmfintegrationtest/ACLNT/WavDecodeUtility.cpp
changeset 0 b8ed18f6c07b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mmlibs/mmfw/tsrc/mmfintegrationtest/ACLNT/WavDecodeUtility.cpp	Thu Oct 07 22:34:12 2010 +0100
@@ -0,0 +1,234 @@
+// Copyright (c) 2003-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 "mmfwavformat.h"
+
+#include "WavDecodeUtility.h" 
+
+
+CWavDecodeUtility::CWavDecodeUtility()
+	{
+	}
+
+void CWavDecodeUtility::ConstructL(TDesC8& aBuffer)
+	{
+	iBuffer = &aBuffer;
+	FindRiffChunksL();
+	ProcessFormatHeaderL();
+	}
+
+CWavDecodeUtility* CWavDecodeUtility::NewL(TDesC8& aBuffer)
+	{
+	CWavDecodeUtility* self = new (ELeave) CWavDecodeUtility();
+	CleanupStack::PushL(self);
+	self->ConstructL(aBuffer);
+	CleanupStack::Pop();
+	return self;
+	}
+
+
+CWavDecodeUtility::~CWavDecodeUtility()
+	{
+	}
+
+TUint16 CWavDecodeUtility::Read16(const TUint8* aPtr)
+
+    {
+	TUint16 ret = *(REINTERPRET_CAST(const TUint16*, aPtr));
+	return ret;
+    }
+
+TUint32 CWavDecodeUtility::Read32(const TUint8* aPtr)
+    {
+    TUint32 x = *aPtr++;
+    x |= *aPtr++ << 8;
+    x |= *aPtr++ << 16;
+    x |= *aPtr++ << 24;
+    return x;
+    }
+void CWavDecodeUtility::AssignChunkTo(TMdaRiffChunk* aAssignedChunk)
+	{
+	Mem::Copy(REINTERPRET_CAST(TUint8*, aAssignedChunk), REINTERPRET_CAST(TUint8*, &iCurrent),sizeof(TMdaRiffChunk));
+	aAssignedChunk->iFound=ETrue;
+	}
+
+void CWavDecodeUtility::ReadChunk(TMdaRiffChunk* aChunk)
+	{
+	Mem::FillZ(REINTERPRET_CAST(TUint8*, aChunk),sizeof(TMdaRiffChunk)); // Zero data
+	aChunk->iPosition=iPos + KRiffChunkHeaderLength;
+	aChunk->iName = Read32(iStartPtr + iPos - iLastReadPosition);
+	aChunk->iLength = Read32(iStartPtr + iPos - iLastReadPosition + KRiffChunkDataLength);
+	}
+void CWavDecodeUtility::FindRiffChunksL()
+	{
+	if (!iFoundChunks)
+		{
+		iFoundChunks=ETrue;
+//		iStartPtr=iBuffer->Data().Ptr();
+		iStartPtr=iBuffer->Ptr();
+		iPos=0;
+		iLastReadPosition=0;//Set by CBase, but what the heck
+		iDone=EFalse;
+		}
+	else
+		{//We've done another read. If there's < chunk in the buffer then something's wrong
+		if (iBuffer->Length() < STATIC_CAST(TInt, KRiffChunkHeaderLength))
+			{
+			if ((iFormatChunk.iFound) && (iDataChunk.iFound)) 
+				{
+				iDone = ETrue; //it should be ok to exit loop
+				return;
+				}
+			else
+				{
+				User::Leave(KErrCorrupt);
+				}
+			}
+		}
+	
+	while (!iDone)
+		{
+		TInt advance=0;
+		
+		ReadChunk(&iCurrent);
+		
+		if (iCurrent.iName == KRiffChunkNameRiff)//we need to look INSIDE the RIFF chunk
+			{
+			if(iBuffer->Length() < STATIC_CAST(TInt, KRiffContainerChunkHeaderLength))
+				User::Leave(KErrCorrupt);
+			iRiffChunkLength=iCurrent.iLength + KRiffChunkHeaderLength;
+			advance=KRiffContainerChunkHeaderLength;
+			}
+		else
+			{
+			advance=iCurrent.iLength + KRiffChunkHeaderLength;		//... and skip all others
+			}
+		
+		if (iCurrent.iName == KRiffChunkNameFmt_)
+			AssignChunkTo(&iFormatChunk);
+		
+		else if (iCurrent.iName == KRiffChunkNameFact)
+			AssignChunkTo(&iFactChunk);
+		
+		else if (iCurrent.iName == KRiffChunkNameData)
+			AssignChunkTo(&iDataChunk);
+		
+		if (iDataChunk.iFound && iFormatChunk.iFound && iFactChunk.iFound)
+			{
+			iDone=ETrue;
+			}
+		else
+			{//still have chunks to look for
+			iPos+=advance;
+			if (iPos & 1)
+				iPos++;
+			
+			if ((TUint)iPos>=(TUint)iRiffChunkLength)
+				{
+				iDone=ETrue;//end of file
+				iClipLength = iRiffChunkLength;
+				}
+			else
+				{//make sure we have at least a chunk's worth left in the buffer
+				if ((TUint)(iPos-iLastReadPosition) > 
+					(TUint)(iBuffer->Length() -KRiffChunkHeaderLength))
+					{
+					iLastReadPosition=iPos;
+					//DoReadL(iLastReadPosition);
+					return;
+					}	
+				}
+			}
+		}
+	
+	iClipLength = iRiffChunkLength;
+	if (iClipLength == 0) User::Leave(KErrNotFound);
+	else if (!(iDataChunk.iFound && iFormatChunk.iFound))
+		User::Leave(KErrCorrupt);
+
+	}
+
+void CWavDecodeUtility::ProcessFormatHeaderL()
+	{
+	TMdaRiffChunk* chunk = &iFormatChunk;
+	
+	if (!chunk)
+		User::Leave(KErrCorrupt);
+	
+	iLastReadPosition = chunk->iPosition; // Should be beginning of fmt block
+	//DoReadL(iLastReadPosition);
+	
+	// Set the real format
+	const TUint8* rawform = iBuffer->Ptr() + iLastReadPosition;	//skip _fmt & length
+	iCodecId = Read16(rawform); rawform+=2;
+	iChannels = Read16(rawform); rawform+=2;
+	if ((iChannels != 1)&&(iChannels != 2))		//only 1 or 2 channels allowed
+		User::Leave(KErrCorrupt); 
+	
+	iSampleRate = Read32(rawform); rawform+=4; // Skip bytes per second estimate
+	if (!iSampleRate) 	User::Leave(KErrCorrupt);
+	
+	iAverageBytesPerSecond = Read32(rawform); rawform+=4;
+	iBlockAlign = Read16(rawform); rawform+=2;
+	
+	iBitsPerSample = Read16(rawform);
+	rawform+=2;
+	
+	switch (iCodecId)
+		{
+		case KMMFWavFormatTypePcm:
+			{
+			}
+			break;
+		case KMMFWavFormatTypeImaAdpcm:
+			{
+			}
+			break;
+		case KMMFWavFormatTypeAlaw:
+			{
+			}
+			break;
+		case KMMFWavFormatTypeMulaw:
+			{
+			}
+			break;
+		case KMMFWavFormatTypeGSM610:
+			{
+			}
+			break;
+		default:
+			User::Leave(KErrNotSupported);
+		}
+	
+	if (iCodecId == KMMFWavFormatTypeImaAdpcm)
+		{
+		TUint16 extraData = Read16(rawform);
+		if (extraData == 2)
+			{
+			rawform+=2;
+			iSamplesPerBlock = Read16(rawform);
+			rawform+=2;
+			}
+		}
+	
+	// Is there a fact chunk?
+	if (iFactChunk.iFound)			
+		iHasFactChunk = ETrue;
+	
+	// Find the data block
+	chunk=&iDataChunk;
+	iStartPosition = chunk->iPosition; 
+	iDataLength = chunk->iLength;
+	}