mmlibs/mmfw/tsrc/mmfintegrationtest/ACLNT/WavDecodeUtility.cpp
changeset 0 b8ed18f6c07b
equal deleted inserted replaced
-1:000000000000 0:b8ed18f6c07b
       
     1 // Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "mmfwavformat.h"
       
    17 
       
    18 #include "WavDecodeUtility.h" 
       
    19 
       
    20 
       
    21 CWavDecodeUtility::CWavDecodeUtility()
       
    22 	{
       
    23 	}
       
    24 
       
    25 void CWavDecodeUtility::ConstructL(TDesC8& aBuffer)
       
    26 	{
       
    27 	iBuffer = &aBuffer;
       
    28 	FindRiffChunksL();
       
    29 	ProcessFormatHeaderL();
       
    30 	}
       
    31 
       
    32 CWavDecodeUtility* CWavDecodeUtility::NewL(TDesC8& aBuffer)
       
    33 	{
       
    34 	CWavDecodeUtility* self = new (ELeave) CWavDecodeUtility();
       
    35 	CleanupStack::PushL(self);
       
    36 	self->ConstructL(aBuffer);
       
    37 	CleanupStack::Pop();
       
    38 	return self;
       
    39 	}
       
    40 
       
    41 
       
    42 CWavDecodeUtility::~CWavDecodeUtility()
       
    43 	{
       
    44 	}
       
    45 
       
    46 TUint16 CWavDecodeUtility::Read16(const TUint8* aPtr)
       
    47 
       
    48     {
       
    49 	TUint16 ret = *(REINTERPRET_CAST(const TUint16*, aPtr));
       
    50 	return ret;
       
    51     }
       
    52 
       
    53 TUint32 CWavDecodeUtility::Read32(const TUint8* aPtr)
       
    54     {
       
    55     TUint32 x = *aPtr++;
       
    56     x |= *aPtr++ << 8;
       
    57     x |= *aPtr++ << 16;
       
    58     x |= *aPtr++ << 24;
       
    59     return x;
       
    60     }
       
    61 void CWavDecodeUtility::AssignChunkTo(TMdaRiffChunk* aAssignedChunk)
       
    62 	{
       
    63 	Mem::Copy(REINTERPRET_CAST(TUint8*, aAssignedChunk), REINTERPRET_CAST(TUint8*, &iCurrent),sizeof(TMdaRiffChunk));
       
    64 	aAssignedChunk->iFound=ETrue;
       
    65 	}
       
    66 
       
    67 void CWavDecodeUtility::ReadChunk(TMdaRiffChunk* aChunk)
       
    68 	{
       
    69 	Mem::FillZ(REINTERPRET_CAST(TUint8*, aChunk),sizeof(TMdaRiffChunk)); // Zero data
       
    70 	aChunk->iPosition=iPos + KRiffChunkHeaderLength;
       
    71 	aChunk->iName = Read32(iStartPtr + iPos - iLastReadPosition);
       
    72 	aChunk->iLength = Read32(iStartPtr + iPos - iLastReadPosition + KRiffChunkDataLength);
       
    73 	}
       
    74 void CWavDecodeUtility::FindRiffChunksL()
       
    75 	{
       
    76 	if (!iFoundChunks)
       
    77 		{
       
    78 		iFoundChunks=ETrue;
       
    79 //		iStartPtr=iBuffer->Data().Ptr();
       
    80 		iStartPtr=iBuffer->Ptr();
       
    81 		iPos=0;
       
    82 		iLastReadPosition=0;//Set by CBase, but what the heck
       
    83 		iDone=EFalse;
       
    84 		}
       
    85 	else
       
    86 		{//We've done another read. If there's < chunk in the buffer then something's wrong
       
    87 		if (iBuffer->Length() < STATIC_CAST(TInt, KRiffChunkHeaderLength))
       
    88 			{
       
    89 			if ((iFormatChunk.iFound) && (iDataChunk.iFound)) 
       
    90 				{
       
    91 				iDone = ETrue; //it should be ok to exit loop
       
    92 				return;
       
    93 				}
       
    94 			else
       
    95 				{
       
    96 				User::Leave(KErrCorrupt);
       
    97 				}
       
    98 			}
       
    99 		}
       
   100 	
       
   101 	while (!iDone)
       
   102 		{
       
   103 		TInt advance=0;
       
   104 		
       
   105 		ReadChunk(&iCurrent);
       
   106 		
       
   107 		if (iCurrent.iName == KRiffChunkNameRiff)//we need to look INSIDE the RIFF chunk
       
   108 			{
       
   109 			if(iBuffer->Length() < STATIC_CAST(TInt, KRiffContainerChunkHeaderLength))
       
   110 				User::Leave(KErrCorrupt);
       
   111 			iRiffChunkLength=iCurrent.iLength + KRiffChunkHeaderLength;
       
   112 			advance=KRiffContainerChunkHeaderLength;
       
   113 			}
       
   114 		else
       
   115 			{
       
   116 			advance=iCurrent.iLength + KRiffChunkHeaderLength;		//... and skip all others
       
   117 			}
       
   118 		
       
   119 		if (iCurrent.iName == KRiffChunkNameFmt_)
       
   120 			AssignChunkTo(&iFormatChunk);
       
   121 		
       
   122 		else if (iCurrent.iName == KRiffChunkNameFact)
       
   123 			AssignChunkTo(&iFactChunk);
       
   124 		
       
   125 		else if (iCurrent.iName == KRiffChunkNameData)
       
   126 			AssignChunkTo(&iDataChunk);
       
   127 		
       
   128 		if (iDataChunk.iFound && iFormatChunk.iFound && iFactChunk.iFound)
       
   129 			{
       
   130 			iDone=ETrue;
       
   131 			}
       
   132 		else
       
   133 			{//still have chunks to look for
       
   134 			iPos+=advance;
       
   135 			if (iPos & 1)
       
   136 				iPos++;
       
   137 			
       
   138 			if ((TUint)iPos>=(TUint)iRiffChunkLength)
       
   139 				{
       
   140 				iDone=ETrue;//end of file
       
   141 				iClipLength = iRiffChunkLength;
       
   142 				}
       
   143 			else
       
   144 				{//make sure we have at least a chunk's worth left in the buffer
       
   145 				if ((TUint)(iPos-iLastReadPosition) > 
       
   146 					(TUint)(iBuffer->Length() -KRiffChunkHeaderLength))
       
   147 					{
       
   148 					iLastReadPosition=iPos;
       
   149 					//DoReadL(iLastReadPosition);
       
   150 					return;
       
   151 					}	
       
   152 				}
       
   153 			}
       
   154 		}
       
   155 	
       
   156 	iClipLength = iRiffChunkLength;
       
   157 	if (iClipLength == 0) User::Leave(KErrNotFound);
       
   158 	else if (!(iDataChunk.iFound && iFormatChunk.iFound))
       
   159 		User::Leave(KErrCorrupt);
       
   160 
       
   161 	}
       
   162 
       
   163 void CWavDecodeUtility::ProcessFormatHeaderL()
       
   164 	{
       
   165 	TMdaRiffChunk* chunk = &iFormatChunk;
       
   166 	
       
   167 	if (!chunk)
       
   168 		User::Leave(KErrCorrupt);
       
   169 	
       
   170 	iLastReadPosition = chunk->iPosition; // Should be beginning of fmt block
       
   171 	//DoReadL(iLastReadPosition);
       
   172 	
       
   173 	// Set the real format
       
   174 	const TUint8* rawform = iBuffer->Ptr() + iLastReadPosition;	//skip _fmt & length
       
   175 	iCodecId = Read16(rawform); rawform+=2;
       
   176 	iChannels = Read16(rawform); rawform+=2;
       
   177 	if ((iChannels != 1)&&(iChannels != 2))		//only 1 or 2 channels allowed
       
   178 		User::Leave(KErrCorrupt); 
       
   179 	
       
   180 	iSampleRate = Read32(rawform); rawform+=4; // Skip bytes per second estimate
       
   181 	if (!iSampleRate) 	User::Leave(KErrCorrupt);
       
   182 	
       
   183 	iAverageBytesPerSecond = Read32(rawform); rawform+=4;
       
   184 	iBlockAlign = Read16(rawform); rawform+=2;
       
   185 	
       
   186 	iBitsPerSample = Read16(rawform);
       
   187 	rawform+=2;
       
   188 	
       
   189 	switch (iCodecId)
       
   190 		{
       
   191 		case KMMFWavFormatTypePcm:
       
   192 			{
       
   193 			}
       
   194 			break;
       
   195 		case KMMFWavFormatTypeImaAdpcm:
       
   196 			{
       
   197 			}
       
   198 			break;
       
   199 		case KMMFWavFormatTypeAlaw:
       
   200 			{
       
   201 			}
       
   202 			break;
       
   203 		case KMMFWavFormatTypeMulaw:
       
   204 			{
       
   205 			}
       
   206 			break;
       
   207 		case KMMFWavFormatTypeGSM610:
       
   208 			{
       
   209 			}
       
   210 			break;
       
   211 		default:
       
   212 			User::Leave(KErrNotSupported);
       
   213 		}
       
   214 	
       
   215 	if (iCodecId == KMMFWavFormatTypeImaAdpcm)
       
   216 		{
       
   217 		TUint16 extraData = Read16(rawform);
       
   218 		if (extraData == 2)
       
   219 			{
       
   220 			rawform+=2;
       
   221 			iSamplesPerBlock = Read16(rawform);
       
   222 			rawform+=2;
       
   223 			}
       
   224 		}
       
   225 	
       
   226 	// Is there a fact chunk?
       
   227 	if (iFactChunk.iFound)			
       
   228 		iHasFactChunk = ETrue;
       
   229 	
       
   230 	// Find the data block
       
   231 	chunk=&iDataChunk;
       
   232 	iStartPosition = chunk->iPosition; 
       
   233 	iDataLength = chunk->iLength;
       
   234 	}