--- a/videoeditorengine/audioeditorengine/codecs/mp3/src/ProcMP3InFileHandler.cpp Fri Jan 29 14:08:33 2010 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1463 +0,0 @@
-/*
-* Copyright (c) 2010 Ixonos Plc.
-* All rights reserved.
-* This component and the accompanying materials are made available
-* under the terms of the "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:
-* Ixonos Plc
-*
-* Description:
-*
-*/
-
-
-/*-- Project Headers. --*/
-#include "AudPanic.h"
-#include "ProcTools.h"
-#include "ProcMP3InFileHandler.h"
-#include "mpheader.h"
-#include "audconstants.h"
-
-
-#include "ProcMP3FrameHandler.h"
-
-// Debug print macro
-#if defined _DEBUG
-#include <e32svr.h>
-#define PRINT(x) RDebug::Print x;
-#else
-#define PRINT(x)
-#endif
-
-/*
- Purpose: Minimum buffer size for determining the payload size
- of a free format mp3 bitstream.
- Explanation: - */
-#define MIN_MP3_FREE_FORMAT_BUF_SIZE (42)
-
-/*
- Purpose: Buffer size for searching the start of a mp3 frame.
- Explanation: - */
-const int16 Kmp3BufSize = 8;
-
-/*
- Purpose: Buffer size for determining an avarage frame size of a mp3 stream.
- Explanation: - */
-const int16 Kmp3BitrateRegions = 4;
-
-/*
- Purpose: # of frames processed from each region.
- Explanation: This is used when the avarage frame size is determined. */
-const int16 Kmp3BitrateNumFrames = 125;
-
-/*
- Purpose: Buffer size for determining if a clip is valid mp3
- Explanation: - */
-const TUint Kmp3TempBufferSize = 4096;
-
-// ID3v2 header's tag offset
-const TUint KSizeOfTagOffset = 6;
-
-// The size of MP3 header, header must include bits for determining frame length
-const TInt KRawMp3FrameHeaderSize = 5;
-
-// Bit rates in bits/sec supported by MPEG2, MPEG1 and MPEG2.5 respectively
-const TInt16 cBitRateTable[3][16] =
- {
- {-1,8,16,24,32,40,48,56,64,80,96,112,128,144,160,0},
- {-1,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0},
- {-1,8,16,24,32,40,48,56,64,80,96,112,128,144,160,0},
- };
-
-// Sampling frequencies supported by MPEG2, MPEG1 and MPEG2.5 respectively
-const TUint16 cSamplingFrequencyTable[3][4] =
- {
- {22050,24000,16000,0},
- {44100,48000,32000,0},
- {11025,12000,8000,0},
- };
-
-const TInt KRawMp3MaxFrameSize = 1441; // 320kbit/s @ 32kHz = int((144*320000/32000)+1)
-
-CProcMP3InFileHandler* CProcMP3InFileHandler::NewL(const TDesC& aFileName, RFile* aFileHandle, CAudClip* aClip,
- TInt aReadBufferSize, TInt aTargetSampleRate, TChannelMode aChannelMode)
-{
- CProcMP3InFileHandler* self = NewLC(aFileName, aFileHandle, aClip, aReadBufferSize,
- aTargetSampleRate, aChannelMode);
- CleanupStack::Pop(self);
-
- return self;
-}
-
-CProcMP3InFileHandler*
-CProcMP3InFileHandler::NewLC(const TDesC& aFileName, RFile* aFileHandle, CAudClip* aClip,
- TInt aReadBufferSize, TInt aTargetSampleRate, TChannelMode aChannelMode)
-{
- CProcMP3InFileHandler* self = new (ELeave) CProcMP3InFileHandler();
- CleanupStack::PushL(self);
- self->ConstructL(aFileName, aFileHandle, aClip, aReadBufferSize,
- aTargetSampleRate, aChannelMode);
-
- return self;
-}
-
-CProcMP3InFileHandler::CProcMP3InFileHandler() : CProcInFileHandler(), mp3FileFormat(0),
- isValidMP3(0), mp3HeaderBytes(0),
- mp3Log(0), isFreeFormatMP3(0), isVbrMP3(0)
-{
-}
-
-
-
-
-TBool CProcMP3InFileHandler::GetEncAudioFrameL(HBufC8*& aFrame, TInt& aSize, TInt32& aTime)
- {
- TBool rValue = EFalse;
-
- if(!iFileOpen)
- {
- TAudPanic::Panic(TAudPanic::EInternal);
- }
-
- aSize = 0;
- aTime = 0;
- aFrame = NULL;
-
- if(isValidMP3)
- {
- TMpFrameState frState;
- int16 frameFound;
- TInt bufSize;
- TPtr8 mp3DataBuf(mp3HeaderBytes, Kmp3BufSize);
-
- /*-- Search start of next frame. --*/
-
- bufSize = BufferedFileRead((TDes8&) mp3DataBuf);
- if(bufSize < Kmp3BufSize)
- ZERO_MEMORY(mp3HeaderBytes + bufSize, Kmp3BufSize - bufSize);
- frameFound = GetMP3Frame(mp3HeaderBytes, Kmp3BufSize, &frState, 0);
-
- /*-- Frame found. --*/
- if(frameFound == 0)
- {
- TInt fLen;
-
- fLen = frState.frameBytes + frState.headerBytes;
- fLen -= Kmp3BufSize - (frState.readBytes - frState.headerBytes);
- if(fLen > 0)
- {
- TInt offset;
- uint8 *audFrameOffsetPtr;
- HBufC8 *audioFrame = HBufC8::NewL(frState.frameBytes + frState.headerBytes);
-
- offset = frState.readBytes - frState.headerBytes;
- mp3DataBuf.Set(mp3HeaderBytes + offset, Kmp3BufSize - offset, Kmp3BufSize - offset);
-
- audioFrame->Des().Copy(((const TDesC8 &) mp3DataBuf));
-
- audFrameOffsetPtr = (uint8 *) audioFrame->Des().Ptr();
-
- TPtr8 audTmpPtr(audFrameOffsetPtr + Kmp3BufSize - offset, fLen, fLen);
-
- bufSize = BufferedFileRead(audTmpPtr, fLen);
-
- fLen = frState.frameBytes + frState.headerBytes;
- audioFrame->Des().SetLength(fLen);
-
- aFrame = audioFrame;
- aSize = fLen;
- aTime = iMp3Edit->GetFrameTime(mp3FileFormat);
- iCurrentTimeMilliseconds += aTime;
-
- TRAPD(err, ManipulateGainL(aFrame));
-
- if (err != KErrNone)
- {
- // something went wrong with the gain manipulation
- // continue by returning the original frame
- }
-
-
- rValue = ETrue;
- }
- }
- }
-
-
-
-
- return (rValue);
- }
-
-
-
-CProcMP3InFileHandler::~CProcMP3InFileHandler()
-{
-// if(iFileOpen)
- CloseFile();
-
- if (iMp3Edit != 0)
- {
- delete iMp3Edit;
- iMp3Edit = 0;
- }
-
- if (iFileName != 0)
- {
- delete iFileName;
- iFileName = 0;
- }
-
- if (iReadBuffer != 0)
- {
- delete iReadBuffer;
- iReadBuffer = 0;
- }
-
- if (mp3FileFormat != 0)
- {
- delete mp3FileFormat;
- mp3FileFormat = 0;
- }
-
- if (mp3HeaderBytes != 0)
- {
- delete mp3HeaderBytes;
- mp3HeaderBytes = 0;
- }
-
- if (iDecoder != 0)
- {
- delete iDecoder;
- iDecoder = 0;
- }
-
- if (iFrameHandler != 0)
- {
- delete iFrameHandler;
- iFrameHandler = 0;
- }
-
- if (iSilentFrame != 0)
- {
- delete iSilentFrame;
- iSilentFrame = 0;
- }
-}
-
-int16 CProcMP3InFileHandler::
-GetMP3Frame(uint8 *dataBytes, int16 bufSize, TMpFrameState *frState, uint8 syncStatus)
-{
-
-
- int16 locateFrame;
- int16 seekSyncStatus = 0;
- TPtr8 mp3DataBuf(dataBytes, bufSize);
-
- /*-- Search start of 1st frame. --*/
- locateFrame = 0;
- frState->totalReadBytes = 0;
-
- while(locateFrame == 0)
- {
- if(syncStatus == 3)
- seekSyncStatus = iMp3Edit->FreeMode(mp3FileFormat, dataBytes, bufSize,
- &frState->readBytes, &frState->frameBytes,
- &frState->headerBytes);
- else
- seekSyncStatus = iMp3Edit->SeekSync(mp3FileFormat, dataBytes, bufSize,
- &frState->readBytes, &frState->frameBytes,
- &frState->headerBytes, (uint8) syncStatus);
-
- /*-- Start of 1st frame found. --*/
- if(seekSyncStatus == 0 || seekSyncStatus == 3)
- locateFrame = 1;
-
- /*-- Update data buffer, start of 1st frame not found yet. --*/
- else if(seekSyncStatus == 2)
- {
- if(frState->readBytes)
- {
- TInt tmpBufLen, tmp2;
-
- /*-- New data bytes to be read into buffer. --*/
- tmpBufLen = (int16) (bufSize - frState->readBytes);
-
- /*-- Move data that is possibly left in the buffer. --*/
- if(tmpBufLen) COPY_MEMORY(dataBytes, dataBytes + frState->readBytes, tmpBufLen);
-
- /*-- Prepare to read. --*/
- mp3DataBuf.Set(dataBytes + tmpBufLen, frState->readBytes, frState->readBytes);
-
- /*-- Update buffer. --*/
- tmp2 = BufferedFileRead((TDes8&) mp3DataBuf);
- if(tmp2 < frState->readBytes)
- ZERO_MEMORY(dataBytes + tmpBufLen + tmp2, frState->readBytes - tmp2);
-
- frState->totalReadBytes += frState->readBytes;
- }
- }
-
- /*-- Abort, start of 1st frame cannot be located. --*/
- else locateFrame = 1;
- }
-
- return (seekSyncStatus);
-
-
-}
-
-void CProcMP3InFileHandler::
-ConstructL(const TDesC& aFileName, RFile* aFileHandle, CAudClip* aClip, TInt aReadBufferSize,
- TInt aTargetSampleRate, TChannelMode aChannelMode)
-{
-
-
- iTargetSampleRate = aTargetSampleRate;
- iChannelMode = aChannelMode;
-
-
- int16 locate1stFrame;
- TMpFrameState frState;
-
- isVbrMP3 = 0;
- isValidMP3 = 0;
- isFreeFormatMP3 = 0;
-
- //-- Initialize file format handle. --
- mp3FileFormat = (TMpTransportHandle *) new (ELeave) TMpTransportHandle[1];
- ZERO_MEMORY(mp3FileFormat, sizeof(TMpTransportHandle));
-
- //-- Buffer for header search. --
- mp3HeaderBytes = new (ELeave) uint8[Kmp3BufSize];
- ZERO_MEMORY(mp3HeaderBytes, Kmp3BufSize);
-
- // -- Buffer for validity check --
- HBufC8* vldBuffer = (HBufC8*) HBufC8::NewLC(Kmp3TempBufferSize);
-
- iMp3Edit = CMp3Edit::NewL();
-
- // Set the file format parameters to default values. Note that this function
- // should be called only once; when searching the start of 1st frame.
- //
- iMp3Edit->InitTransport(mp3FileFormat);
-
- iClip = aClip;
-
- //-- Open file. --//
- InitAndOpenFileL(aFileName, aFileHandle, aReadBufferSize);
-
- TPtr8 mp3DataBuf(mp3HeaderBytes, Kmp3BufSize);
-
- /*-- Read 1st bytes in. --*/
- BufferedFileSetFilePos(0);
- BufferedFileRead((TDes8&) mp3DataBuf);
-
-
- // ----------------------------------------->
-
- // Identify ID3v2 header:
-
- // more info in http://www.id3.org/
-
- TInt tagLen = 0;
- if (mp3DataBuf.Left(3).Compare(_L8("ID3")) == 0)
- {
-
- const TInt KLenOffset = 6;
-
- BufferedFileSetFilePos(KLenOffset);
- BufferedFileRead((TDes8&) mp3DataBuf);
-
- // ID3v2 tag found, calculate lenght:
-
- const TInt K2Pow7 = 128;
- const TInt K2Pow14 = 16384;
- const TInt K2Pow21 = 2097152;
-
- tagLen = K2Pow21 * mp3DataBuf[0] +
- K2Pow14 * mp3DataBuf[1] +
- K2Pow7 * mp3DataBuf[2] +
- mp3DataBuf[3];
-
-
- tagLen += 10; // include ID3v2 header
-
- }
-
- // <-----------------------------------------
-
- BufferedFileSetFilePos(tagLen);
-
- TPtr8 vldDes( vldBuffer->Des() );
-
- TInt bytesRead = BufferedFileRead((TDes8&) vldDes);
- vldDes.SetLength(bytesRead);
-
- TBool result = Validate(vldDes);
-
- CleanupStack::PopAndDestroy(vldBuffer);
-
- if (!result)
- {
- User::Leave(KErrCorrupt);
- }
-
- BufferedFileSetFilePos(tagLen);
- bytesRead = BufferedFileRead((TDes8&) mp3DataBuf);
-
- /*-- Search start of 1st frame. --*/
- locate1stFrame = GetMP3Frame(mp3HeaderBytes, Kmp3BufSize, &frState, 1);
-
- /*-- If free format, we must determine the payload size of the frames. --*/
- if(locate1stFrame == 3)
- {
- int16 tmpBufLen;
- uint8 tmpBuf[MIN_MP3_FREE_FORMAT_BUF_SIZE];
-
- /*-- Switch to larger buffer. --*/
- tmpBufLen = (int16) (Kmp3BufSize - frState.readBytes);
- COPY_MEMORY(tmpBuf, mp3HeaderBytes + frState.readBytes, tmpBufLen);
- if(frState.readBytes)
- {
- int16 tmpBufLen2;
-
- tmpBufLen2 = (int16) (MIN_MP3_FREE_FORMAT_BUF_SIZE - tmpBufLen);
- mp3DataBuf.Set(tmpBuf + tmpBufLen, tmpBufLen2, tmpBufLen2);
- BufferedFileRead((TDes8&) mp3DataBuf);
- }
-
- /*-- Determine the payload size. --*/
- locate1stFrame = GetMP3Frame(tmpBuf, MIN_MP3_FREE_FORMAT_BUF_SIZE, &frState, 3);
-
- /*-- If payload size known, then go back to the start of 1st frame. --*/
- if(locate1stFrame == 0)
- {
- isFreeFormatMP3 = 1;
-
- BufferedFileSetFilePos(0);
- mp3DataBuf.Set(mp3HeaderBytes, Kmp3BufSize, Kmp3BufSize);
- BufferedFileRead((TDes8&) mp3DataBuf);
-
- locate1stFrame = GetMP3Frame(mp3HeaderBytes, Kmp3BufSize, &frState, 0);
- }
- }
-
- if(locate1stFrame == 0)
- isValidMP3 = 1;
-
- BufferedFileSetFilePos(0);
-
- TAudFileProperties prop;
- GetPropertiesL(&prop);
-
- if (iProperties != 0)
- {
-
-
- // generate a header -------------->
-
-
- TUint8 byte1 = 0xFF; // sync
- TUint8 byte2 = 0xFB; // sync + V1,L3 (mp3), no CRC
-
- TBuf8<8> byte3B;
-
- switch (iProperties->iBitrate)
- {
-
- case (32000):
- {
- byte3B.Append(_L8("0001"));
- break;
- }
- case (40000):
- {
- byte3B.Append(_L8("0010"));
- break;
- }
- case (48000):
- {
- byte3B.Append(_L8("0011"));
- break;
- }
- case (56000):
- {
- byte3B.Append(_L8("0100"));
- break;
- }
- case (64000):
- {
- byte3B.Append(_L8("0101"));
- break;
- }
- case (80000):
- {
- byte3B.Append(_L8("0110"));
- break;
- }
- case (96000):
- {
- byte3B.Append(_L8("0111"));
- break;
- }
- case (112000):
- {
- byte3B.Append(_L8("1000"));
- break;
- }
- case (128000):
- {
- byte3B.Append(_L8("1001"));
- break;
- }
- case (160000):
- {
- byte3B.Append(_L8("1010"));
- break;
- }
- case (192000):
- {
- byte3B.Append(_L8("1011"));
- break;
- }
- case (224000):
- {
- byte3B.Append(_L8("1100"));
- break;
- }
- case (256000):
- {
- byte3B.Append(_L8("1101"));
- break;
- }
- case (320000):
- {
- byte3B.Append(_L8("1110"));
- break;
- }
- default:
- {
- if ( iProperties->iBitrateMode == EAudVariable )
- {
- // bitrate for silent frames in variable bitrate mode; use the lowest bitrate.
- // However, mp3 is not an output format so this is not so relevant currently
- byte3B.Append(_L8("0001"));
-
- }
- else
- {
-
- User::Leave(KErrGeneral);
- }
- break;
-
- }
-
- }
-
- switch (iProperties->iSamplingRate)
- {
-
- case(44100):
- {
- byte3B.Append(_L8("00"));
- break;
- }
- case(48000):
- {
- byte3B.Append(_L8("01"));
- break;
- }
- case(32000):
- {
- byte3B.Append(_L8("10"));
- break;
- }
- default:
- {
- User::Leave(KErrGeneral);
- break;
- }
- }
-
-
- byte3B.Append(_L8("00")); // padding + protection bits
-
- TBuf8<8> byte4B;
-
- switch (iProperties->iChannelMode)
- {
-
- case(EAudStereo):
- {
- byte4B.Append(_L8("00"));
- break;
- }
- case(EAudDualChannel):
- {
- byte4B.Append(_L8("10"));
- break;
- }
- case(EAudSingleChannel):
- {
- byte4B.Append(_L8("11"));
- break;
- }
- default:
- {
- User::Leave(KErrGeneral);
- break;
- }
- }
-
-
- byte4B.Append(_L8("000")); // mode extension,
- // not copyrighted,
-
- if (iProperties->iOriginal)
- {
- byte4B.Append(_L8("100"));
- }
- else
- {
- byte4B.Append(_L8("000"));
- }
- //copy of original, no emphasis
-
- TInt frameLength;
- if ( iProperties->iBitrateMode == EAudVariable )
- {
- // Use the lowest bitrate for silent frames in variable bitrate mode.
- // However, mp3 is not an output format so this is not so relevant currently
- frameLength = (144*32000)/(iProperties->iSamplingRate);
- }
- else
- {
- frameLength = (144*iProperties->iBitrate)/(iProperties->iSamplingRate);
- }
-
- iSilentFrame = HBufC8::NewL(frameLength);
-
- TUint byte3 = 0;
- ProcTools::Bin2Dec(byte3B, byte3);
-
- TUint byte4 = 0;
- ProcTools::Bin2Dec(byte4B, byte4);
-
- TPtr8 silentFramePtr(iSilentFrame->Des());
-
- silentFramePtr.FillZ(frameLength);
-
- silentFramePtr[0] = byte1;
- silentFramePtr[1] = byte2;
- silentFramePtr[2] = static_cast<TUint8>(byte3);
- silentFramePtr[3] = static_cast<TUint8>(byte4);
- iSilentFrameDuration = ProcTools::MilliSeconds(iProperties->iFrameDuration);
-
- }
-
- if (aClip != 0)
- {
- iCutInTime = ProcTools::MilliSeconds(aClip->CutInTime());
-
- }
-
- iDecoder = CProcDecoder::NewL();
-
- iDecodingPossible = iDecoder->InitL(*iProperties, aTargetSampleRate, aChannelMode);
-
- iFrameHandler = CProcMP3FrameHandler::NewL();
-
-
- if (iClip != 0 && iClip->Normalizing())
- {
- SetNormalizingGainL(iFrameHandler);
- }
-
-}
-
-TBool CProcMP3InFileHandler::Validate(TDes8& aDes)
-{
-
- const TUint8* bufferPtr = aDes.Ptr();
-
- TInt bufferSize = aDes.Length();
-
- TInt scannedBuffer = 0;
- TInt lenMetaData = 0;
- TInt syncOffset = 0;
- TInt bufferPosition = 0;
-
- if (lenMetaData == 0)
- {
- syncOffset = 0;
- lenMetaData = ID3HeaderLength(aDes, bufferPosition);
- }
-
- TInt bufferRemaining = bufferSize;
-
- while (lenMetaData > 0)
- {
- if (lenMetaData >= bufferRemaining)
- {
- // this buffer contains all metadata
- syncOffset += bufferRemaining;
- lenMetaData -= bufferRemaining;
- return KErrCorrupt;
- }
- else
- {
- syncOffset += lenMetaData;
- scannedBuffer += lenMetaData;
- // be sure to check for following id3 tags
- bufferRemaining = bufferSize - scannedBuffer;
- bufferPosition = scannedBuffer;
- lenMetaData = ID3HeaderLength(aDes, bufferPosition);
- }
- }
-
-
- TInt seekOffset = 0;
- bufferPosition = scannedBuffer;
-
- seekOffset = SeekSync(aDes, bufferPosition);
-
- syncOffset += seekOffset; // offset to this point from content beginning
- scannedBuffer += seekOffset; // offset to this point in this buffer
-
- bufferPosition = scannedBuffer;
-
- if (seekOffset == bufferSize)
- {
- return EFalse;
- }
-
- return ETrue;
-
- }
-
-
-TInt CProcMP3InFileHandler::SeekSync(TDes8& aDes, TInt aBufPos)
- {
- const TUint bufStart = aBufPos;
-
- TInt bufLen = aDes.Length();
- const TUint8* buf = aDes.Ptr() + bufStart;
- const TInt KMaxFrames = 3; // number of frames to check
- const TInt KNotFound = bufLen; // sync not found position
-
- TInt i = 0;
- TInt syncPos = KNotFound;
- TInt maxSeek = KMaxFrames;
- TInt bitRate = 0;
-
- const TUint8* endPtr = buf+bufLen-bufStart;
-
- // Seek a valid frame candidate byte by byte until a valid frame
- // is found or all bytes have been checked.
- while (buf < endPtr && syncPos == KNotFound)
- {
- TInt seekCount = 0;
- const TUint8* framePtr = buf;
- TInt frameBufLen = bufLen;
- syncPos = i;
-
- // Check the validity of this frame candidate and the nearest next
- // frames. If they are not OK, syncPos will be set to KNotFound.
- while (framePtr < endPtr && syncPos != KNotFound && seekCount < maxSeek)
- {
-
- TInt length = FrameInfo(framePtr, frameBufLen, bitRate);
-
- if (length == 0)
- {
- syncPos = KNotFound;
- }
-
- if ((length > 0) && (bitRate < 0))
- {
- maxSeek = 1; // free formatcase
- }
- framePtr += length;
- frameBufLen -= length;
- seekCount++;
-
- // consider SYNC not found if we reach end of buffer before finding 3 SYNC frames
- if ((framePtr >= endPtr) && (seekCount < maxSeek))
- {
- syncPos = KNotFound;
- buf += (bufLen-1); // force an exit from while loop
- }
-
- }
- buf++; bufLen--; i++;
- }
- return syncPos;
- }
-
-TInt CProcMP3InFileHandler::FrameInfo(const TUint8* aBuf,TInt aBufLen,TInt& aBitRate)
- {
- TInt length = 0;
- TUint temp;
- TUint lTempVal;
-
- TInt samplingRate = 0;
- TInt id = 0;
- TInt Padding = 0;
-
- if (aBufLen >= KRawMp3FrameHeaderSize)
- {
- // Extract header fields to aInfo and check their bit syntax
- // (including the sync word!). If the syntax is not OK the length
- // is set to zero.
-
- temp = 0;
- temp = aBuf[0] << 24;
- temp |= (aBuf[1] << 16);
- temp |= (aBuf[2] << 8);
- temp |= aBuf[3];
- if (((temp >> 21) & 0x7FF) != 0x7FF)
- {
- return length;
- }
-
- lTempVal = (temp >> 19) & 0x03;
- switch (lTempVal)
- {
- case 0:
- id = 2; // MPEG2.5
- break;
- case 1:
- return length;
- case 2:
- id = 0; // MPEG 2
- break;
- case 3:
- id = 1; // MPEG 1
- break;
- }
-
- lTempVal = (temp >> 17) & 0x03;
- if (lTempVal != 1)
- {
- return length;
- }
-
- lTempVal = (temp >> 12) & 0x0F;
- aBitRate = cBitRateTable[id][lTempVal]*1000;
-
- if (aBitRate == 0)
- {
- return length;
- }
-
- lTempVal = (temp >> 10) & 0x03;
- if (lTempVal == 3)
- {
- return length;
- }
- else
- {
- samplingRate = cSamplingFrequencyTable[id][lTempVal];
- }
-
- Padding = (temp >> 9) & 0x01;
-
- lTempVal = (temp >> 6) & 0x03;
-
-
- if (lTempVal == 3)
- {
- }
- else
- {
- }
-
- if (aBitRate == -1)
- {
- // For free mode operation
- length = KRawMp3MaxFrameSize;
- }
-
- if (samplingRate > 0 && aBitRate > 0)
- {
- length = (144*aBitRate)/samplingRate;
-
- if (id != 1)
- {
- length >>= 1; /*for MPEG2 and MPEG2.5 */
- }
-
- if (Padding)
- {
- length++;
- }
- }
- }
- return length;
- }
-
-
-TInt CProcMP3InFileHandler::ID3HeaderLength(TDes8& aDes, TInt aPosition)
- {
- TInt lenMetaData;
- TUint offset = aPosition;
-
- _LIT8 (KTagID3, "ID3");
- TPtrC8 searchBuf;
-
- // Set search buffer
- searchBuf.Set(aDes);
-
- const TUint8* ptr = aDes.Ptr();
- TInt len = aDes.Length();
- searchBuf.Set(ptr+offset, len-offset);
-
- TInt startTagPos = searchBuf.Find (KTagID3);
- if (startTagPos == KErrNotFound || startTagPos != 0)
- {
- lenMetaData = 0;
- }
- else
- {
- lenMetaData = searchBuf[KSizeOfTagOffset];
- lenMetaData = ((lenMetaData << 8) | (searchBuf[KSizeOfTagOffset+1] << 1)) >> 1;
- lenMetaData = ((lenMetaData << 8) | (searchBuf[KSizeOfTagOffset+2] << 1)) >> 1;
- lenMetaData = ((lenMetaData << 8) | (searchBuf[KSizeOfTagOffset+3] << 1)) >> 1;
- lenMetaData += 10;
- }
-
- return lenMetaData;
- }
-
-
-int16
-CProcMP3InFileHandler::GetMP3Bitrate(void)
-{
-
-
- TMpFrameState frState;
- int16 bitRate, frameFound, offsetBytes;
- TPtr8 mp3DataBuf(mp3HeaderBytes, Kmp3BufSize);
-
- bitRate = 0;
- isVbrMP3 = 0;
-
- /*-- Search start of 1st frame. --*/
- BufferedFileRead((TDes8&) mp3DataBuf);
- frameFound = GetMP3Frame(mp3HeaderBytes, Kmp3BufSize, &frState, 0);
-
- /*-- How many unknown bytes at the start of the file? --*/
- offsetBytes = static_cast<int16>(frState.totalReadBytes + (frState.readBytes - frState.headerBytes));
-
- /*-- Get bitrate information. --*/
- if(frameFound == 0)
- {
- if(isFreeFormatMP3)
- bitRate = iMp3Edit->EstimateBitrate(mp3FileFormat, 0);
-
- /*
- * Since the mp3 stream is not using free format, we must somehow
- * determine the (average) bitrate. Yes, mp3 header includes
- * information about the bitrate but that's valid only for
- * the current frame. In case variable coding is used the bitrate
- * can vary quite a lot depending on the goodness of the encoder
- * and signal conditions. Also if the mp3 stream is already an edited
- * version, the bitrate can change quite radicly between different portions
- * of the file. At the moment we determine the avarage frame size by
- * dividing the file into 'Kmp3BitrateRegions' regions of equal width
- * and from each region we determine the average frame size. The 1st
- * 'Kmp3BitrateNumFrames' frames are used from each region. The final
- * average frame size is then averaged across each region.
- * The reason why the bitrate estimation is so complicated is related
- * to seeking. At the moment we jump to the desired position and in order
- * to make this jump as accurate as possible we must have accurate information
- * about the average frame size. The advantages of jumping is that it's fast,
- * the side effect might be that we jump to incorrect position, the deviation
- * is negligible with constant bitrate streams but with variable bitrate streams
- * this can lead to quite large deviations, especially if the stream is using
- * the full range of allowed bitrates. Fortunately, this is not the case in
- * typical mp3 streams but after a series of editing we might have a
- * file where bitrate changes are significant. Of course this means also that
- * the quality is not so good either, so probably the user will never create
- * such files due to poor sound quality...
- *
- * The other approach would be the loop each frame and store frame positions,
- * let's say for every second. Works great, but the side effect is quite considerable
- * delay, since it certainly takes some time to process 5000-10000 mp3 frames...
- */
- else
- {
- int32 fPosOffset[Kmp3BitrateRegions];
- TInt fileSize, stepSize, nRegions, byteOffset;
-
- if(iFile.Size(fileSize) == KErrNone)
- {
- uint8 idx;
- int32 nFrames;
- int16 prevBitRate;
- TMPEG_Header *header;
- TInt ProcessingOnGoing;
-
- fileSize -= offsetBytes;
- if(fileSize < 0)
- return (0);
-
- header = &mp3FileFormat->header;
-
- /*-- Build the data region boundaries. --*/
- nRegions = 1;
- stepSize = fileSize / Kmp3BitrateRegions;
- byteOffset = stepSize;
- fPosOffset[0] = stepSize;
- TInt i = 0;
- for(i = 1; i < Kmp3BitrateRegions - 1; i++)
- {
- byteOffset += stepSize;
- if(byteOffset < fileSize)
- {
- nRegions++;
- fPosOffset[i] = byteOffset;
- }
- else break;
- }
-
- idx = 0;
- nFrames = 0;
- ProcessingOnGoing = 1;
- mp3FileFormat->aveFrameLen = 0;
-
- prevBitRate = bit_rate(header);
-
- /*-- Process each data region and accumulate the frame size. --*/
- while(ProcessingOnGoing)
- {
- TInt rValue, bufSize;
-
- for(i = 0; i < Kmp3BitrateNumFrames; i++)
- {
- TInt fLen;
-
- nFrames++;
- fLen = static_cast<int16>(frState.frameBytes + frState.headerBytes);
-
- frameFound = 2;
- mp3FileFormat->aveFrameLen += fLen;
-
- /*-- Check whether bitrate changed => variable bitrate. --*/
- if(!isVbrMP3)
- if(prevBitRate != bit_rate(header))
- isVbrMP3 = 1;
-
- /*
- * Skip the payload, remember that the input buffer has 'Kmp3BufSize'
- * bytes already that belong to the current mp3 frame. These bytes
- * need to be compensated before jumping to the start of next frame.
- */
- fLen -= static_cast<int16>(Kmp3BufSize - (frState.readBytes - frState.headerBytes));
- if(fLen < 0) fLen = 1;
- rValue = BufferedFileSetFilePos(BufferedFileGetFilePos() + fLen);
-
- if(rValue)
- {
- /*-- Read new data for parsing of next frame. --*/
- bufSize = BufferedFileRead((TDes8&) mp3DataBuf);
- if(bufSize < Kmp3BufSize)
- ZERO_MEMORY(mp3HeaderBytes + bufSize, Kmp3BufSize - bufSize);
-
- frameFound = GetMP3Frame(mp3HeaderBytes, Kmp3BufSize, &frState, 0);
- }
-
- if(frameFound != 0)
- {
- ProcessingOnGoing = 0;
- break;
- }
- }
-
- if(ProcessingOnGoing && idx < nRegions)
- {
- frameFound = 2;
-
- /*-- Seek to start of next data region. --*/
- rValue = BufferedFileSetFilePos(fPosOffset[idx++]);
-
- if(rValue)
- {
- /*-- Read new data and search start of frame. --*/
- bufSize = BufferedFileRead((TDes8&) mp3DataBuf);
- if(bufSize < Kmp3BufSize)
- ZERO_MEMORY(mp3HeaderBytes + bufSize, Kmp3BufSize - bufSize);
-
- frameFound = GetMP3Frame(mp3HeaderBytes, Kmp3BufSize, &frState, 0);
- }
-
- if(frameFound != 0)
- ProcessingOnGoing = 0;
- }
- else ProcessingOnGoing = 0;
- }
-
- if(frameFound != 0)
- {
- mp3FileFormat->execState.execMode = GLITCH_FREE;
- mp3FileFormat->header.header = mp3FileFormat->headerOld.header;
- }
-
- /*-- Average frame length, in bytes. --*/
- if(nFrames)
- {
- FLOAT tmp;
-
- tmp = mp3FileFormat->aveFrameLen / (FLOAT) nFrames;
- mp3FileFormat->aveFrameLen = (int16) (tmp + 0.5f);
- }
-
- /*-- This is our estimated bitrate. --*/
- bitRate = iMp3Edit->EstimateBitrate(mp3FileFormat, 1);
- }
- }
- }
- return (bitRate);
-
-}
-
-void
-CProcMP3InFileHandler::GetPropertiesL(TAudFileProperties* aProperties)
-{
- PRINT((_L("CProcMP3InFileHandler::GetPropertiesL in") ));
-
-
- if (iProperties != 0)
- {
- *aProperties = *iProperties;
- return;
- }
-
- if(iFileOpen)
- {
- TInt origFilePos = iFilePos;
-
- aProperties->iFileFormat = EAudFormatUnrecognized;
- aProperties->iAudioType = EAudTypeUnrecognized;
- aProperties->iAudioTypeExtension = EAudExtensionTypeNoExtension;
- aProperties->iBitrate = 0;
- aProperties->iBitrateMode = EAudBitrateModeNotRecognized;
- aProperties->iChannelMode = EAudChannelModeNotRecognized;
- aProperties->iDuration = 0;
- aProperties->iSamplingRate = 0;
- aProperties->iFrameLen = 0;
- aProperties->iFrameCount = 0;
-
- /*-- First mp3 frame found? --*/
- if(isValidMP3)
- {
- TMPEG_Header *header;
-
- header = &mp3FileFormat->header;
-
- /*-- Seek to start of file. --*/
- BufferedFileSetFilePos(0);
-
-
-
- if (version(header) != 1)
- {
- PRINT((_L("CProcMP4InFileHandler::GetPropertiesL header unsupported, leaving") ));
- User::Leave(KErrNotSupported);
- return;
- }
-
-
- /*-- Determine bitrate. --*/
- aProperties->iBitrate = GetMP3Bitrate();
-
-
- if(aProperties->iBitrate)
- {
- TInt fileSize;
-
- iFile.Size(fileSize);
-
- aProperties->iAudioType = EAudMP3;
- aProperties->iFileFormat = EAudFormatMP3;
- aProperties->iBitrateMode = (!isVbrMP3) ? EAudConstant : EAudVariable;
-
- /*-- Determine channel mode. --*/
- switch(mode(header))
- {
- case 0:
- case 1:
- aProperties->iChannelMode = EAudStereo;
- break;
-
- case 2:
- aProperties->iChannelMode = EAudDualChannel;
- break;
-
- case 3:
- default:
- aProperties->iChannelMode = EAudSingleChannel;
- break;
- }
-
- /*-- Estimate duration. --*/
- TInt64 tmp = (TInt64)iMp3Edit->FileLengthInMs(mp3FileFormat, fileSize) * 1000;
- TTimeIntervalMicroSeconds durationMicro(tmp);
- aProperties->iDuration = durationMicro;
-
- aProperties->iSamplingRate = frequency(header);
-
- // Check that the sample rate is supported
- if( (aProperties->iSamplingRate != KAedSampleRate8kHz) &&
- (aProperties->iSamplingRate != KAedSampleRate11kHz) &&
- (aProperties->iSamplingRate != KAedSampleRate16kHz) &&
- (aProperties->iSamplingRate != KAedSampleRate22kHz) &&
- (aProperties->iSamplingRate != KAedSampleRate24kHz) &&
- (aProperties->iSamplingRate != KAedSampleRate32kHz) &&
- (aProperties->iSamplingRate != KAedSampleRate44kHz) &&
- (aProperties->iSamplingRate != KAedSampleRate48kHz) )
- {
- User::Leave(KErrNotSupported);
- }
-
- aProperties->iFrameLen = mp3FileFormat->aveFrameLen;
-
- // casting for PC-Lint
- tmp = (TInt64) (TInt)(iMp3Edit->GetFrameTime(mp3FileFormat) * 1000);
- aProperties->iFrameDuration = tmp;
- aProperties->iFrameCount = ProcTools::GetTInt((aProperties->iDuration).Int64()/(aProperties->iFrameDuration).Int64());
-
- if (((TUint32)header->header & 0x4) != 0)
- {
-
- aProperties->iOriginal = ETrue;
-
- }
-
- BufferedFileSetFilePos(origFilePos);
- }
- }
- else
- {
- PRINT((_L("CProcMP4InFileHandler::GetPropertiesL could not parse frames, leaving") ));
- User::Leave(KErrNotSupported);
- }
- }
- else
- {
- TAudPanic::Panic(TAudPanic::EInternal);
- }
-
- // bitrate is bytes not kilobytes
- aProperties->iBitrate *= 1000;
-
-
- if (iProperties == 0)
- {
- iProperties = new (ELeave) TAudFileProperties;
- *iProperties = *aProperties;
-
- }
-
-}
-
-TBool
-CProcMP3InFileHandler::SeekAudioFrame(TInt32 aTime)
-{
- TBool rValue = EFalse;
-
-
-
- if(!iFileOpen)
- {
- TAudPanic::Panic(TAudPanic::EInternal);
- }
-
- if(isValidMP3)
- {
- int32 fPos;
-
- mp3FileFormat->aveFrameLen = iProperties->iFrameLen;
- fPos = iMp3Edit->GetSeekOffset(mp3FileFormat, aTime);
-
- BufferedFileSetFilePos(fPos);
-
- iCurrentTimeMilliseconds = aTime;
-
- rValue = ETrue;
- }
-
-
-
- return (rValue);
-}
-
-TBool
-CProcMP3InFileHandler::SeekCutInFrame()
-{
- iCurrentTimeMilliseconds = iCutInTime;
-
- return SeekAudioFrame(iCutInTime);
-}
-
-
-TBool
-CProcMP3InFileHandler::GetDurationL(TInt32& aTime, TInt& aFrameAmount)
-{
- TBool rValue = EFalse;
-
-
-
- if(!iFileOpen)
- {
- TAudPanic::Panic(TAudPanic::EInternal);
- }
-
- aTime = 0;
- aFrameAmount = 0;
-
- if(isValidMP3)
- {
- TInt filePos;
- TAudFileProperties aProperties;
-
- filePos = iFilePos;
-
- GetPropertiesL(&aProperties);
-
- if(aProperties.iBitrate)
- {
- rValue = ETrue;
- aTime = ProcTools::MilliSeconds(aProperties.iDuration);
- aFrameAmount = aTime / iMp3Edit->GetFrameTime(mp3FileFormat);
- }
-
- BufferedFileSetFilePos(filePos);
- }
-
-
- return (rValue);
-}
-
-
-TBool
-CProcMP3InFileHandler::SetNormalizingGainL(const CProcFrameHandler* aFrameHandler)
-{
-
- HBufC8* point = 0;
- TInt siz;
- TInt32 tim = 0;
- TInt maxGain = 0;
- RArray<TInt> gains;
- TInt maxAverage = 0;
- TInt tmpGain = 0;
- TInt gainCounter = 0;
- TInt timeNow = 0;
- TBitStream bs;
-
- while(GetEncAudioFrameL(point, siz, tim))
- {
- timeNow += tim;
- ((CProcMP3FrameHandler*) aFrameHandler)->GetMP3Gains(point, gains, maxGain, bs);
-
- for (TInt a = 0 ; a < gains.Count() ; a = a+2)
- {
- tmpGain += gains[a];
- gainCounter++;
- }
- gains.Reset();
-
- if (timeNow > 1000)
- {
- if (tmpGain/gainCounter > maxAverage)
- {
- maxAverage = tmpGain/gainCounter;
- }
-
- timeNow = 0;
- tmpGain = 0;
- gainCounter = 0;
- }
-
- delete point;
-
- }
-
- // bigger value makes normalizing more efficient, but makes
- // dynamic compression more likely to occur
- TInt NormalizingFactor = 179;
- if (iProperties->iBitrate > 20000 && iProperties->iBitrate < 40000)
- {
-
- // 32 kBit/s
- NormalizingFactor = 187;
-
- }
- else if (iProperties->iBitrate > 40000 && iProperties->iBitrate < 80000)
- {
- // 64 kBit/s
- NormalizingFactor = 181;
-
- }
-
-
- else if (iProperties->iBitrate > 80000 && iProperties->iBitrate < 140000)
- {
- // 128 kBit/s
- if (iProperties->iChannelMode == EAudSingleChannel)
- NormalizingFactor = 170;
- else
- NormalizingFactor = 179;
-
- }
- else if (iProperties->iBitrate > 140000)
- {
- // 256 kBit/s
- if (iProperties->iChannelMode == EAudSingleChannel)
- NormalizingFactor = 155;
- else
- NormalizingFactor = 167;
-
- }
- else
- {
-
- if (iProperties->iChannelMode == EAudSingleChannel)
- NormalizingFactor = 170;
-
- }
-
-
- TInt gainBoost = (NormalizingFactor-maxAverage)*3;
-
- if (gainBoost < 0) gainBoost = 0;
-
- iNormalizingMargin = static_cast<TInt8>(gainBoost);
-
- SeekAudioFrame(0);
-
- mp3FileFormat->execState.a0_s16[0] = 0;
- mp3FileFormat->execState.a0_s16[1] = 0;
- mp3FileFormat->execState.a0_s16[2] = 0;
-
- mp3FileFormat->execState.a0_u32[0] = 0;
- mp3FileFormat->execState.a0_u32[1] = 0;
- mp3FileFormat->execState.a0_u32[2] = 0;
-
-
-
-
- return ETrue;
-
-
-}
-
-