home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / flash078.zip / flashsource-r0_7_8.zip / FlashMP3Encoder.cpp < prev    next >
C/C++ Source or Header  |  2001-08-02  |  7KB  |  285 lines

  1. /* MP3 Encoding Extension Class
  2.    Author: Jesse Ezell <JesseEzell@netscape.net>
  3.    Last Updated: Jan. 27, 2000 
  4.  
  5. */
  6.  
  7. /* mp3 reading tables */
  8.  
  9. #include "FSound.h"
  10. #include "FlashMP3Encoder.h"
  11. #include <stdio.h>
  12. #include <iostream>
  13.  
  14. static const int vertab[4]={2,3,1,0};
  15. static const int freqtab[4]={44100,48000,32000};
  16. static const int ratetab[2][3][16]=
  17.  {
  18.    {
  19.      {  0, 32, 64,
  20.  96,128,160,192,224,256,288,320,352,384,416,448,  0},
  21.      {  0, 32, 48, 56, 64, 80,
  22.  96,112,128,160,192,224,256,320,384,  0},
  23.      {  0, 32, 40, 48, 56, 64, 80,
  24.  96,112,128,160,192,224,256,320,  0},
  25.    },
  26.    {
  27.      {  0, 32, 48, 56, 64, 80,
  28.  96,112,128,144,160,176,192,224,256,  0},
  29.      {  0,  8, 16, 24, 32, 40, 48, 56, 64, 80,
  30.  96,112,128,144,160,  0},
  31.      {  0,  8, 16, 24, 32, 40, 48, 56, 64, 80,
  32.  96,112,128,144,160,  0},
  33.    },
  34.  };
  35.  
  36. int FlashMP3Encoder::SeekToNextValidHeader (FILE *fp, 
  37.                                          int &layer, 
  38.                                          int &ver, 
  39.                                          int &freq, 
  40.                                          int &stereo, 
  41.                                          int &rate)
  42.  {
  43.      unsigned char hdr[4];
  44.      
  45.      long nFileEnd, nCurPos;
  46.      
  47.      nCurPos = ftell(fp);
  48.      
  49.      bool          bFound = false;
  50.      long          nRead;
  51.      
  52.      if (nCurPos == -1) return (false);
  53.  
  54.      ::fseek(fp,0,SEEK_END);
  55.      nFileEnd = ftell (fp);
  56.  
  57.      /* what a mess */
  58.      while (!bFound && nCurPos + 3 < nFileEnd)
  59.      {
  60.          ::fseek(fp,nCurPos,SEEK_SET);
  61.          nRead = fread(hdr,1,4,fp);
  62.          if (nRead < 4) 
  63.          {             
  64.              return (false);
  65.          }
  66.          ver=vertab[((hdr[1]>>3)&3)];
  67.         layer=3-((hdr[1]>>1)&3);
  68.         //int pad=(hdr[2]>>1)&1;
  69.         stereo=((hdr[3]>>6)&3)!=3;
  70.         if (hdr[0]!=0xFF || hdr [1] < 0xE0 || ver==3 || layer != 2)
  71.         {   // not a header 
  72.             nCurPos++;
  73.         }
  74.         else
  75.         {
  76.             freq=freqtab[(hdr[2]>>2)&3]>>ver;
  77.             rate=ratetab[ver?1:0][layer][(hdr[2]>>4)&15]*1000;
  78.             if (!freq || !rate)
  79.             {
  80.                 nCurPos++;
  81.             }
  82.             else
  83.             {                 
  84.                  fseek(fp,nCurPos,SEEK_SET);
  85.                  bFound = true;
  86.             }
  87.          }
  88.      }
  89.      return (bFound);
  90.  }
  91.  
  92.  
  93.  int FlashMP3Encoder::ReadMp3Frame (FILE *fp, char *lpData, long *pnSize)
  94.  {
  95.      int   nFrameSize = 0;
  96.      long  lResult = 0;
  97.      if (fp==NULL) return (false);
  98.      int layer1, ver1, freq1, stereo1, rate1;
  99.     
  100.      if (SeekToNextValidHeader (fp, layer1, ver1, freq1, stereo1, rate1))
  101.      {
  102.          nFrameSize = ((ver1?72:144)*rate1)/freq1;
  103.          long nRead = fread(lpData, 1, nFrameSize,fp);
  104.          // clear the padding bit
  105.          if (nRead == nFrameSize)
  106.          {
  107.              if (lpData [2] & 2) // pad bit! 
  108.              {    
  109.                  nRead = fread(&lpData [nFrameSize], 1,1,fp);
  110.                  *pnSize+=nRead;
  111.              }
  112.              lResult = 0;
  113.              
  114.          }
  115.      }
  116.      return (lResult); 
  117.  }
  118.  
  119.  
  120.  
  121.  int FlashMP3Encoder::GetMp3FrameSize (char *szMp3File, long *pnFrameSize, long *pnPCMFrameSize)
  122.  {
  123.      FILE *fp;
  124.      fp=fopen(szMp3File,"rb");
  125.      int layer, ver, freq, stereo, rate;
  126.      *pnFrameSize = 0;
  127.      if (fp==NULL) return (false);
  128.      if (!SeekToNextValidHeader (fp, layer, ver, freq, stereo, rate))
  129.      {
  130.          return (false);
  131.      }
  132.      *pnFrameSize = ((ver ? 72:144)*rate)/freq;
  133.  
  134.      if(freq > 32000) *pnPCMFrameSize = 1152;
  135.         else *pnPCMFrameSize = 576;
  136.     fclose(fp);
  137.      return (0);
  138. }
  139.  
  140. FlashMP3Encoder::FlashMP3Encoder(const char *filename, int FrameRate) :
  141.     m_delay(0), m_frameRate(FrameRate), m_pos(0), m_done(false), m_frame(0)
  142. {
  143.  
  144.      FILE *fp = fopen(filename,"rb");
  145.  
  146.      int &layer = m_layer;
  147.      int &ver = m_ver;
  148.      int &freq = m_freq;
  149.      int &stereo = m_stereo;
  150.      int &rate = m_rate;
  151.  
  152.      long pnFrameSize = 0;
  153.      long pnPCMFrameSize = 0;
  154.  
  155.      if (fp==NULL) return; // ERROR
  156.  
  157.      char *data;
  158.      while (SeekToNextValidHeader (fp, layer, ver, freq, stereo, rate))
  159.      {
  160.         pnFrameSize = ((ver?72:144)*rate)/freq;
  161.         if(freq > 32000) pnPCMFrameSize = 1152;
  162.         else pnPCMFrameSize = 576;
  163.  
  164.          data = (char*)malloc((pnFrameSize+1));
  165.          
  166.         ReadMp3Frame(fp,data,&pnFrameSize);
  167.         
  168.         m_sizes.push_back(pnFrameSize);    
  169.         m_frameData.push_back(data);        
  170.      }
  171.     fclose(fp);
  172.     
  173.     pcmFrameSize=pnPCMFrameSize;
  174.     
  175.     int samplerate;
  176.     if(m_freq==44100) samplerate=3;
  177.     if(m_freq==22050) samplerate=2;
  178.     if(m_freq==11025) samplerate=1;
  179.     if(m_freq==5512) samplerate=0;
  180.     else samplerate = -1;
  181.     if(samplerate == -1)
  182.     {
  183.         //throw ERROR;
  184.     }
  185.  
  186. }
  187.  
  188. FlashMP3Encoder::~FlashMP3Encoder()
  189. {
  190.     for(std::vector<char*>::iterator i = m_frameData.begin(); i != m_frameData.end(); i++)
  191.     {
  192.         free(*i);
  193.     }
  194. }
  195.  
  196. void FlashMP3Encoder::WriteHeader(std::ostream &out)
  197. {
  198.     
  199.     const double mspf_mp3 = 26;
  200.     
  201.     double avg_samples = (double)((1000.0/m_frameRate)/mspf_mp3)*(double)(pcmFrameSize);
  202.     
  203.     int samplerate = 0;
  204.     if(m_freq==44100) samplerate=3;
  205.     if(m_freq==22050) samplerate=2;
  206.     if(m_freq==11025) samplerate=1;
  207.     if(m_freq==5512) samplerate=0;
  208.     out << FlashTagSoundStreamHead2(3, 1,  1, 2, samplerate, 1, m_stereo ? true : false, (UWORD)avg_samples);
  209. }
  210.  
  211. void FlashMP3Encoder::WriteStream(std::ostream &out)
  212. {
  213.     if(!m_done)
  214.     {
  215.         double         mspf      = 1000.0/m_frameRate;
  216.         const double mspf_mp3 = 26.0;
  217.     
  218.         unsigned int i=0;
  219.     
  220.         for(;;)
  221.         {
  222.             if((double)mspf_mp3*i+(m_delay*mspf_mp3/pcmFrameSize) > mspf) break; 
  223.             i++;
  224.         }
  225.         long size=0;
  226.         unsigned int index;
  227.         for(index = 0; (index < i) && (m_pos+index < m_sizes.size()); index++)
  228.         {
  229.             size+=m_sizes[m_pos+index];
  230.         }
  231.         //long delay = (long)((double)index*sps);
  232.     
  233.         char *out2 = (char*)malloc(size+1);
  234.     
  235.         long offset=0;
  236.         for(i=0; i < index; i++)
  237.         {
  238.             memcpy(out2+offset,m_frameData[m_pos+i],m_sizes[m_pos+i]);
  239.             offset+=m_sizes[m_pos+i];
  240.         }
  241.         
  242.         
  243.         out << FlashTagSoundStreamBlockMP3(pcmFrameSize*index, (unsigned short)m_delay, (char *)out2, size); // 1152*index, 
  244.         
  245.         m_frame++;
  246.         m_pos+=index;
  247.         m_delay = (long)(((m_pos * mspf_mp3) - (m_frame*mspf))*pcmFrameSize/26);
  248.  
  249.         if(m_pos >= m_frameData.size()) m_done = true;
  250.     }
  251. }
  252.  
  253. UWORD FlashMP3Encoder::WriteDefineTag(std::ostream &out)
  254. {
  255.     int samplerate = 0;
  256.     if(m_freq==44100) samplerate=3;
  257.     else if(m_freq==22050) samplerate=2;
  258.     else if(m_freq==11025) samplerate=1;
  259.     else if(m_freq==5512) samplerate=0;
  260.     else 
  261.     {
  262.         //throw ERROR;
  263.     }
  264.     
  265.     UDWORD len = 0;
  266.     for(std::vector<UDWORD>::iterator i = m_sizes.begin(); i != m_sizes.end(); i++)
  267.     { 
  268.       len += *i;    
  269.     }
  270.     char *data = (char *)malloc(len);
  271.     UDWORD it=0;
  272.     UDWORD pos=0;
  273.     for(std::vector<char *>::iterator i2 = m_frameData.begin(); i2 != m_frameData.end(); i2++)
  274.     { 
  275.         memcpy(data+pos, *i2, m_sizes[it]);
  276.         pos+=m_sizes[it];
  277.         it++;
  278.     }
  279.     FlashTagDefineSoundMP3 tag((samplerate << 2) | (1 << 1) | (m_stereo), pcmFrameSize*m_sizes.size(), data, len, 0);
  280.     out << tag;
  281.     free (data);
  282.     
  283.     return(tag.GetID());
  284. }
  285.