AC3FileSrc.cpp
上传用户:tuheem
上传日期:2007-05-01
资源大小:21889k
文件大小:10k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <windows.h>
  4. #include <vfw.h>
  5. #include "AC3FileSrc.h"
  6. /////////////////////////////
  7. // byte swapping routine
  8. #define SWAP_ENDIAN32(x)  ((((uint_8*)&x)[0] << 24) |  
  9.    (((uint_8*)&x)[1] << 16) |  
  10.    (((uint_8*)&x)[2] << 8)  |  
  11.    ((uint_8*)&x)[3])           
  12. AC3_Bitstream::AC3_Bitstream(FILE *f) 
  13. {
  14.   file            = f;
  15.   current_word    = 0;
  16.   bits_left       = 0;
  17.   total_bits_read = 0;
  18.   done            = FALSE;
  19.   
  20.   // preload data
  21.   this->Load();
  22. }
  23. AC3_Bitstream::~AC3_Bitstream() 
  24. {
  25. }
  26. // Load data from file - does byte swapping
  27. int AC3_Bitstream::Load()
  28. {
  29.   int bytes_read = 0;
  30.   if (file!=NULL){
  31.     bytes_read = fread(&current_word,4,1,file);
  32.   }
  33.   bytes_read = ( bytes_read << 2 ); /* multiply by 4 */
  34.   current_word = SWAP_ENDIAN32(current_word);
  35.   bits_left = bytes_read * 8;
  36.   //FIXME finishing up the stream isn't done too gracefully
  37.   if (bytes_read < 4){  // check to see if end of file
  38.     done = TRUE;
  39.     file = NULL;
  40.   }
  41.   return bytes_read;
  42. }
  43. // Fetches 1-32 bits from the file opened in bitstream_open
  44. int AC3_Bitstream::GetBitSequence(uint_32 num_bits)
  45. {
  46.   uint_32 result;
  47.   uint_32 bits_read;
  48.   uint_32 bits_to_go;
  49.   if(num_bits == 0)
  50.     return 0;
  51.   bits_read = num_bits > bits_left ? bits_left : num_bits; 
  52.   result = current_word  >> (32 - bits_read);
  53.   current_word <<= bits_read;
  54.   bits_left -= bits_read;
  55.   
  56.   if(bits_left == 0){
  57.     long loaded = Load();
  58.   }
  59.   if (bits_read < num_bits) {
  60.     bits_to_go = num_bits - bits_read;
  61.     result <<= bits_to_go;
  62.     result |= current_word  >> (32 - bits_to_go);
  63.     current_word <<= bits_to_go;
  64.     bits_left -= bits_to_go;
  65.   }
  66.   total_bits_read += num_bits;
  67.   // crc_process(result,num_bits);
  68.   return result;
  69. }
  70. // Positions the stream pointer to a sync word
  71. int AC3_Bitstream::Resync() {
  72.   int i = 0;
  73.   uint_16 sync_word;
  74.   if (!file) return -1;
  75.   sync_word = GetBitSequence(16);
  76.   /* Make sure we sync'ed */
  77.   while(1) {
  78.     if(sync_word == 0x0b77)
  79.       break;
  80.     sync_word = ( sync_word << 1 );
  81.     sync_word |= GetBitSequence(1);
  82.     i++;
  83.     if (i > 32) {  // fix added to handle EOF or closed files 
  84.                    // printf( "EOF %dn", ftell( bs->file ) );
  85.       if ( ftell(file)==-1 || feof(file) ) {
  86. i = -1;
  87. break;
  88.       }
  89.     }
  90.   }
  91.   total_bits_read = 16;
  92.   // crc_init();
  93.   return i; /* return # bits skipped */
  94. }
  95. ///////////////////////////
  96. const uint_16 nfchans[] = {2,1,2,3,3,4,4,5};
  97. struct frmsize_s
  98. {
  99.   uint_16 bit_rate;
  100.   uint_16 frm_size[3];
  101. };
  102. const struct frmsize_s frmsizecod_tbl[] = {
  103.       { 32  ,{64   ,69   ,96   } },
  104.       { 32  ,{64   ,70   ,96   } },
  105.       { 40  ,{80   ,87   ,120  } },
  106.       { 40  ,{80   ,88   ,120  } },
  107.       { 48  ,{96   ,104  ,144  } },
  108.       { 48  ,{96   ,105  ,144  } },
  109.       { 56  ,{112  ,121  ,168  } },
  110.       { 56  ,{112  ,122  ,168  } },
  111.       { 64  ,{128  ,139  ,192  } },
  112.       { 64  ,{128  ,140  ,192  } },
  113.       { 80  ,{160  ,174  ,240  } },
  114.       { 80  ,{160  ,175  ,240  } },
  115.       { 96  ,{192  ,208  ,288  } },
  116.       { 96  ,{192  ,209  ,288  } },
  117.       { 112 ,{224  ,243  ,336  } },
  118.       { 112 ,{224  ,244  ,336  } },
  119.       { 128 ,{256  ,278  ,384  } },
  120.       { 128 ,{256  ,279  ,384  } },
  121.       { 160 ,{320  ,348  ,480  } },
  122.       { 160 ,{320  ,349  ,480  } },
  123.       { 192 ,{384  ,417  ,576  } },
  124.       { 192 ,{384  ,418  ,576  } },
  125.       { 224 ,{448  ,487  ,672  } },
  126.       { 224 ,{448  ,488  ,672  } },
  127.       { 256 ,{512  ,557  ,768  } },
  128.       { 256 ,{512  ,558  ,768  } },
  129.       { 320 ,{640  ,696  ,960  } },
  130.       { 320 ,{640  ,697  ,960  } },
  131.       { 384 ,{768  ,835  ,1152 } },
  132.       { 384 ,{768  ,836  ,1152 } },
  133.       { 448 ,{896  ,975  ,1344 } },
  134.       { 448 ,{896  ,976  ,1344 } },
  135.       { 512 ,{1024 ,1114 ,1536 } },
  136.       { 512 ,{1024 ,1115 ,1536 } },
  137.       { 576 ,{1152 ,1253 ,1728 } },
  138.       { 576 ,{1152 ,1254 ,1728 } },
  139.       { 640 ,{1280 ,1393 ,1920 } },
  140.       { 640 ,{1280 ,1394 ,1920 } }
  141. };
  142. AC3FileSrc::AC3FileSrc(FILE *ac3File) 
  143. {
  144.   // set the file ptr
  145.   m_ac3File = ac3File;
  146. }
  147. AC3FileSrc::~AC3FileSrc() 
  148. {
  149.   // nothing
  150. }
  151. BOOL AC3FileSrc::Parse(LPWAVEFORMATEX fmt)
  152. {
  153.   if (m_ac3File==NULL) {
  154.     return FALSE;
  155.   }
  156.   // create a bitstream
  157.   m_ac3Bitstream = new AC3_Bitstream(m_ac3File);
  158.   // sync to the start of an AC3 frame
  159.   if (m_ac3Bitstream->Resync() < 0) {
  160.     // unable to resync - clean up and return
  161.     delete m_ac3Bitstream;
  162.     return FALSE;
  163.   }
  164.   // create sync info structure
  165.   m_sync_info = new AC3_SYNCINFO();
  166.   // and parse the sync_info
  167.   ParseSyncInfo();
  168.   // create the BSI
  169.   m_bsi = new AC3_BSI();
  170.   ParseBSI();
  171.   fmt->wFormatTag = WAVE_FORMAT_DOLBY_AC3;
  172.   fmt->nChannels  = m_bsi->nfchans;
  173.   switch (m_sync_info->fscod) {
  174.   case 2:
  175.     fmt->nSamplesPerSec = 32000;
  176.     break;
  177.   case 1:
  178.     fmt->nSamplesPerSec = 44100;
  179.     break;
  180.   case 0:
  181.     fmt->nSamplesPerSec = 48000;
  182.     break;
  183.   default:
  184.     fmt->nSamplesPerSec = 0;
  185.     break;
  186.   }
  187.   fmt->nAvgBytesPerSec = (1000 * m_sync_info->bit_rate) / 8;
  188.   fmt->nBlockAlign = 1;
  189.   fmt->wBitsPerSample = 0;
  190.   fmt->cbSize = sizeof(WAVEFORMATEX);
  191.   delete m_bsi;
  192.   delete m_sync_info;
  193.   delete m_ac3Bitstream;
  194.   return TRUE;
  195. }
  196. // Parse a syncinfo structure, minus the sync word
  197. void AC3FileSrc::ParseSyncInfo()
  198. {
  199.   /* Get crc1 - we don't actually use this data though */
  200.   m_ac3Bitstream->GetBitSequence(16);
  201.   
  202.   /* Get the sampling rate */
  203.   m_sync_info->fscod  = m_ac3Bitstream->GetBitSequence(2);
  204.   
  205.   /* Get the frame size code */
  206.   m_sync_info->frmsizecod = m_ac3Bitstream->GetBitSequence(6);
  207.   
  208.   m_sync_info->bit_rate = frmsizecod_tbl[m_sync_info->frmsizecod].bit_rate;
  209.   m_sync_info->frame_size = frmsizecod_tbl[m_sync_info->frmsizecod].frm_size[m_sync_info->fscod];
  210.   // stats_printf_syncinfo(syncinfo);
  211. }
  212. void AC3FileSrc::ParseBSI()
  213. {
  214.   uint_32 i;
  215.   /* Check the AC-3 version number */
  216.   m_bsi->bsid = m_ac3Bitstream->GetBitSequence(5);
  217.   /* Get the audio service provided by the steram */
  218.   m_bsi->bsmod = m_ac3Bitstream->GetBitSequence(3);
  219.   /* Get the audio coding mode (ie how many channels)*/
  220.   m_bsi->acmod = m_ac3Bitstream->GetBitSequence(3);
  221.   /* Predecode the number of full bandwidth channels as we use this
  222.    * number a lot */
  223.   m_bsi->nfchans = nfchans[m_bsi->acmod];
  224.   /* If it is in use, get the centre channel mix level */
  225.   if ((m_bsi->acmod & 0x1) && (m_bsi->acmod != 0x1))
  226.     m_bsi->cmixlev = m_ac3Bitstream->GetBitSequence(2);
  227.   /* If it is in use, get the surround channel mix level */
  228.   if (m_bsi->acmod & 0x4)
  229.     m_bsi->surmixlev = m_ac3Bitstream->GetBitSequence(2);
  230.   /* Get the dolby surround mode if in 2/0 mode */
  231.   if(m_bsi->acmod == 0x2)
  232.     m_bsi->dsurmod= m_ac3Bitstream->GetBitSequence(2);
  233.   /* Is the low frequency effects channel on? */
  234.   m_bsi->lfeon = m_ac3Bitstream->GetBitSequence(1);
  235.   /* Get the dialogue normalization level */
  236.   m_bsi->dialnorm = m_ac3Bitstream->GetBitSequence(5);
  237.   /* Does compression gain exist? */
  238.   m_bsi->compre = m_ac3Bitstream->GetBitSequence(1);
  239.   if (m_bsi->compre) {
  240.     /* Get compression gain */
  241.     m_bsi->compr = m_ac3Bitstream->GetBitSequence(8);
  242.   }
  243.   /* Does language code exist? */
  244.   m_bsi->langcode = m_ac3Bitstream->GetBitSequence(1);
  245.   if (m_bsi->langcode) {
  246.     /* Get langauge code */
  247.     m_bsi->langcod = m_ac3Bitstream->GetBitSequence(8);
  248.   }
  249.   /* Does audio production info exist? */
  250.   m_bsi->audprodie = m_ac3Bitstream->GetBitSequence(1);
  251.   if (m_bsi->audprodie) {
  252.     /* Get mix level */
  253.     m_bsi->mixlevel = m_ac3Bitstream->GetBitSequence(5);
  254.     
  255.     /* Get room type */
  256.     m_bsi->roomtyp = m_ac3Bitstream->GetBitSequence(2);
  257.   }
  258.   /* If we're in dual mono mode then get some extra info */
  259.   if (m_bsi->acmod ==0) {
  260.     /* Get the dialogue normalization level two */
  261.     m_bsi->dialnorm2 = m_ac3Bitstream->GetBitSequence(5);
  262.     /* Does compression gain two exist? */
  263.     m_bsi->compr2e = m_ac3Bitstream->GetBitSequence(1);
  264.     if (m_bsi->compr2e) {
  265.       /* Get compression gain two */
  266.       m_bsi->compr2 = m_ac3Bitstream->GetBitSequence(8);
  267.     }
  268.     /* Does language code two exist? */
  269.     m_bsi->langcod2e = m_ac3Bitstream->GetBitSequence(1);
  270.     if (m_bsi->langcod2e) {
  271.       /* Get langauge code two */
  272.       m_bsi->langcod2 = m_ac3Bitstream->GetBitSequence(8);
  273.     }
  274.     /* Does audio production info two exist? */
  275.     m_bsi->audprodi2e = m_ac3Bitstream->GetBitSequence(1);
  276.     if (m_bsi->audprodi2e) {
  277.       /* Get mix level two */
  278.       m_bsi->mixlevel2 = m_ac3Bitstream->GetBitSequence(5);
  279.       /* Get room type two */
  280.       m_bsi->roomtyp2 = m_ac3Bitstream->GetBitSequence(2);
  281.     }
  282.   }
  283.   /* Get the copyright bit */
  284.   m_bsi->copyrightb = m_ac3Bitstream->GetBitSequence(1);
  285.   /* Get the original bit */
  286.   m_bsi->origbs = m_ac3Bitstream->GetBitSequence(1);
  287.   /* Does timecode one exist? */
  288.   m_bsi->timecod1e = m_ac3Bitstream->GetBitSequence(1);
  289.   if(m_bsi->timecod1e) {
  290.     m_bsi->timecod1 = m_ac3Bitstream->GetBitSequence(14);
  291.   }
  292.   /* Does timecode two exist? */
  293.   m_bsi->timecod2e = m_ac3Bitstream->GetBitSequence(1);
  294.   if(m_bsi->timecod2e) {
  295.     m_bsi->timecod2 = m_ac3Bitstream->GetBitSequence(14);
  296.   }
  297.   /* Does addition info exist? */
  298.   m_bsi->addbsie = m_ac3Bitstream->GetBitSequence(1);
  299.   if(m_bsi->addbsie) {
  300.     /* Get how much info is there */
  301.     m_bsi->addbsil = m_ac3Bitstream->GetBitSequence(6);
  302.     
  303.     /* Get the additional info */
  304.     for(i=0;i<(m_bsi->addbsil + 1);i++)
  305.       m_bsi->addbsi[i] = m_ac3Bitstream->GetBitSequence(8);
  306.   }
  307.   // stats_printf_bsi(bsi);
  308. }