videoeditorengine/audioeditorengine/codecs/mp3/src/ProcMP3InFileHandler.cpp
changeset 0 951a5db380a0
equal deleted inserted replaced
-1:000000000000 0:951a5db380a0
       
     1 /*
       
     2 * Copyright (c) 2010 Ixonos Plc.
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - Initial contribution
       
    11 *
       
    12 * Contributors:
       
    13 * Ixonos Plc
       
    14 *
       
    15 * Description:
       
    16 *
       
    17 */
       
    18 
       
    19 
       
    20 /*-- Project Headers. --*/
       
    21 #include "AudPanic.h"
       
    22 #include "ProcTools.h"
       
    23 #include "ProcMP3InFileHandler.h"
       
    24 #include "mpheader.h"
       
    25 #include "audconstants.h"
       
    26 
       
    27 
       
    28 #include "ProcMP3FrameHandler.h"
       
    29 
       
    30 // Debug print macro
       
    31 #if defined _DEBUG 
       
    32 #include <e32svr.h>
       
    33 #define PRINT(x) RDebug::Print x;
       
    34 #else
       
    35 #define PRINT(x)
       
    36 #endif
       
    37 
       
    38 /*
       
    39    Purpose:     Minimum buffer size for determining the payload size
       
    40                 of a free format mp3 bitstream.
       
    41    Explanation: - */
       
    42 #define MIN_MP3_FREE_FORMAT_BUF_SIZE (42)
       
    43 
       
    44 /*
       
    45    Purpose:     Buffer size for searching the start of a mp3 frame.
       
    46    Explanation: - */
       
    47 const int16 Kmp3BufSize = 8;
       
    48 
       
    49 /*
       
    50    Purpose:     Buffer size for determining an avarage frame size of a mp3 stream.
       
    51    Explanation: - */
       
    52 const int16 Kmp3BitrateRegions = 4;
       
    53 
       
    54 /*
       
    55    Purpose:     # of frames processed from each region.
       
    56    Explanation: This is used when the avarage frame size is determined. */
       
    57 const int16 Kmp3BitrateNumFrames = 125;
       
    58 
       
    59 /*
       
    60    Purpose:     Buffer size for determining if a clip is valid mp3
       
    61    Explanation: - */
       
    62 const TUint Kmp3TempBufferSize = 4096;
       
    63 
       
    64 // ID3v2 header's tag offset
       
    65 const TUint KSizeOfTagOffset = 6;
       
    66 
       
    67 // The size of MP3 header, header must include bits for determining frame length
       
    68 const TInt KRawMp3FrameHeaderSize = 5;
       
    69 
       
    70 // Bit rates in bits/sec supported by MPEG2, MPEG1 and MPEG2.5 respectively
       
    71 const TInt16 cBitRateTable[3][16] =
       
    72 	{
       
    73 		{-1,8,16,24,32,40,48,56,64,80,96,112,128,144,160,0},
       
    74 		{-1,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0},
       
    75 		{-1,8,16,24,32,40,48,56,64,80,96,112,128,144,160,0},
       
    76 	};
       
    77 
       
    78 // Sampling frequencies supported by MPEG2, MPEG1 and MPEG2.5 respectively
       
    79 const TUint16 cSamplingFrequencyTable[3][4] =
       
    80 	{
       
    81 		{22050,24000,16000,0},
       
    82 		{44100,48000,32000,0},
       
    83 		{11025,12000,8000,0},
       
    84 	};
       
    85 
       
    86 const TInt KRawMp3MaxFrameSize = 1441;     // 320kbit/s @ 32kHz = int((144*320000/32000)+1)
       
    87 
       
    88 CProcMP3InFileHandler* CProcMP3InFileHandler::NewL(const TDesC& aFileName, RFile* aFileHandle, CAudClip* aClip, 
       
    89                             TInt aReadBufferSize, TInt aTargetSampleRate, TChannelMode aChannelMode) 
       
    90 {
       
    91   CProcMP3InFileHandler* self = NewLC(aFileName, aFileHandle, aClip, aReadBufferSize, 
       
    92                                           aTargetSampleRate, aChannelMode);
       
    93   CleanupStack::Pop(self);
       
    94   
       
    95   return self;
       
    96 }
       
    97 
       
    98 CProcMP3InFileHandler* 
       
    99 CProcMP3InFileHandler::NewLC(const TDesC& aFileName, RFile* aFileHandle, CAudClip* aClip, 
       
   100                             TInt aReadBufferSize, TInt aTargetSampleRate, TChannelMode aChannelMode) 
       
   101 {
       
   102   CProcMP3InFileHandler* self = new (ELeave) CProcMP3InFileHandler();
       
   103   CleanupStack::PushL(self);
       
   104   self->ConstructL(aFileName, aFileHandle, aClip, aReadBufferSize,
       
   105                       aTargetSampleRate, aChannelMode);
       
   106   
       
   107   return self;
       
   108 }
       
   109 
       
   110 CProcMP3InFileHandler::CProcMP3InFileHandler() : CProcInFileHandler(), mp3FileFormat(0),
       
   111                                                  isValidMP3(0), mp3HeaderBytes(0), 
       
   112                                                  mp3Log(0), isFreeFormatMP3(0), isVbrMP3(0) 
       
   113 {
       
   114 }
       
   115 
       
   116 
       
   117 
       
   118 
       
   119 TBool CProcMP3InFileHandler::GetEncAudioFrameL(HBufC8*& aFrame, TInt& aSize, TInt32& aTime)
       
   120     {
       
   121     TBool rValue = EFalse;
       
   122 
       
   123   if(!iFileOpen) 
       
   124   {
       
   125     TAudPanic::Panic(TAudPanic::EInternal);
       
   126   }
       
   127 
       
   128   aSize = 0;
       
   129   aTime = 0;
       
   130   aFrame = NULL;
       
   131 
       
   132   if(isValidMP3)
       
   133   {
       
   134     TMpFrameState frState;
       
   135     int16 frameFound;
       
   136     TInt bufSize;
       
   137     TPtr8 mp3DataBuf(mp3HeaderBytes, Kmp3BufSize);
       
   138 
       
   139     /*-- Search start of next frame. --*/
       
   140     
       
   141     bufSize = BufferedFileRead((TDes8&) mp3DataBuf);
       
   142     if(bufSize < Kmp3BufSize)
       
   143       ZERO_MEMORY(mp3HeaderBytes + bufSize, Kmp3BufSize - bufSize);
       
   144     frameFound = GetMP3Frame(mp3HeaderBytes, Kmp3BufSize, &frState, 0);
       
   145 
       
   146     /*-- Frame found. --*/
       
   147     if(frameFound == 0)
       
   148     {
       
   149       TInt fLen;
       
   150 
       
   151       fLen = frState.frameBytes + frState.headerBytes;
       
   152       fLen -= Kmp3BufSize - (frState.readBytes - frState.headerBytes);
       
   153       if(fLen > 0)
       
   154       {
       
   155         TInt offset;
       
   156         uint8 *audFrameOffsetPtr;
       
   157         HBufC8 *audioFrame = HBufC8::NewL(frState.frameBytes + frState.headerBytes);
       
   158 
       
   159         offset = frState.readBytes - frState.headerBytes;
       
   160         mp3DataBuf.Set(mp3HeaderBytes + offset, Kmp3BufSize - offset, Kmp3BufSize - offset);
       
   161 
       
   162         audioFrame->Des().Copy(((const TDesC8 &) mp3DataBuf));
       
   163 
       
   164         audFrameOffsetPtr = (uint8 *) audioFrame->Des().Ptr();
       
   165 
       
   166         TPtr8 audTmpPtr(audFrameOffsetPtr + Kmp3BufSize - offset, fLen, fLen);
       
   167 
       
   168         bufSize = BufferedFileRead(audTmpPtr, fLen);
       
   169 
       
   170         fLen = frState.frameBytes + frState.headerBytes;
       
   171         audioFrame->Des().SetLength(fLen);
       
   172 
       
   173         aFrame = audioFrame;
       
   174         aSize = fLen;
       
   175         aTime = iMp3Edit->GetFrameTime(mp3FileFormat);
       
   176         iCurrentTimeMilliseconds += aTime;
       
   177         
       
   178         TRAPD(err, ManipulateGainL(aFrame));
       
   179     
       
   180         if (err != KErrNone)
       
   181             {
       
   182             // something went wrong with the gain manipulation
       
   183             // continue by returning the original frame
       
   184             }
       
   185     
       
   186 
       
   187         rValue = ETrue;
       
   188       }
       
   189     }
       
   190   }
       
   191 
       
   192 
       
   193 
       
   194 
       
   195   return (rValue);
       
   196     }
       
   197 
       
   198 
       
   199 
       
   200 CProcMP3InFileHandler::~CProcMP3InFileHandler() 
       
   201 {
       
   202 //  if(iFileOpen)
       
   203   CloseFile();
       
   204 
       
   205   if (iMp3Edit != 0)
       
   206     {
       
   207       delete iMp3Edit;
       
   208       iMp3Edit = 0;
       
   209     }
       
   210 
       
   211   if (iFileName != 0)
       
   212     {
       
   213       delete iFileName;
       
   214       iFileName = 0;
       
   215     }
       
   216     
       
   217   if (iReadBuffer != 0)
       
   218     {
       
   219       delete iReadBuffer;
       
   220       iReadBuffer = 0;
       
   221     }
       
   222 
       
   223   if (mp3FileFormat != 0)
       
   224     {
       
   225       delete mp3FileFormat;
       
   226       mp3FileFormat = 0;
       
   227     }
       
   228 
       
   229   if (mp3HeaderBytes != 0)
       
   230     {
       
   231       delete mp3HeaderBytes;
       
   232       mp3HeaderBytes = 0;
       
   233     }
       
   234   
       
   235   if (iDecoder != 0)
       
   236     {
       
   237       delete iDecoder;
       
   238       iDecoder = 0;
       
   239     }
       
   240   
       
   241   if (iFrameHandler != 0)
       
   242     {
       
   243       delete iFrameHandler;
       
   244       iFrameHandler = 0;
       
   245     }
       
   246 
       
   247   if (iSilentFrame != 0)
       
   248     {
       
   249       delete iSilentFrame;
       
   250       iSilentFrame = 0;
       
   251     }
       
   252 }
       
   253 
       
   254 int16 CProcMP3InFileHandler::
       
   255 GetMP3Frame(uint8 *dataBytes, int16 bufSize, TMpFrameState *frState, uint8 syncStatus)
       
   256 {
       
   257 
       
   258 
       
   259   int16 locateFrame;
       
   260   int16 seekSyncStatus = 0;
       
   261   TPtr8 mp3DataBuf(dataBytes, bufSize);
       
   262 
       
   263   /*-- Search  start of 1st frame. --*/
       
   264   locateFrame = 0;
       
   265   frState->totalReadBytes = 0;
       
   266   
       
   267   while(locateFrame == 0)
       
   268   {
       
   269     if(syncStatus == 3)
       
   270       seekSyncStatus = iMp3Edit->FreeMode(mp3FileFormat, dataBytes, bufSize, 
       
   271                                    &frState->readBytes, &frState->frameBytes, 
       
   272                                    &frState->headerBytes);
       
   273     else
       
   274       seekSyncStatus = iMp3Edit->SeekSync(mp3FileFormat, dataBytes, bufSize, 
       
   275                                    &frState->readBytes, &frState->frameBytes, 
       
   276                                    &frState->headerBytes, (uint8) syncStatus);
       
   277     
       
   278     /*-- Start of 1st frame found. --*/
       
   279     if(seekSyncStatus == 0 || seekSyncStatus == 3)
       
   280       locateFrame = 1;
       
   281 
       
   282     /*-- Update data buffer, start of 1st frame not found yet. --*/
       
   283     else if(seekSyncStatus == 2)
       
   284     {
       
   285       if(frState->readBytes)
       
   286       {
       
   287         TInt tmpBufLen, tmp2;
       
   288 
       
   289         /*-- New data bytes to be read into buffer. --*/
       
   290         tmpBufLen = (int16) (bufSize - frState->readBytes);
       
   291 
       
   292         /*-- Move data that is possibly left in the buffer. --*/
       
   293         if(tmpBufLen) COPY_MEMORY(dataBytes, dataBytes + frState->readBytes, tmpBufLen);
       
   294 
       
   295         /*-- Prepare to read. --*/
       
   296         mp3DataBuf.Set(dataBytes + tmpBufLen, frState->readBytes, frState->readBytes);
       
   297 
       
   298         /*-- Update buffer. --*/
       
   299         tmp2 = BufferedFileRead((TDes8&) mp3DataBuf);
       
   300         if(tmp2 < frState->readBytes) 
       
   301           ZERO_MEMORY(dataBytes + tmpBufLen + tmp2, frState->readBytes - tmp2);
       
   302 
       
   303         frState->totalReadBytes += frState->readBytes;
       
   304       }
       
   305     }
       
   306 
       
   307     /*-- Abort, start of 1st frame cannot be located. --*/
       
   308     else locateFrame = 1;
       
   309   }
       
   310 
       
   311   return (seekSyncStatus);
       
   312 
       
   313 
       
   314 }
       
   315 
       
   316 void CProcMP3InFileHandler::
       
   317 ConstructL(const TDesC& aFileName, RFile* aFileHandle, CAudClip* aClip, TInt aReadBufferSize,
       
   318             TInt aTargetSampleRate, TChannelMode aChannelMode) 
       
   319 {
       
   320 
       
   321 
       
   322   iTargetSampleRate = aTargetSampleRate;
       
   323   iChannelMode = aChannelMode;
       
   324 
       
   325     
       
   326   int16 locate1stFrame;
       
   327   TMpFrameState frState;
       
   328 
       
   329   isVbrMP3 = 0;
       
   330   isValidMP3 = 0;
       
   331   isFreeFormatMP3 = 0;
       
   332 
       
   333   //-- Initialize file format handle. --
       
   334   mp3FileFormat = (TMpTransportHandle *) new (ELeave) TMpTransportHandle[1];
       
   335   ZERO_MEMORY(mp3FileFormat, sizeof(TMpTransportHandle));
       
   336 
       
   337   //-- Buffer for header search. --
       
   338   mp3HeaderBytes = new (ELeave) uint8[Kmp3BufSize];
       
   339   ZERO_MEMORY(mp3HeaderBytes, Kmp3BufSize);
       
   340   
       
   341   // -- Buffer for validity check --
       
   342   HBufC8* vldBuffer = (HBufC8*) HBufC8::NewLC(Kmp3TempBufferSize);
       
   343 
       
   344   iMp3Edit = CMp3Edit::NewL();
       
   345 
       
   346    // Set the file format parameters to default values. Note that this function
       
   347    // should be called only once; when searching the start of 1st frame.
       
   348    //
       
   349   iMp3Edit->InitTransport(mp3FileFormat);
       
   350 
       
   351   iClip = aClip;
       
   352 
       
   353   //-- Open file. --//
       
   354   InitAndOpenFileL(aFileName, aFileHandle, aReadBufferSize);
       
   355 
       
   356   TPtr8 mp3DataBuf(mp3HeaderBytes, Kmp3BufSize);
       
   357 
       
   358   /*-- Read 1st bytes in. --*/
       
   359   BufferedFileSetFilePos(0);
       
   360   BufferedFileRead((TDes8&) mp3DataBuf);
       
   361   
       
   362   
       
   363   // ----------------------------------------->
       
   364   
       
   365   // Identify ID3v2 header:
       
   366   
       
   367   // more info in http://www.id3.org/
       
   368   
       
   369   TInt tagLen = 0;
       
   370   if (mp3DataBuf.Left(3).Compare(_L8("ID3")) == 0)
       
   371     {
       
   372     
       
   373     const TInt KLenOffset = 6;
       
   374     
       
   375     BufferedFileSetFilePos(KLenOffset);
       
   376     BufferedFileRead((TDes8&) mp3DataBuf);
       
   377     
       
   378     // ID3v2 tag found, calculate lenght:
       
   379 
       
   380     const TInt K2Pow7 = 128;
       
   381     const TInt K2Pow14 = 16384;
       
   382     const TInt K2Pow21 = 2097152;
       
   383     
       
   384     tagLen = K2Pow21 * mp3DataBuf[0] + 
       
   385              K2Pow14 * mp3DataBuf[1] +
       
   386              K2Pow7 * mp3DataBuf[2] +
       
   387              mp3DataBuf[3];
       
   388                   
       
   389                   
       
   390     tagLen += 10; // include ID3v2 header
       
   391 
       
   392     }
       
   393   
       
   394   // <-----------------------------------------
       
   395 
       
   396   BufferedFileSetFilePos(tagLen);
       
   397   
       
   398   TPtr8 vldDes( vldBuffer->Des() );
       
   399   
       
   400   TInt bytesRead = BufferedFileRead((TDes8&) vldDes);
       
   401   vldDes.SetLength(bytesRead);
       
   402     
       
   403   TBool result = Validate(vldDes);
       
   404   
       
   405   CleanupStack::PopAndDestroy(vldBuffer);
       
   406   
       
   407   if (!result)
       
   408   {
       
   409       User::Leave(KErrCorrupt);
       
   410   }
       
   411 
       
   412   BufferedFileSetFilePos(tagLen);
       
   413   bytesRead = BufferedFileRead((TDes8&) mp3DataBuf);
       
   414 
       
   415   /*-- Search start of 1st frame. --*/
       
   416   locate1stFrame = GetMP3Frame(mp3HeaderBytes, Kmp3BufSize, &frState, 1);
       
   417 
       
   418   /*-- If free format, we must determine the payload size of the frames. --*/
       
   419   if(locate1stFrame == 3)
       
   420   {
       
   421     int16 tmpBufLen;
       
   422     uint8 tmpBuf[MIN_MP3_FREE_FORMAT_BUF_SIZE];
       
   423 
       
   424     /*-- Switch to larger buffer. --*/
       
   425     tmpBufLen = (int16) (Kmp3BufSize - frState.readBytes);
       
   426     COPY_MEMORY(tmpBuf, mp3HeaderBytes + frState.readBytes, tmpBufLen);
       
   427     if(frState.readBytes)
       
   428     {
       
   429       int16 tmpBufLen2;
       
   430       
       
   431       tmpBufLen2 = (int16) (MIN_MP3_FREE_FORMAT_BUF_SIZE - tmpBufLen);
       
   432       mp3DataBuf.Set(tmpBuf + tmpBufLen, tmpBufLen2, tmpBufLen2);
       
   433       BufferedFileRead((TDes8&) mp3DataBuf);
       
   434     }
       
   435 
       
   436     /*-- Determine the payload size. --*/
       
   437     locate1stFrame = GetMP3Frame(tmpBuf, MIN_MP3_FREE_FORMAT_BUF_SIZE, &frState, 3);
       
   438 
       
   439     /*-- If payload size known, then go back to the start of 1st frame. --*/
       
   440     if(locate1stFrame == 0)
       
   441     {
       
   442       isFreeFormatMP3 = 1;
       
   443 
       
   444       BufferedFileSetFilePos(0);
       
   445       mp3DataBuf.Set(mp3HeaderBytes, Kmp3BufSize, Kmp3BufSize);
       
   446       BufferedFileRead((TDes8&) mp3DataBuf);
       
   447 
       
   448       locate1stFrame = GetMP3Frame(mp3HeaderBytes, Kmp3BufSize, &frState, 0);
       
   449     }
       
   450   }
       
   451 
       
   452   if(locate1stFrame == 0)
       
   453     isValidMP3 = 1;
       
   454 
       
   455   BufferedFileSetFilePos(0);
       
   456 
       
   457   TAudFileProperties prop;
       
   458   GetPropertiesL(&prop);
       
   459 
       
   460   if (iProperties != 0)
       
   461     {
       
   462       
       
   463       
       
   464       // generate a header -------------->
       
   465       
       
   466       
       
   467       TUint8 byte1 = 0xFF; // sync
       
   468       TUint8 byte2 = 0xFB; // sync + V1,L3 (mp3), no CRC
       
   469       
       
   470       TBuf8<8> byte3B;
       
   471       
       
   472       switch (iProperties->iBitrate)
       
   473       {
       
   474           
       
   475       case (32000):
       
   476           {
       
   477               byte3B.Append(_L8("0001"));
       
   478               break;
       
   479           }
       
   480       case (40000):
       
   481           {
       
   482               byte3B.Append(_L8("0010"));
       
   483               break;
       
   484           }
       
   485       case (48000):
       
   486           {
       
   487               byte3B.Append(_L8("0011"));
       
   488               break;
       
   489           }
       
   490       case (56000):
       
   491           {
       
   492               byte3B.Append(_L8("0100"));
       
   493               break;
       
   494           }
       
   495       case (64000):
       
   496           {
       
   497               byte3B.Append(_L8("0101"));
       
   498               break;
       
   499           }
       
   500       case (80000):
       
   501           {
       
   502               byte3B.Append(_L8("0110"));
       
   503               break;
       
   504           }
       
   505       case (96000):
       
   506           {
       
   507               byte3B.Append(_L8("0111"));
       
   508               break;
       
   509           }
       
   510       case (112000):
       
   511           {
       
   512               byte3B.Append(_L8("1000"));
       
   513               break;
       
   514           }
       
   515       case (128000):
       
   516           {
       
   517               byte3B.Append(_L8("1001"));
       
   518               break;
       
   519           }
       
   520       case (160000):
       
   521           {
       
   522               byte3B.Append(_L8("1010"));
       
   523               break;
       
   524           }
       
   525       case (192000):
       
   526           {
       
   527               byte3B.Append(_L8("1011"));
       
   528               break;
       
   529           }
       
   530       case (224000):
       
   531           {
       
   532               byte3B.Append(_L8("1100"));
       
   533               break;
       
   534           }
       
   535       case (256000):
       
   536           {
       
   537               byte3B.Append(_L8("1101"));
       
   538               break;
       
   539           }
       
   540       case (320000):
       
   541           {
       
   542               byte3B.Append(_L8("1110"));
       
   543               break;
       
   544           }
       
   545       default:
       
   546           {
       
   547           if ( iProperties->iBitrateMode == EAudVariable )
       
   548             {
       
   549             // bitrate for silent frames in variable bitrate mode; use the lowest bitrate. 
       
   550             // However, mp3 is not an output format so this is not so relevant currently
       
   551               byte3B.Append(_L8("0001"));
       
   552             
       
   553             }
       
   554           else
       
   555             {
       
   556             
       
   557               User::Leave(KErrGeneral);
       
   558             }
       
   559               break;
       
   560               
       
   561           }
       
   562           
       
   563       }
       
   564       
       
   565       switch (iProperties->iSamplingRate)
       
   566       {
       
   567           
       
   568       case(44100):
       
   569           {
       
   570               byte3B.Append(_L8("00"));
       
   571               break;
       
   572           }
       
   573       case(48000):
       
   574           {
       
   575               byte3B.Append(_L8("01"));
       
   576               break;
       
   577           }
       
   578       case(32000):
       
   579           {
       
   580               byte3B.Append(_L8("10"));
       
   581               break;
       
   582           }
       
   583       default:
       
   584           {
       
   585               User::Leave(KErrGeneral);
       
   586               break;
       
   587           }
       
   588       }
       
   589       
       
   590       
       
   591       byte3B.Append(_L8("00")); // padding + protection bits
       
   592       
       
   593       TBuf8<8> byte4B;
       
   594       
       
   595       switch (iProperties->iChannelMode)
       
   596       {
       
   597           
       
   598       case(EAudStereo):
       
   599           {
       
   600               byte4B.Append(_L8("00"));
       
   601               break;
       
   602           }
       
   603       case(EAudDualChannel):
       
   604           {
       
   605               byte4B.Append(_L8("10"));
       
   606               break;
       
   607           }
       
   608       case(EAudSingleChannel):
       
   609           {
       
   610               byte4B.Append(_L8("11"));
       
   611               break;
       
   612           }
       
   613       default:
       
   614           {
       
   615               User::Leave(KErrGeneral);
       
   616               break;
       
   617           }
       
   618       }
       
   619       
       
   620       
       
   621       byte4B.Append(_L8("000")); // mode extension, 
       
   622       //    not copyrighted, 
       
   623       
       
   624       if (iProperties->iOriginal)
       
   625       {
       
   626           byte4B.Append(_L8("100"));
       
   627       }
       
   628       else
       
   629       {
       
   630           byte4B.Append(_L8("000"));
       
   631       }
       
   632       //copy of original, no emphasis
       
   633       
       
   634       TInt frameLength;
       
   635       if ( iProperties->iBitrateMode == EAudVariable )
       
   636           {
       
   637           // Use the lowest bitrate for silent frames in variable bitrate mode. 
       
   638           // However, mp3 is not an output format so this is not so relevant currently
       
   639           frameLength = (144*32000)/(iProperties->iSamplingRate);
       
   640           }
       
   641       else
       
   642           {
       
   643           frameLength = (144*iProperties->iBitrate)/(iProperties->iSamplingRate);
       
   644           }
       
   645           
       
   646       iSilentFrame = HBufC8::NewL(frameLength);
       
   647       
       
   648       TUint byte3 = 0;
       
   649       ProcTools::Bin2Dec(byte3B, byte3);
       
   650       
       
   651       TUint byte4 = 0;
       
   652       ProcTools::Bin2Dec(byte4B, byte4);
       
   653       
       
   654       TPtr8 silentFramePtr(iSilentFrame->Des());
       
   655       
       
   656       silentFramePtr.FillZ(frameLength);
       
   657       
       
   658       silentFramePtr[0] = byte1;
       
   659       silentFramePtr[1] = byte2;
       
   660       silentFramePtr[2] = static_cast<TUint8>(byte3);
       
   661       silentFramePtr[3] = static_cast<TUint8>(byte4);
       
   662       iSilentFrameDuration = ProcTools::MilliSeconds(iProperties->iFrameDuration);
       
   663       
       
   664     }
       
   665     
       
   666     if (aClip != 0)
       
   667         {
       
   668         iCutInTime = ProcTools::MilliSeconds(aClip->CutInTime());
       
   669         
       
   670         }
       
   671     
       
   672     iDecoder = CProcDecoder::NewL();
       
   673     
       
   674     iDecodingPossible = iDecoder->InitL(*iProperties, aTargetSampleRate, aChannelMode);
       
   675             
       
   676     iFrameHandler = CProcMP3FrameHandler::NewL();
       
   677 
       
   678 
       
   679     if (iClip != 0 && iClip->Normalizing())
       
   680         {
       
   681         SetNormalizingGainL(iFrameHandler);    
       
   682         }
       
   683 
       
   684 }
       
   685 
       
   686 TBool CProcMP3InFileHandler::Validate(TDes8& aDes)
       
   687 {
       
   688 
       
   689     const TUint8* bufferPtr = aDes.Ptr();
       
   690     
       
   691     TInt bufferSize = aDes.Length();
       
   692 	
       
   693 	TInt scannedBuffer = 0;    	
       
   694 	TInt lenMetaData = 0;    	
       
   695 	TInt syncOffset = 0;
       
   696 	TInt bufferPosition = 0;
       
   697 	
       
   698     if (lenMetaData == 0)
       
   699         {
       
   700         syncOffset = 0;        
       
   701         lenMetaData = ID3HeaderLength(aDes, bufferPosition);
       
   702         }
       
   703 
       
   704     TInt bufferRemaining = bufferSize;
       
   705     
       
   706     while (lenMetaData > 0)
       
   707         {
       
   708 	    if (lenMetaData >= bufferRemaining)
       
   709 	        {
       
   710 	        // this buffer contains all metadata
       
   711 	        syncOffset += bufferRemaining;
       
   712 	        lenMetaData -= bufferRemaining;
       
   713 	        return KErrCorrupt;
       
   714 	        }
       
   715 	    else
       
   716 	        {
       
   717 	        syncOffset += lenMetaData;
       
   718 	        scannedBuffer += lenMetaData;
       
   719 	        // be sure to check for following id3 tags
       
   720 	        bufferRemaining = bufferSize - scannedBuffer;	        
       
   721 	        bufferPosition = scannedBuffer;	        
       
   722 	        lenMetaData = ID3HeaderLength(aDes, bufferPosition);
       
   723     	    }
       
   724         }
       
   725 
       
   726 
       
   727     TInt seekOffset = 0;    
       
   728     bufferPosition = scannedBuffer;
       
   729     	
       
   730 	seekOffset = SeekSync(aDes, bufferPosition);
       
   731 
       
   732     syncOffset += seekOffset; // offset to this point from content beginning
       
   733     scannedBuffer += seekOffset; // offset to this point in this buffer
       
   734         
       
   735     bufferPosition = scannedBuffer;
       
   736     
       
   737 	if (seekOffset == bufferSize)
       
   738 		{        
       
   739         return EFalse;
       
   740 		}
       
   741 		
       
   742     return ETrue;
       
   743     
       
   744     }
       
   745     
       
   746     
       
   747 TInt CProcMP3InFileHandler::SeekSync(TDes8& aDes, TInt aBufPos)
       
   748     {
       
   749     const TUint bufStart = aBufPos;    
       
   750     
       
   751     TInt bufLen = aDes.Length();
       
   752     const TUint8* buf = aDes.Ptr() + bufStart;
       
   753     const TInt KMaxFrames = 3;          // number of frames to check
       
   754     const TInt KNotFound = bufLen;     // sync not found position
       
   755     
       
   756     TInt i = 0;
       
   757     TInt syncPos = KNotFound;
       
   758     TInt maxSeek = KMaxFrames;
       
   759     TInt bitRate = 0;
       
   760         
       
   761     const TUint8* endPtr = buf+bufLen-bufStart;
       
   762 
       
   763     // Seek a valid frame candidate byte by byte until a valid frame
       
   764     // is found or all bytes have been checked.
       
   765     while (buf < endPtr  &&  syncPos == KNotFound)
       
   766 	    {
       
   767         TInt seekCount = 0;
       
   768         const TUint8* framePtr = buf;
       
   769         TInt frameBufLen = bufLen;
       
   770         syncPos = i;
       
   771 
       
   772 		// Check the validity of this frame candidate and the nearest next
       
   773         // frames. If they are not OK, syncPos will be set to KNotFound.
       
   774         while (framePtr < endPtr  &&  syncPos != KNotFound  && seekCount < maxSeek)
       
   775 	        {
       
   776 	        
       
   777             TInt length = FrameInfo(framePtr, frameBufLen, bitRate);
       
   778 
       
   779 			if (length == 0)
       
   780             	{
       
   781                 syncPos = KNotFound;
       
   782 				}
       
   783             
       
   784             if ((length > 0) && (bitRate < 0))
       
   785             	{
       
   786                 maxSeek = 1; // free formatcase
       
   787 				}
       
   788             framePtr += length;
       
   789             frameBufLen -= length;
       
   790             seekCount++;
       
   791 
       
   792 			// consider SYNC not found if we reach end of buffer before finding 3 SYNC frames
       
   793 			if ((framePtr >= endPtr) && (seekCount < maxSeek))
       
   794 				{
       
   795 				syncPos = KNotFound;
       
   796 				buf += (bufLen-1);      // force an exit from while loop				
       
   797 				}
       
   798 
       
   799         	}
       
   800         buf++; bufLen--; i++;
       
   801     	}
       
   802     return syncPos;
       
   803     }
       
   804 
       
   805 TInt CProcMP3InFileHandler::FrameInfo(const TUint8* aBuf,TInt aBufLen,TInt& aBitRate)
       
   806     {
       
   807     TInt length = 0;
       
   808     TUint temp;
       
   809     TUint lTempVal;
       
   810 
       
   811     TInt samplingRate = 0;
       
   812     TInt id = 0;
       
   813     TInt Padding = 0;
       
   814 
       
   815 	if (aBufLen >= KRawMp3FrameHeaderSize)
       
   816 	    {
       
   817 		// Extract header fields to aInfo and check their bit syntax
       
   818 		// (including the sync word!). If the syntax is not OK the length
       
   819 		// is set to zero.
       
   820 
       
   821 		temp = 0;
       
   822 		temp = aBuf[0] << 24;
       
   823 		temp |= (aBuf[1] << 16);
       
   824 		temp |= (aBuf[2] << 8);
       
   825 		temp |= aBuf[3];
       
   826 		if (((temp >> 21) & 0x7FF) != 0x7FF)
       
   827 			{
       
   828 			return length;
       
   829 			}
       
   830 
       
   831 		lTempVal = (temp >> 19) & 0x03;
       
   832 		switch (lTempVal)
       
   833 			{
       
   834 			case 0:
       
   835 				id = 2;  // MPEG2.5				
       
   836 				break;
       
   837 			case 1:
       
   838 				return length;
       
   839 			case 2:				
       
   840 				id = 0;  // MPEG 2				
       
   841 				break;
       
   842 			case 3:
       
   843 				id = 1;  // MPEG 1				
       
   844 				break;
       
   845 			}
       
   846 
       
   847 		lTempVal = (temp >> 17) & 0x03;
       
   848 		if (lTempVal != 1)
       
   849 			{
       
   850 			return length;
       
   851 			}
       
   852 
       
   853 		lTempVal = (temp >> 12) & 0x0F;
       
   854 		aBitRate = cBitRateTable[id][lTempVal]*1000;
       
   855 
       
   856 		if (aBitRate == 0)
       
   857 			{
       
   858 			return length;
       
   859 			}
       
   860 
       
   861 		lTempVal = (temp >> 10) & 0x03;
       
   862 		if (lTempVal == 3)
       
   863 			{
       
   864 			return length;
       
   865 			}
       
   866 		else
       
   867 			{
       
   868 			samplingRate = cSamplingFrequencyTable[id][lTempVal];
       
   869 			}
       
   870 
       
   871 		Padding = (temp >> 9) & 0x01;
       
   872 
       
   873 		lTempVal = (temp >> 6) & 0x03;
       
   874 		
       
   875 
       
   876 		if (lTempVal == 3)
       
   877 			{			
       
   878 			}
       
   879 		else
       
   880             {            
       
   881             }        
       
   882 
       
   883 		if (aBitRate == -1)
       
   884 			{
       
   885 			// For free mode operation
       
   886 			length = KRawMp3MaxFrameSize;
       
   887 			}
       
   888 
       
   889 		if (samplingRate > 0  &&  aBitRate > 0)
       
   890 			{
       
   891 			length = (144*aBitRate)/samplingRate;
       
   892 
       
   893 			if (id != 1)
       
   894 				{
       
   895 				length >>= 1; /*for MPEG2 and MPEG2.5 */
       
   896 				}
       
   897 
       
   898 			if (Padding)
       
   899 				{
       
   900 				length++;
       
   901 				}
       
   902 			}	
       
   903     	}
       
   904     return length;
       
   905     }
       
   906 
       
   907 
       
   908 TInt CProcMP3InFileHandler::ID3HeaderLength(TDes8& aDes, TInt aPosition)
       
   909     {
       
   910 	TInt lenMetaData;	
       
   911 	TUint offset = aPosition;
       
   912 
       
   913 	_LIT8 (KTagID3, "ID3");
       
   914 	TPtrC8 searchBuf;
       
   915 
       
   916 	// Set search buffer	
       
   917 	searchBuf.Set(aDes);
       
   918 
       
   919     const TUint8* ptr = aDes.Ptr();
       
   920 	TInt len = aDes.Length();
       
   921 	searchBuf.Set(ptr+offset, len-offset);
       
   922 
       
   923     TInt startTagPos = searchBuf.Find (KTagID3);
       
   924 	if (startTagPos == KErrNotFound || startTagPos != 0)
       
   925 		{
       
   926         lenMetaData = 0;
       
   927 		}
       
   928 	else
       
   929 		{
       
   930         lenMetaData = searchBuf[KSizeOfTagOffset];
       
   931         lenMetaData = ((lenMetaData << 8) | (searchBuf[KSizeOfTagOffset+1] << 1)) >> 1;
       
   932 		lenMetaData = ((lenMetaData << 8) | (searchBuf[KSizeOfTagOffset+2] << 1)) >> 1;
       
   933 		lenMetaData = ((lenMetaData << 8) | (searchBuf[KSizeOfTagOffset+3] << 1)) >> 1;
       
   934 		lenMetaData += 10;
       
   935 		}
       
   936 
       
   937     return lenMetaData;
       
   938     }
       
   939 
       
   940 
       
   941 int16 
       
   942 CProcMP3InFileHandler::GetMP3Bitrate(void)
       
   943 {
       
   944 
       
   945 
       
   946   TMpFrameState frState;
       
   947   int16 bitRate, frameFound, offsetBytes;
       
   948   TPtr8 mp3DataBuf(mp3HeaderBytes, Kmp3BufSize);
       
   949 
       
   950   bitRate = 0;
       
   951   isVbrMP3 = 0;
       
   952 
       
   953   /*-- Search start of 1st frame. --*/
       
   954   BufferedFileRead((TDes8&) mp3DataBuf);
       
   955   frameFound = GetMP3Frame(mp3HeaderBytes, Kmp3BufSize, &frState, 0);
       
   956 
       
   957   /*-- How many unknown bytes at the start of the file? --*/
       
   958   offsetBytes = static_cast<int16>(frState.totalReadBytes + (frState.readBytes - frState.headerBytes));
       
   959 
       
   960   /*-- Get bitrate information. --*/
       
   961   if(frameFound == 0)
       
   962   {
       
   963     if(isFreeFormatMP3)
       
   964       bitRate = iMp3Edit->EstimateBitrate(mp3FileFormat, 0);
       
   965 
       
   966     /*
       
   967      * Since the mp3 stream is not using free format, we must somehow 
       
   968      * determine the (average) bitrate. Yes, mp3 header includes
       
   969      * information about the bitrate but that's valid only for
       
   970      * the current frame. In case variable coding is used the bitrate
       
   971      * can vary quite a lot depending on the goodness of the encoder
       
   972      * and signal conditions. Also if the mp3 stream is already an edited
       
   973      * version, the bitrate can change quite radicly between different portions
       
   974      * of the file. At the moment we determine the avarage frame size by
       
   975      * dividing the file into 'Kmp3BitrateRegions' regions of equal width
       
   976      * and from each region we determine the average frame size. The 1st
       
   977      * 'Kmp3BitrateNumFrames' frames are used from each region. The final
       
   978      * average frame size is then averaged across each region.
       
   979      * The reason why the bitrate estimation is so complicated is related
       
   980      * to seeking. At the moment we jump to the desired position and in order
       
   981      * to make this jump as accurate as possible we must have accurate information
       
   982      * about the average frame size. The advantages of jumping is that it's fast,
       
   983      * the side effect might be that we jump to incorrect position, the deviation
       
   984      * is negligible with constant bitrate streams but with variable bitrate streams
       
   985      * this can lead to quite large deviations, especially if the stream is using 
       
   986      * the full range of allowed bitrates. Fortunately, this is not the case in 
       
   987      * typical mp3 streams but after a series of editing we might have a 
       
   988      * file where bitrate changes are significant. Of course this means also that
       
   989      * the quality is not so good either, so probably the user will never create
       
   990      * such files due to poor sound quality...
       
   991      * 
       
   992      * The other approach would be the loop each frame and store frame positions,
       
   993      * let's say for every second. Works great, but the side effect is quite considerable
       
   994      * delay, since it certainly takes some time to process 5000-10000 mp3 frames...
       
   995      */
       
   996     else
       
   997     {
       
   998       int32 fPosOffset[Kmp3BitrateRegions];
       
   999       TInt fileSize, stepSize, nRegions, byteOffset;
       
  1000 
       
  1001       if(iFile.Size(fileSize) == KErrNone)
       
  1002       {
       
  1003         uint8 idx;
       
  1004         int32 nFrames;
       
  1005         int16 prevBitRate;
       
  1006         TMPEG_Header *header;
       
  1007         TInt ProcessingOnGoing;
       
  1008 
       
  1009         fileSize -= offsetBytes;
       
  1010         if(fileSize < 0)
       
  1011           return (0);
       
  1012 
       
  1013         header = &mp3FileFormat->header;
       
  1014 
       
  1015         /*-- Build the data region boundaries. --*/
       
  1016         nRegions = 1;
       
  1017         stepSize = fileSize / Kmp3BitrateRegions;
       
  1018         byteOffset = stepSize;
       
  1019         fPosOffset[0] = stepSize;
       
  1020         TInt i = 0;
       
  1021         for(i = 1; i < Kmp3BitrateRegions - 1; i++)
       
  1022         {
       
  1023           byteOffset += stepSize;
       
  1024           if(byteOffset < fileSize)
       
  1025           {
       
  1026             nRegions++;
       
  1027             fPosOffset[i] = byteOffset;
       
  1028           }
       
  1029           else break;
       
  1030         }
       
  1031 
       
  1032         idx = 0;
       
  1033         nFrames = 0;
       
  1034         ProcessingOnGoing = 1;
       
  1035         mp3FileFormat->aveFrameLen = 0;
       
  1036 
       
  1037         prevBitRate = bit_rate(header);
       
  1038 
       
  1039         /*-- Process each data region and accumulate the frame size. --*/
       
  1040         while(ProcessingOnGoing)
       
  1041         {
       
  1042           TInt rValue, bufSize;
       
  1043 
       
  1044           for(i = 0; i < Kmp3BitrateNumFrames; i++)
       
  1045           {
       
  1046             TInt fLen;
       
  1047 
       
  1048             nFrames++;
       
  1049             fLen = static_cast<int16>(frState.frameBytes + frState.headerBytes);
       
  1050 
       
  1051             frameFound = 2;
       
  1052             mp3FileFormat->aveFrameLen += fLen;
       
  1053 
       
  1054             /*-- Check whether bitrate changed => variable bitrate. --*/
       
  1055             if(!isVbrMP3)
       
  1056               if(prevBitRate != bit_rate(header))
       
  1057                 isVbrMP3 = 1;
       
  1058 
       
  1059             /*
       
  1060              * Skip the payload, remember that the input buffer has 'Kmp3BufSize'
       
  1061              * bytes already that belong to the current mp3 frame. These bytes
       
  1062              * need to be compensated before jumping to the start of next frame.
       
  1063              */
       
  1064             fLen -= static_cast<int16>(Kmp3BufSize - (frState.readBytes - frState.headerBytes)); 
       
  1065             if(fLen < 0) fLen = 1;
       
  1066             rValue = BufferedFileSetFilePos(BufferedFileGetFilePos() + fLen);
       
  1067 
       
  1068             if(rValue) 
       
  1069             {
       
  1070               /*-- Read new data for parsing of next frame. --*/
       
  1071               bufSize = BufferedFileRead((TDes8&) mp3DataBuf);
       
  1072               if(bufSize < Kmp3BufSize)
       
  1073                 ZERO_MEMORY(mp3HeaderBytes + bufSize, Kmp3BufSize - bufSize);
       
  1074 
       
  1075               frameFound = GetMP3Frame(mp3HeaderBytes, Kmp3BufSize, &frState, 0);
       
  1076             }
       
  1077             
       
  1078             if(frameFound != 0)
       
  1079             {
       
  1080               ProcessingOnGoing = 0;
       
  1081               break;
       
  1082             }
       
  1083           }
       
  1084 
       
  1085           if(ProcessingOnGoing && idx < nRegions)
       
  1086           {
       
  1087             frameFound = 2;
       
  1088 
       
  1089             /*-- Seek to start of next data region. --*/
       
  1090             rValue = BufferedFileSetFilePos(fPosOffset[idx++]);
       
  1091 
       
  1092             if(rValue)
       
  1093             {
       
  1094               /*-- Read new data and search start of frame. --*/
       
  1095               bufSize = BufferedFileRead((TDes8&) mp3DataBuf);
       
  1096               if(bufSize < Kmp3BufSize)
       
  1097                 ZERO_MEMORY(mp3HeaderBytes + bufSize, Kmp3BufSize - bufSize);
       
  1098 
       
  1099               frameFound = GetMP3Frame(mp3HeaderBytes, Kmp3BufSize, &frState, 0);
       
  1100             }
       
  1101 
       
  1102             if(frameFound != 0)
       
  1103               ProcessingOnGoing = 0;
       
  1104           }
       
  1105           else ProcessingOnGoing = 0;
       
  1106         }
       
  1107 
       
  1108         if(frameFound != 0)
       
  1109         {
       
  1110           mp3FileFormat->execState.execMode = GLITCH_FREE;
       
  1111           mp3FileFormat->header.header = mp3FileFormat->headerOld.header;
       
  1112         }
       
  1113 
       
  1114         /*-- Average frame length, in bytes. --*/
       
  1115         if(nFrames)
       
  1116         {
       
  1117           FLOAT tmp;
       
  1118 
       
  1119           tmp = mp3FileFormat->aveFrameLen / (FLOAT) nFrames;
       
  1120           mp3FileFormat->aveFrameLen = (int16) (tmp + 0.5f);
       
  1121         }
       
  1122 
       
  1123         /*-- This is our estimated bitrate. --*/
       
  1124         bitRate = iMp3Edit->EstimateBitrate(mp3FileFormat, 1);
       
  1125       }
       
  1126     }
       
  1127   }
       
  1128   return (bitRate);
       
  1129 
       
  1130 }
       
  1131 
       
  1132 void 
       
  1133 CProcMP3InFileHandler::GetPropertiesL(TAudFileProperties* aProperties) 
       
  1134 {
       
  1135     PRINT((_L("CProcMP3InFileHandler::GetPropertiesL in") ));
       
  1136 
       
  1137 
       
  1138     if (iProperties != 0)
       
  1139         {
       
  1140         *aProperties = *iProperties;
       
  1141         return;
       
  1142         }
       
  1143 
       
  1144     if(iFileOpen) 
       
  1145         {
       
  1146         TInt origFilePos = iFilePos;
       
  1147 
       
  1148         aProperties->iFileFormat = EAudFormatUnrecognized;
       
  1149         aProperties->iAudioType = EAudTypeUnrecognized;
       
  1150         aProperties->iAudioTypeExtension = EAudExtensionTypeNoExtension;
       
  1151         aProperties->iBitrate = 0;
       
  1152         aProperties->iBitrateMode = EAudBitrateModeNotRecognized;
       
  1153         aProperties->iChannelMode = EAudChannelModeNotRecognized;
       
  1154         aProperties->iDuration = 0;
       
  1155         aProperties->iSamplingRate = 0;
       
  1156         aProperties->iFrameLen = 0;
       
  1157         aProperties->iFrameCount = 0;
       
  1158 
       
  1159         /*-- First mp3 frame found? --*/
       
  1160         if(isValidMP3)
       
  1161             {
       
  1162             TMPEG_Header *header;
       
  1163 
       
  1164             header = &mp3FileFormat->header;
       
  1165 
       
  1166             /*-- Seek to start of file. --*/
       
  1167             BufferedFileSetFilePos(0);
       
  1168 
       
  1169           
       
  1170 
       
  1171             if (version(header) != 1)
       
  1172                 {
       
  1173                 PRINT((_L("CProcMP4InFileHandler::GetPropertiesL header unsupported, leaving") ));
       
  1174                 User::Leave(KErrNotSupported);
       
  1175                 return;
       
  1176                 }
       
  1177 
       
  1178 
       
  1179             /*-- Determine bitrate. --*/
       
  1180             aProperties->iBitrate = GetMP3Bitrate();
       
  1181 
       
  1182          
       
  1183             if(aProperties->iBitrate)
       
  1184                 {
       
  1185                 TInt fileSize;
       
  1186 
       
  1187                 iFile.Size(fileSize);
       
  1188 
       
  1189                 aProperties->iAudioType = EAudMP3;
       
  1190                 aProperties->iFileFormat = EAudFormatMP3;
       
  1191                 aProperties->iBitrateMode = (!isVbrMP3) ? EAudConstant : EAudVariable;
       
  1192 
       
  1193                 /*-- Determine channel mode. --*/
       
  1194                 switch(mode(header))
       
  1195                     {
       
  1196                     case 0:
       
  1197                     case 1:
       
  1198                         aProperties->iChannelMode = EAudStereo;
       
  1199                         break;
       
  1200 
       
  1201                     case 2:
       
  1202                         aProperties->iChannelMode = EAudDualChannel;
       
  1203                         break;
       
  1204 
       
  1205                     case 3:
       
  1206                     default:
       
  1207                         aProperties->iChannelMode = EAudSingleChannel;
       
  1208                         break;
       
  1209                     }
       
  1210 
       
  1211                 /*-- Estimate duration. --*/
       
  1212                 TInt64 tmp = (TInt64)iMp3Edit->FileLengthInMs(mp3FileFormat, fileSize) * 1000;
       
  1213                 TTimeIntervalMicroSeconds durationMicro(tmp);
       
  1214                 aProperties->iDuration = durationMicro;
       
  1215 
       
  1216                 aProperties->iSamplingRate = frequency(header);
       
  1217                 
       
  1218                 // Check that the sample rate is supported    
       
  1219                 if( (aProperties->iSamplingRate != KAedSampleRate8kHz) &&
       
  1220                     (aProperties->iSamplingRate != KAedSampleRate11kHz) &&
       
  1221                     (aProperties->iSamplingRate != KAedSampleRate16kHz) &&
       
  1222                     (aProperties->iSamplingRate != KAedSampleRate22kHz) &&
       
  1223                     (aProperties->iSamplingRate != KAedSampleRate24kHz) &&
       
  1224                     (aProperties->iSamplingRate != KAedSampleRate32kHz) &&
       
  1225                     (aProperties->iSamplingRate != KAedSampleRate44kHz) &&
       
  1226                     (aProperties->iSamplingRate != KAedSampleRate48kHz) )
       
  1227                     {
       
  1228                     User::Leave(KErrNotSupported);
       
  1229                     }
       
  1230 
       
  1231                 aProperties->iFrameLen = mp3FileFormat->aveFrameLen;
       
  1232             
       
  1233                 // casting for PC-Lint
       
  1234                 tmp = (TInt64) (TInt)(iMp3Edit->GetFrameTime(mp3FileFormat) * 1000);
       
  1235                 aProperties->iFrameDuration = tmp;
       
  1236                 aProperties->iFrameCount = ProcTools::GetTInt((aProperties->iDuration).Int64()/(aProperties->iFrameDuration).Int64());
       
  1237 
       
  1238                 if (((TUint32)header->header & 0x4) != 0)
       
  1239                     {
       
  1240 
       
  1241                     aProperties->iOriginal = ETrue;
       
  1242                 
       
  1243                     }
       
  1244 
       
  1245                 BufferedFileSetFilePos(origFilePos);
       
  1246                 }
       
  1247             }
       
  1248         else
       
  1249             {
       
  1250             PRINT((_L("CProcMP4InFileHandler::GetPropertiesL could not parse frames, leaving") ));
       
  1251             User::Leave(KErrNotSupported);
       
  1252             }
       
  1253         }
       
  1254     else 
       
  1255     {
       
  1256         TAudPanic::Panic(TAudPanic::EInternal);
       
  1257     }
       
  1258 
       
  1259     // bitrate is bytes not kilobytes
       
  1260     aProperties->iBitrate *= 1000;
       
  1261 
       
  1262 
       
  1263     if (iProperties == 0)
       
  1264     {
       
  1265         iProperties = new (ELeave) TAudFileProperties;
       
  1266         *iProperties = *aProperties;
       
  1267         
       
  1268     }
       
  1269     
       
  1270 }
       
  1271 
       
  1272 TBool 
       
  1273 CProcMP3InFileHandler::SeekAudioFrame(TInt32 aTime) 
       
  1274 {
       
  1275   TBool rValue = EFalse;
       
  1276 
       
  1277 
       
  1278 
       
  1279   if(!iFileOpen) 
       
  1280   {
       
  1281     TAudPanic::Panic(TAudPanic::EInternal);
       
  1282   }
       
  1283 
       
  1284   if(isValidMP3)
       
  1285   {
       
  1286     int32 fPos;
       
  1287     
       
  1288     mp3FileFormat->aveFrameLen = iProperties->iFrameLen;
       
  1289     fPos = iMp3Edit->GetSeekOffset(mp3FileFormat, aTime);
       
  1290 
       
  1291     BufferedFileSetFilePos(fPos);
       
  1292 
       
  1293     iCurrentTimeMilliseconds = aTime;
       
  1294 
       
  1295     rValue = ETrue;
       
  1296   }
       
  1297 
       
  1298 
       
  1299 
       
  1300   return (rValue);
       
  1301 }    
       
  1302 
       
  1303 TBool 
       
  1304 CProcMP3InFileHandler::SeekCutInFrame() 
       
  1305 {
       
  1306   iCurrentTimeMilliseconds = iCutInTime;
       
  1307 
       
  1308   return SeekAudioFrame(iCutInTime);
       
  1309 }
       
  1310 
       
  1311 
       
  1312 TBool 
       
  1313 CProcMP3InFileHandler::GetDurationL(TInt32& aTime, TInt& aFrameAmount) 
       
  1314 {
       
  1315   TBool rValue = EFalse;
       
  1316 
       
  1317 
       
  1318 
       
  1319   if(!iFileOpen) 
       
  1320   {
       
  1321     TAudPanic::Panic(TAudPanic::EInternal);
       
  1322   }
       
  1323 
       
  1324   aTime = 0;
       
  1325   aFrameAmount = 0;
       
  1326 
       
  1327   if(isValidMP3)
       
  1328   {
       
  1329     TInt filePos;
       
  1330     TAudFileProperties aProperties;
       
  1331     
       
  1332     filePos = iFilePos;
       
  1333 
       
  1334     GetPropertiesL(&aProperties); 
       
  1335 
       
  1336     if(aProperties.iBitrate)
       
  1337     {
       
  1338       rValue = ETrue;
       
  1339       aTime = ProcTools::MilliSeconds(aProperties.iDuration);
       
  1340       aFrameAmount = aTime / iMp3Edit->GetFrameTime(mp3FileFormat);
       
  1341     }
       
  1342 
       
  1343     BufferedFileSetFilePos(filePos);
       
  1344   }
       
  1345     
       
  1346 
       
  1347   return (rValue);
       
  1348 }
       
  1349 
       
  1350 
       
  1351 TBool 
       
  1352 CProcMP3InFileHandler::SetNormalizingGainL(const CProcFrameHandler* aFrameHandler)
       
  1353 {
       
  1354     
       
  1355     HBufC8* point = 0;
       
  1356     TInt siz;
       
  1357     TInt32 tim = 0;
       
  1358     TInt maxGain = 0;
       
  1359     RArray<TInt> gains;
       
  1360     TInt maxAverage = 0;
       
  1361     TInt tmpGain = 0;
       
  1362     TInt gainCounter = 0;
       
  1363     TInt timeNow = 0;
       
  1364     TBitStream bs;
       
  1365 
       
  1366     while(GetEncAudioFrameL(point, siz, tim)) 
       
  1367     {
       
  1368         timeNow += tim;
       
  1369         ((CProcMP3FrameHandler*) aFrameHandler)->GetMP3Gains(point, gains, maxGain, bs);
       
  1370         
       
  1371         for (TInt a = 0 ; a < gains.Count() ; a = a+2)
       
  1372         {
       
  1373             tmpGain += gains[a];
       
  1374             gainCounter++;
       
  1375         }
       
  1376         gains.Reset();
       
  1377         
       
  1378         if (timeNow > 1000)
       
  1379         {
       
  1380             if (tmpGain/gainCounter > maxAverage)
       
  1381             {
       
  1382                 maxAverage = tmpGain/gainCounter;
       
  1383             }
       
  1384             
       
  1385             timeNow = 0;
       
  1386             tmpGain = 0;
       
  1387             gainCounter = 0;
       
  1388         }
       
  1389         
       
  1390         delete point;
       
  1391         
       
  1392     }
       
  1393 
       
  1394     // bigger value makes normalizing more efficient, but makes
       
  1395     // dynamic compression more likely to occur
       
  1396     TInt NormalizingFactor = 179;
       
  1397     if (iProperties->iBitrate > 20000 && iProperties->iBitrate < 40000)
       
  1398     {
       
  1399         
       
  1400         // 32 kBit/s
       
  1401         NormalizingFactor = 187;
       
  1402         
       
  1403     }
       
  1404     else if (iProperties->iBitrate > 40000 && iProperties->iBitrate < 80000)
       
  1405     {
       
  1406         // 64 kBit/s
       
  1407         NormalizingFactor = 181;
       
  1408         
       
  1409     }
       
  1410     
       
  1411     
       
  1412     else if (iProperties->iBitrate > 80000 && iProperties->iBitrate < 140000)
       
  1413     {
       
  1414         // 128 kBit/s
       
  1415         if (iProperties->iChannelMode == EAudSingleChannel)
       
  1416             NormalizingFactor = 170;
       
  1417         else
       
  1418             NormalizingFactor = 179;
       
  1419         
       
  1420     }
       
  1421     else if (iProperties->iBitrate > 140000)
       
  1422     {
       
  1423         // 256 kBit/s
       
  1424         if (iProperties->iChannelMode == EAudSingleChannel)
       
  1425             NormalizingFactor = 155;
       
  1426         else
       
  1427             NormalizingFactor = 167;
       
  1428         
       
  1429     }
       
  1430     else
       
  1431     {
       
  1432         
       
  1433         if (iProperties->iChannelMode == EAudSingleChannel)
       
  1434             NormalizingFactor = 170;
       
  1435         
       
  1436     }
       
  1437     
       
  1438     
       
  1439     TInt gainBoost = (NormalizingFactor-maxAverage)*3;
       
  1440     
       
  1441     if (gainBoost < 0) gainBoost = 0;
       
  1442     
       
  1443     iNormalizingMargin = static_cast<TInt8>(gainBoost);
       
  1444 
       
  1445     SeekAudioFrame(0);
       
  1446 
       
  1447     mp3FileFormat->execState.a0_s16[0] = 0;
       
  1448     mp3FileFormat->execState.a0_s16[1] = 0;
       
  1449     mp3FileFormat->execState.a0_s16[2] = 0;
       
  1450 
       
  1451     mp3FileFormat->execState.a0_u32[0] = 0;
       
  1452     mp3FileFormat->execState.a0_u32[1] = 0;
       
  1453     mp3FileFormat->execState.a0_u32[2] = 0;
       
  1454 
       
  1455 
       
  1456 
       
  1457     
       
  1458     return ETrue;
       
  1459     
       
  1460     
       
  1461 }
       
  1462 
       
  1463