os/mm/mmlibs/mmfw/tsrc/mmfintegrationtest/ACLNT/WavDecodeUtility.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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 	}