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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
16 #include "mmfwavformat.h"
18 #include "WavDecodeUtility.h"
21 CWavDecodeUtility::CWavDecodeUtility()
25 void CWavDecodeUtility::ConstructL(TDesC8& aBuffer)
29 ProcessFormatHeaderL();
32 CWavDecodeUtility* CWavDecodeUtility::NewL(TDesC8& aBuffer)
34 CWavDecodeUtility* self = new (ELeave) CWavDecodeUtility();
35 CleanupStack::PushL(self);
36 self->ConstructL(aBuffer);
42 CWavDecodeUtility::~CWavDecodeUtility()
46 TUint16 CWavDecodeUtility::Read16(const TUint8* aPtr)
49 TUint16 ret = *(REINTERPRET_CAST(const TUint16*, aPtr));
53 TUint32 CWavDecodeUtility::Read32(const TUint8* aPtr)
61 void CWavDecodeUtility::AssignChunkTo(TMdaRiffChunk* aAssignedChunk)
63 Mem::Copy(REINTERPRET_CAST(TUint8*, aAssignedChunk), REINTERPRET_CAST(TUint8*, &iCurrent),sizeof(TMdaRiffChunk));
64 aAssignedChunk->iFound=ETrue;
67 void CWavDecodeUtility::ReadChunk(TMdaRiffChunk* aChunk)
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);
74 void CWavDecodeUtility::FindRiffChunksL()
79 // iStartPtr=iBuffer->Data().Ptr();
80 iStartPtr=iBuffer->Ptr();
82 iLastReadPosition=0;//Set by CBase, but what the heck
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))
89 if ((iFormatChunk.iFound) && (iDataChunk.iFound))
91 iDone = ETrue; //it should be ok to exit loop
96 User::Leave(KErrCorrupt);
105 ReadChunk(&iCurrent);
107 if (iCurrent.iName == KRiffChunkNameRiff)//we need to look INSIDE the RIFF chunk
109 if(iBuffer->Length() < STATIC_CAST(TInt, KRiffContainerChunkHeaderLength))
110 User::Leave(KErrCorrupt);
111 iRiffChunkLength=iCurrent.iLength + KRiffChunkHeaderLength;
112 advance=KRiffContainerChunkHeaderLength;
116 advance=iCurrent.iLength + KRiffChunkHeaderLength; //... and skip all others
119 if (iCurrent.iName == KRiffChunkNameFmt_)
120 AssignChunkTo(&iFormatChunk);
122 else if (iCurrent.iName == KRiffChunkNameFact)
123 AssignChunkTo(&iFactChunk);
125 else if (iCurrent.iName == KRiffChunkNameData)
126 AssignChunkTo(&iDataChunk);
128 if (iDataChunk.iFound && iFormatChunk.iFound && iFactChunk.iFound)
133 {//still have chunks to look for
138 if ((TUint)iPos>=(TUint)iRiffChunkLength)
140 iDone=ETrue;//end of file
141 iClipLength = iRiffChunkLength;
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))
148 iLastReadPosition=iPos;
149 //DoReadL(iLastReadPosition);
156 iClipLength = iRiffChunkLength;
157 if (iClipLength == 0) User::Leave(KErrNotFound);
158 else if (!(iDataChunk.iFound && iFormatChunk.iFound))
159 User::Leave(KErrCorrupt);
163 void CWavDecodeUtility::ProcessFormatHeaderL()
165 TMdaRiffChunk* chunk = &iFormatChunk;
168 User::Leave(KErrCorrupt);
170 iLastReadPosition = chunk->iPosition; // Should be beginning of fmt block
171 //DoReadL(iLastReadPosition);
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);
180 iSampleRate = Read32(rawform); rawform+=4; // Skip bytes per second estimate
181 if (!iSampleRate) User::Leave(KErrCorrupt);
183 iAverageBytesPerSecond = Read32(rawform); rawform+=4;
184 iBlockAlign = Read16(rawform); rawform+=2;
186 iBitsPerSample = Read16(rawform);
191 case KMMFWavFormatTypePcm:
195 case KMMFWavFormatTypeImaAdpcm:
199 case KMMFWavFormatTypeAlaw:
203 case KMMFWavFormatTypeMulaw:
207 case KMMFWavFormatTypeGSM610:
212 User::Leave(KErrNotSupported);
215 if (iCodecId == KMMFWavFormatTypeImaAdpcm)
217 TUint16 extraData = Read16(rawform);
221 iSamplesPerBlock = Read16(rawform);
226 // Is there a fact chunk?
227 if (iFactChunk.iFound)
228 iHasFactChunk = ETrue;
230 // Find the data block
232 iStartPosition = chunk->iPosition;
233 iDataLength = chunk->iLength;