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

多媒体编程

开发平台:

Visual C++

  1. // VirtualDub - Video processing and capture application
  2. // Copyright (C) 1998-2001 Avery Lee
  3. //
  4. // This program is free software; you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation; either version 2 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // This program is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. // GNU General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU General Public License
  15. // along with this program; if not, write to the Free Software
  16. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <windows.h>
  20. #include <vfw.h>
  21. #include "AudioSource.h"
  22. #include "AVIReadHandler.h"
  23. #include "AC3FileSrc.h"
  24. AudioSourceWAV::AudioSourceWAV(char *szFile, LONG inputBufferSize) {
  25. MMIOINFO mmi;
  26. memset(&mmi,0,sizeof mmi);
  27. mmi.cchBuffer = inputBufferSize;
  28. hmmioFile = mmioOpen(szFile, &mmi, MMIO_READ | MMIO_ALLOCBUF);
  29. }
  30. AudioSourceWAV::~AudioSourceWAV() {
  31. mmioClose(hmmioFile, 0);
  32. }
  33. BOOL AudioSourceWAV::init() {
  34. if (!hmmioFile) return FALSE;
  35. chunkRIFF.fccType = mmioFOURCC('W','A','V','E');
  36. if (MMSYSERR_NOERROR != mmioDescend(hmmioFile, &chunkRIFF, NULL, MMIO_FINDRIFF))
  37. return FALSE;
  38. chunkDATA.ckid = mmioFOURCC('f','m','t',' ');
  39. if (MMSYSERR_NOERROR != mmioDescend(hmmioFile, &chunkDATA, &chunkRIFF, MMIO_FINDCHUNK))
  40. return FALSE;
  41. if (!allocFormat(chunkDATA.cksize)) return FALSE;
  42. if (chunkDATA.cksize != mmioRead(hmmioFile, (char *)getWaveFormat(), chunkDATA.cksize))
  43. return FALSE;
  44. if (MMSYSERR_NOERROR != mmioAscend(hmmioFile, &chunkDATA, 0))
  45. return FALSE;
  46. chunkDATA.ckid = mmioFOURCC('d','a','t','a');
  47. if (MMSYSERR_NOERROR != mmioDescend(hmmioFile, &chunkDATA, &chunkRIFF, MMIO_FINDCHUNK))
  48. return FALSE;
  49. bytesPerSample = getWaveFormat()->nBlockAlign; //getWaveFormat()->nAvgBytesPerSec / getWaveFormat()->nSamplesPerSec;
  50. lSampleFirst = 0;
  51. lSampleLast = chunkDATA.cksize / bytesPerSample;
  52. lCurrentSample = 0;
  53. streamInfo.fccType = streamtypeAUDIO;
  54. streamInfo.fccHandler = 0;
  55. streamInfo.dwFlags = 0;
  56. streamInfo.wPriority = 0;
  57. streamInfo.wLanguage = 0;
  58. streamInfo.dwInitialFrames = 0;
  59. streamInfo.dwScale = bytesPerSample;
  60. streamInfo.dwRate = getWaveFormat()->nAvgBytesPerSec;
  61. streamInfo.dwStart = 0;
  62. streamInfo.dwLength = chunkDATA.cksize / bytesPerSample;
  63. streamInfo.dwSuggestedBufferSize = 0;
  64. streamInfo.dwQuality = 0xffffffff;
  65. streamInfo.dwSampleSize = bytesPerSample;
  66. return TRUE;
  67. }
  68. int AudioSourceWAV::_read(LONG lStart, LONG lCount, LPVOID buffer, LONG cbBuffer, LONG *lBytesRead, LONG *lSamplesRead) {
  69. LONG lBytes = lCount * bytesPerSample;
  70. if (buffer) {
  71. if (lStart != lCurrentSample)
  72. if (-1 == mmioSeek(hmmioFile, chunkDATA.dwDataOffset + bytesPerSample*lStart, SEEK_SET))
  73. return AVIERR_FILEREAD;
  74. if (lBytes != mmioRead(hmmioFile, (char *)buffer, lBytes))
  75. return AVIERR_FILEREAD;
  76. lCurrentSample = lStart + lCount;
  77. }
  78. *lSamplesRead = lCount;
  79. *lBytesRead = lBytes;
  80. return AVIERR_OK;
  81. }
  82. ///////////////////////////
  83. AudioSourceAVI::AudioSourceAVI(IAVIReadHandler *pAVI) {
  84. pAVIFile = pAVI;
  85. pAVIStream = NULL;
  86. }
  87. AudioSourceAVI::~AudioSourceAVI() {
  88. if (pAVIStream)
  89. delete pAVIStream;
  90. }
  91. BOOL AudioSourceAVI::init() {
  92. LONG format_len;
  93. pAVIStream = pAVIFile->GetStream(streamtypeAUDIO, 0);
  94. if (!pAVIStream) return FALSE;
  95. if (pAVIStream->Info(&streamInfo, sizeof streamInfo))
  96. return FALSE;
  97. pAVIStream->FormatSize(0, &format_len);
  98. if (!allocFormat(format_len)) return FALSE;
  99. if (pAVIStream->ReadFormat(0, getFormat(), &format_len))
  100. return FALSE;
  101. lSampleFirst = pAVIStream->Start();
  102. lSampleLast = pAVIStream->End();
  103. return TRUE;
  104. }
  105. void AudioSourceAVI::Reinit() {
  106. pAVIStream->Info(&streamInfo, sizeof streamInfo);
  107. lSampleFirst = pAVIStream->Start();
  108. lSampleLast = pAVIStream->End();
  109. }
  110. bool AudioSourceAVI::isStreaming() {
  111. return pAVIStream->isStreaming();
  112. }
  113. void AudioSourceAVI::streamBegin(bool fRealTime) {
  114. pAVIStream->BeginStreaming(lSampleFirst, lSampleLast, fRealTime ? 1000 : 2000);
  115. }
  116. void AudioSourceAVI::streamEnd() {
  117. pAVIStream->EndStreaming();
  118. }
  119. BOOL AudioSourceAVI::_isKey(LONG lSample) {
  120. return pAVIStream->IsKeyFrame(lSample);
  121. }
  122. int AudioSourceAVI::_read(LONG lStart, LONG lCount, LPVOID lpBuffer, LONG cbBuffer, LONG *lpBytesRead, LONG *lpSamplesRead) {
  123. int err;
  124. long lBytes, lSamples;
  125. // There are some video clips roaming around with truncated audio streams
  126. // (audio streams that state their length as being longer than they
  127. // really are).  We use a kludge here to get around the problem.
  128. err = pAVIStream->Read(lStart, lCount, lpBuffer, cbBuffer, lpBytesRead, lpSamplesRead);
  129. if (err != AVIERR_FILEREAD)
  130. return err;
  131. // Suspect a truncated stream.
  132. //
  133. // AVISTREAMREAD_CONVENIENT will tell us if we're actually encountering a
  134. // true read error or not.  At least for the AVI handler, it returns
  135. // AVIERR_ERROR if we've broached the end.  
  136. *lpBytesRead = *lpSamplesRead = 0;
  137. while(lCount > 0) {
  138. err = pAVIStream->Read(lStart, AVISTREAMREAD_CONVENIENT, NULL, 0, &lBytes, &lSamples);
  139. if (err)
  140. return 0;
  141. if (!lSamples) return AVIERR_OK;
  142. if (lSamples > lCount) lSamples = lCount;
  143. err = pAVIStream->Read(lStart, lSamples, lpBuffer, cbBuffer, &lBytes, &lSamples);
  144. if (err)
  145. return err;
  146. lpBuffer = (LPVOID)((char *)lpBuffer + lBytes);
  147. cbBuffer -= lBytes;
  148. lCount -= lSamples;
  149. *lpBytesRead += lBytes;
  150. *lpSamplesRead += lSamples;
  151. }
  152. return AVIERR_OK;
  153. }
  154. ///////////////////////////////////////////////////////////////////////////////////////////////////
  155. // Dummy CRC pointer
  156. Crc16 *crc;
  157. AudioSourceMP3::AudioSourceMP3(char *szFile) {
  158. stream = new Ibitstream(szFile);
  159. header = new Header;
  160. f = fopen( szFile, "rb" );
  161. }
  162. AudioSourceMP3::~AudioSourceMP3() {
  163. if( f ) fclose( f );
  164. delete header;
  165. delete stream;
  166. }
  167. BOOL AudioSourceMP3::init() {
  168. if( !f ) return FALSE;
  169. if (!header->read_header(stream, &crc)){
  170. return FALSE;
  171. }
  172. do {
  173. } while( header->read_header(stream, &crc) );
  174. real s_len = (stream->current_frame()+1)*header->ms_per_frame()/1000;
  175. if (!allocFormat(sizeof MPEGLAYER3WAVEFORMAT)) return FALSE;
  176. MPEGLAYER3WAVEFORMAT *mp3format = (MPEGLAYER3WAVEFORMAT *)getWaveFormat();
  177. mp3format->wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3; /* format type */
  178.     mp3format->wfx.nChannels = (header->mode() == single_channel) ? 1 : 2; /* number of channels (i.e. mono, stereo...) */
  179.     mp3format->wfx.nSamplesPerSec = header->frequency(); /* sample rate */
  180.     mp3format->wfx.nAvgBytesPerSec = stream->file_size()/s_len; /* for buffer estimation */
  181.     mp3format->wfx.nBlockAlign = 1152; /* block size of data */
  182.     mp3format->wfx.wBitsPerSample = 0; /* Number of bits per sample of mono data */
  183. mp3format->wfx.cbSize = 12; /* The count in bytes of the size of
  184. extra information (after cbSize) */
  185. mp3format->wID = 1;
  186. mp3format->fdwFlags = 2;
  187. mp3format->nBlockSize = stream->file_size()/(stream->current_frame()+1);
  188. mp3format->nFramesPerBlock = 1;
  189. mp3format->nCodecDelay = 0;
  190. lSampleFirst = 0;
  191. lSampleLast = stream->current_frame()+1;
  192. streamInfo.fccType = streamtypeAUDIO;
  193. streamInfo.fccHandler = 0;
  194. streamInfo.dwFlags = 0;
  195. streamInfo.wPriority = 0;
  196. streamInfo.wLanguage = 0;
  197. streamInfo.dwInitialFrames = 0;
  198. streamInfo.dwScale = 1152;
  199. streamInfo.dwRate = header->frequency();
  200. streamInfo.dwStart = 0;
  201. streamInfo.dwLength = lSampleLast;
  202. streamInfo.dwSuggestedBufferSize = 0;
  203. streamInfo.dwQuality = 0xffffffff;
  204. streamInfo.dwSampleSize = 0;
  205. delete header;
  206. header = new Header;
  207. stream->reset();
  208. pos = 0;
  209. header->read_header(stream, &crc);
  210. return TRUE;
  211. }
  212. int AudioSourceMP3::_read(LONG lStart, LONG lCount, LPVOID buffer, LONG cbBuffer, LONG *lBytesRead, LONG *lSamplesRead)
  213. {
  214. *lSamplesRead = 0;
  215. *lBytesRead = 0;
  216. if( buffer )
  217. {
  218. if (lStart != stream->current_frame())
  219. {
  220. delete header;
  221. header = new Header;
  222. stream->reset();
  223. while( stream->current_frame() != lStart )
  224. {
  225. pos = stream->file_pos();
  226. header->read_header(stream, &crc);
  227. }
  228. }
  229. uint32 frame_size = stream->file_pos() - pos;
  230. if( frame_size>cbBuffer ) return AVIERR_OK;
  231. fseek( f, pos, SEEK_SET );
  232. fread( buffer, frame_size, 1, f );
  233. cbBuffer -= frame_size;
  234. buffer = (void *)(((unsigned long)buffer)+frame_size);
  235. (*lBytesRead) += frame_size;
  236. pos = stream->file_pos();
  237. header->read_header(stream, &crc);
  238. (*lSamplesRead) = 1;
  239. }
  240.     
  241. return AVIERR_OK;
  242. }
  243. ///////////////////////////////////////////////////////////////////////////////////////////////////
  244. AudioSourceOggVorbis::AudioSourceOggVorbis(char *szFile) {
  245. f = fopen( szFile, "rb" );
  246. pos = 0;
  247. }
  248. AudioSourceOggVorbis::~AudioSourceOggVorbis() {
  249. if( f ) fclose( f );
  250. }
  251. #ifndef _WAVEFORMATEXTENSIBLE_
  252. #define _WAVEFORMATEXTENSIBLE_
  253. #pragma pack(1)
  254. typedef struct {
  255.     WAVEFORMATEX    Format;
  256.     union {
  257.         WORD wValidBitsPerSample;       /* bits of precision  */
  258.         WORD wSamplesPerBlock;          /* valid if wBitsPerSample==0 */
  259.         WORD wReserved;                 /* If neither applies, set to zero. */
  260.     } Samples;
  261.     DWORD           dwChannelMask;      /* which channels are */
  262.                                         /* present in stream  */
  263.     GUID            SubFormat;
  264. } WAVEFORMATEXTENSIBLE, *PWAVEFORMATEXTENSIBLE;
  265. #pragma pack()
  266. #endif // !_WAVEFORMATEXTENSIBLE_
  267. BOOL AudioSourceOggVorbis::streamInit() {
  268. char *buffer;
  269. int bytes;
  270. eos = 0;
  271. while( ogg_sync_pageout( &oy, &og )!=1 ) {
  272. buffer = ogg_sync_buffer( &oy, 1 );
  273. bytes = fread( buffer, 1, 1, f );
  274. ogg_sync_wrote( &oy, bytes );
  275. }
  276. ogg_stream_init( &os, ogg_page_serialno( &og ) );
  277. vorbis_info_init( &vi );
  278. vorbis_comment_init( &vc );
  279. if( ogg_stream_pagein( &os, &og )<0 ) { 
  280. return FALSE;
  281. }
  282. if( ogg_stream_packetout( &os, &op )!=1 ) { 
  283. return FALSE;
  284. }
  285. if( vorbis_synthesis_headerin( &vi, &vc, &op )<0 ) { 
  286. return FALSE;
  287. }
  288. int i = 0;
  289. while( i<2 ) {
  290. while( i<2 ) {
  291. int result = ogg_sync_pageout( &oy, &og );
  292. if( result==0 ) break; /* Need more data */
  293. /* Don't complain about missing or corrupt data yet.  We'll
  294. catch it at the packet output phase */
  295. if( result==1 ) {
  296. ogg_stream_pagein( &os, &og ); /* we can ignore any errors here
  297. as they'll also become apparent
  298. at packetout */
  299. while( i<2 ) {
  300. result = ogg_stream_packetout( &os, &op );
  301. if( result==0 ) break;
  302. if( result<0 ) {
  303. /* Uh oh; data at some point was corrupted or missing!
  304. We can't tolerate that in a header.  Die. */
  305. return FALSE;
  306. }
  307. vorbis_synthesis_headerin( &vi, &vc, &op );
  308. i++;
  309. }
  310. }
  311. }
  312. /* no harm in not checking before adding more */
  313. buffer = ogg_sync_buffer( &oy, 1 );
  314. bytes = fread( buffer, 1, 1, f );
  315. if( bytes==0 && i<2 ) {
  316. return FALSE;
  317. }
  318. ogg_sync_wrote( &oy, bytes );
  319. }
  320. fgetpos( f, &pos );
  321. --pos;
  322. vorbis_synthesis_init( &vd, &vi );
  323. vorbis_block_init( &vd, &vb );
  324. return TRUE;
  325. }
  326. typedef unsigned __int8 uint8;
  327. //typedef unsigned __int32 uint32;
  328. typedef unsigned __int64 uint64;
  329. bool splitHeader( const uint8* Buffer, size_t BufferSize, size_t& SplitPosition, uint8** Header,size_t*HeaderSize )
  330. {
  331. // Just for your information, here's the format of an Ogg Page header:
  332. #pragma pack(1)
  333.  struct PageHeader
  334.  {
  335.  // Flag values
  336. enum
  337. {
  338. CONTINUED=1
  339. ,BOS=2
  340. ,EOS=4
  341. };
  342. char Magic[4]; // The String "OggS" in ASCII
  343. uint8 Version; // Currently 0
  344. uint8 Flags; // Enf of stream, Beginning of stream
  345. uint64 GranulePos; // Not used for header packets. This is big endian !!!
  346. uint32 Serial; // serial number of the stream used for multiplexing/chaining
  347. uint32 PageNumber; // Page number within the stream
  348. uint32 CRC; // CRC value, similar to the ZIP CRC32, but with swapped bits. For more info I can provide a small Java class.
  349. uint8 LacingCount;
  350.  };
  351. #pragma pack()
  352.  uint8*HeaderStart[3]={Header[0],Header[1],Header[2]};
  353.  const uint8*BufferStart=Buffer;
  354.  for(size_t PacketIndex=0;PacketIndex<3;)
  355.  {
  356.  // Read the next header
  357.  if(BufferSize<sizeof(PageHeader))
  358.  return false; // No data available for fixed header
  359.  // Read the fixed header
  360.  const PageHeader*CurrentPageHeader=reinterpret_cast<const PageHeader*>(Buffer);
  361.  Buffer+=sizeof(PageHeader);
  362.  BufferSize-=sizeof(PageHeader);
  363.  // Verify some fields
  364.  if(CurrentPageHeader->Magic[0]!='O'
  365.  ||CurrentPageHeader->Magic[1]!='g'
  366.  ||CurrentPageHeader->Magic[2]!='g'
  367.  ||CurrentPageHeader->Magic[3]!='S'
  368.  )
  369.  return false; // Our minimum requirement failed, see above for details
  370.  if(CurrentPageHeader->LacingCount>BufferSize)
  371.  return false; // No data available for lacing values
  372.  const uint8*CurrentLacings=Buffer;
  373.  Buffer+=CurrentPageHeader->LacingCount;
  374.  BufferSize-=CurrentPageHeader->LacingCount;
  375.  for(uint8 LacingIndex=0;PacketIndex<3&&LacingIndex<CurrentPageHeader->LacingCount;)
  376.  {
  377.  for(;PacketIndex<3&&LacingIndex<CurrentPageHeader->LacingCount;++LacingIndex)
  378.  {
  379.  if(BufferSize<CurrentLacings[LacingIndex])
  380.  return false; // No more data for the current part
  381.  // Copy the data
  382.  if(HeaderSize[PacketIndex]<CurrentLacings[LacingIndex])
  383.  return false; // No more space in output buffer
  384.  memcpy(Header[PacketIndex],Buffer,CurrentLacings[LacingIndex]);
  385.  HeaderSize[PacketIndex]-=CurrentLacings[LacingIndex];
  386.  Header[PacketIndex]+=CurrentLacings[LacingIndex];
  387.  Buffer+=CurrentLacings[LacingIndex];
  388.  if(CurrentLacings[LacingIndex]<255)
  389.  {
  390.  // Found new end of packet. If this is the last header
  391.  // packet, we must be at the page end.
  392.  if(PacketIndex==2&&LacingIndex<(CurrentPageHeader->LacingCount-1))
  393.  return false;
  394.  ++PacketIndex;
  395.  }
  396.  }
  397.  }
  398.  }
  399.  // Buffer points to the end of the last header page
  400.  SplitPosition=Buffer-BufferStart;
  401.  for(size_t i=0;i<3;++i)
  402.  {
  403. HeaderSize[i]=Header[i]-HeaderStart[i];
  404. Header[i]=HeaderStart[i];
  405.  }
  406.  return true;
  407. }
  408. BOOL AudioSourceOggVorbis::init() {
  409. if( !f ) return FALSE;
  410. char *buffer;
  411. int bytes;
  412. ogg_sync_init(&oy); /* Now we can read pages */
  413. if( streamInit()==FALSE ) return FALSE;
  414. fseek( f, 0, SEEK_SET );
  415. uint8* Buffer = (uint8*)malloc( pos );
  416. size_t Size = fread( Buffer, 1, pos, f );
  417. uint8* Header = (uint8*)malloc( pos );
  418. uint8* Comments = (uint8*)malloc( pos );
  419. uint8* Codebook = (uint8*)malloc( pos );
  420. if( Buffer==NULL || Header==NULL || Comments==NULL || Codebook==NULL ) {
  421. failed:
  422. if( Buffer ) free( Buffer );
  423. if( Header ) free( Header );
  424. if( Comments ) free( Comments );
  425. if( Codebook ) free( Codebook );
  426. return FALSE;
  427. }
  428. size_t SplitPosition;
  429. size_t PacketSizes[] = { pos, pos, pos };
  430. uint8* PacketAddresses[] = { Header, Comments, Codebook };
  431. if( splitHeader( Buffer, Size, SplitPosition, PacketAddresses, PacketSizes )==FALSE )
  432. goto failed;
  433. int s = sizeof(WAVEFORMATEXTENSIBLE)+3*sizeof(size_t)+PacketSizes[0]+PacketSizes[1]+PacketSizes[2];
  434. s = (s+7) & -8;
  435. if( !allocFormat( s ) )
  436. goto failed;
  437. // prepare WAVEFORMAT
  438. WAVEFORMATEXTENSIBLE *wfext = (WAVEFORMATEXTENSIBLE *)getWaveFormat();
  439.     wfext->Format.wFormatTag = 0xFFFE; // WAVE_FORMAT_EXTENSIBLE
  440.     wfext->Format.nChannels = vi.channels;
  441.     wfext->Format.nSamplesPerSec = vi.rate;
  442.     wfext->Format.nAvgBytesPerSec = 176400;
  443.     wfext->Format.nBlockAlign = 20000; // ahem, testing...
  444.     wfext->Format.wBitsPerSample = 0;
  445.     wfext->Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE)
  446. +3*sizeof(size_t)
  447. +PacketSizes[0]+PacketSizes[1]+PacketSizes[2]
  448. -sizeof(WAVEFORMATEX);
  449. //  wfext->Samples.wValidBitsPerSample = 0;       /* bits of precision  */
  450. //  wfext->Samples.wSamplesPerBlock = 0;          /* valid if wBitsPerSample==0 */
  451.     wfext->Samples.wReserved = 0;                 /* If neither applies, set to zero. */
  452. wfext->dwChannelMask = (1<<vi.channels)-1;
  453. // {6BA47966-3F83-4178-9665-00F0BF6292E5}
  454. // DEFINE_GUID(MEDIASUBTYPE_VorbisStream,0x6ba47966, 0x3f83, 0x4178, 0x96, 0x65, 0x0, 0xf0, 0xbf, 0x62, 0x92, 0xe5);
  455. GUID guid = { 0x6ba47966, 0x3f83, 0x4178, { 0x96, 0x65, 0x0, 0xf0, 0xbf, 0x62, 0x92, 0xe5 } };
  456. wfext->SubFormat = guid;
  457. // append the Ogg headers to the Wav header
  458. char* p = (char*)getWaveFormat()+sizeof(WAVEFORMATEXTENSIBLE);
  459. *(size_t*)p = PacketSizes[0]; p += sizeof(size_t);
  460. *(size_t*)p = PacketSizes[1]; p += sizeof(size_t);
  461. *(size_t*)p = PacketSizes[2]; p += sizeof(size_t);
  462. memcpy( p, PacketAddresses[0], PacketSizes[0] ); p += PacketSizes[0];
  463. memcpy( p, PacketAddresses[1], PacketSizes[1] ); p += PacketSizes[1];
  464. memcpy( p, PacketAddresses[2], PacketSizes[2] ); p += PacketSizes[2];
  465. // We need to know the length of the stream. Sure, there are other methods...
  466. int tot_pcm_samples = 0;
  467. // vorbis_synthesis_init( &vd, &vi );
  468. // vorbis_block_init( &vd, &vb );
  469. while( !eos ) {
  470. while( !eos ) {
  471. int result = ogg_sync_pageout( &oy, &og );
  472. if( result==0 ) break;
  473. if( result<0 ){
  474. //fprintf(stderr,"Corrupt or missing data in bitstream; continuing...n");
  475. }else{
  476. ogg_stream_pagein( &os, &og );
  477. while( TRUE ) {
  478. result = ogg_stream_packetout( &os, &op );
  479. if( result==0 ) break;
  480. if( result<0 ) {
  481. /* no reason to complain; already complained above */
  482. }else{
  483. int samples;
  484. float **pcm;
  485. if( vorbis_synthesis( &vb, &op )==0 ) /* test for success! */
  486. vorbis_synthesis_blockin( &vd, &vb );
  487. if( (samples=vorbis_synthesis_pcmout( &vd, &pcm ))>0) {
  488. tot_pcm_samples += samples;
  489. vorbis_synthesis_read( &vd, samples );
  490. }     
  491. }
  492. }
  493. if( ogg_page_eos( &og ) ) eos = 1;
  494. }
  495. }
  496. if( !eos ) {
  497. buffer = ogg_sync_buffer( &oy, 1 );
  498. bytes = fread( buffer, 1, 1, f);
  499. ogg_sync_wrote( &oy, bytes );
  500. if( bytes==0 ) eos = 1;
  501. }
  502. }
  503. ogg_stream_clear( &os );
  504. vorbis_block_clear( &vb );
  505. vorbis_dsp_clear( &vd );
  506. vorbis_comment_clear( &vc );
  507. vorbis_info_clear( &vi );
  508. // init some variables
  509. lSampleFirst = 0;
  510. lSampleLast = (tot_pcm_samples/20000)+1;
  511. pcm_samples = 0;
  512. pcm_written = 0;
  513. // reset the input
  514. fseek( f, 0, SEEK_SET );
  515. streamInit();
  516. while( pcm_samples<20000 ) {
  517. readPage();
  518. decodePage();
  519. }
  520. lCurrentSample = 0;
  521. if( Buffer ) free( Buffer );
  522. if( Header ) free( Header );
  523. if( Comments ) free( Comments );
  524. if( Codebook ) free( Codebook );
  525. // prepare StreamInfo
  526. streamInfo.fccType = streamtypeAUDIO;
  527. streamInfo.fccHandler = 0;
  528. streamInfo.dwFlags = 0;
  529. streamInfo.wPriority = 0;
  530. streamInfo.wLanguage = 0;
  531. streamInfo.dwInitialFrames = 0;
  532. streamInfo.dwScale = 20000;
  533. streamInfo.dwRate = vi.rate;
  534. streamInfo.dwStart = 0;
  535. streamInfo.dwLength = lSampleLast;
  536. streamInfo.dwSuggestedBufferSize = 0;
  537. streamInfo.dwQuality = 0xffffffff;
  538. streamInfo.dwSampleSize = 0;
  539. return TRUE;
  540. }
  541. void AudioSourceOggVorbis::readPage() 
  542. {
  543. char *buffer;
  544. int bytes;
  545. while( eos==0 && ogg_sync_pageout( &oy, &og )!=1 ) {
  546. buffer = ogg_sync_buffer( &oy, 1 );
  547. bytes = fread( buffer, 1, 1, f );
  548. ogg_sync_wrote( &oy, bytes );
  549. if( bytes==0 ) eos = 1;
  550. }
  551. }
  552. void AudioSourceOggVorbis::decodePage() 
  553. {
  554. ogg_stream_pagein( &os, &og );
  555. while( TRUE ) {
  556. int result = ogg_stream_packetout( &os, &op );
  557. if( result==0 ) break;
  558. if( result<0 ) {
  559. /* no reason to complain; already complained above */
  560. }else{
  561. int samples;
  562. float **pcm;
  563. if( vorbis_synthesis( &vb, &op )==0 ) /* test for success! */
  564. vorbis_synthesis_blockin( &vd, &vb );
  565. if( (samples=vorbis_synthesis_pcmout( &vd, &pcm ))>0) {
  566. pcm_samples += samples;
  567. vorbis_synthesis_read( &vd, samples );
  568. }     
  569. }
  570. }
  571. if( ogg_page_eos( &og ) ) eos = 1;
  572. }
  573. int AudioSourceOggVorbis::_read(LONG lStart, LONG lCount, LPVOID buffer, LONG cbBuffer, LONG *lBytesRead, LONG *lSamplesRead)
  574. {
  575. *lSamplesRead = 0;
  576. *lBytesRead = 0;
  577. if( buffer ) {
  578. if (lStart != lCurrentSample) {
  579. ogg_stream_clear( &os );
  580. vorbis_block_clear( &vb );
  581. vorbis_dsp_clear( &vd );
  582. vorbis_comment_clear( &vc );
  583. vorbis_info_clear( &vi );
  584. fseek( f, 0, SEEK_SET );
  585. streamInit();
  586. readPage();
  587. lCurrentSample = 0;
  588. while( lStart != lCurrentSample ) {
  589. fgetpos( f, &pos );
  590. readPage();
  591. lCurrentSample++;
  592. }
  593. }
  594. __int64 pos2;
  595. fgetpos( f, &pos2 );
  596. uint32 frame_size = (uint32)pos2 - pos;
  597. if( frame_size>cbBuffer ) return AVIERR_OK;
  598. fseek( f, pos, SEEK_SET );
  599. fread( buffer, frame_size, 1, f );
  600. cbBuffer -= frame_size;
  601. buffer = (void *)(((unsigned long)buffer)+frame_size);
  602. (*lBytesRead) += frame_size;
  603. pcm_samples -= 20000;
  604. pos = pos2;
  605. while( pcm_samples<20000 ) {
  606. readPage();
  607. decodePage();
  608. }
  609. lCurrentSample++;
  610. (*lSamplesRead) = 1;
  611. }
  612. return AVIERR_OK;
  613. }
  614. ///////////////////////////////////////////////////////////////////////////////////////////////////////
  615. AudioSourceAC3::AudioSourceAC3(char *szFile, LONG inputBufferSize) 
  616. {
  617. ac3File = fopen(szFile,"rb");
  618. }
  619. AudioSourceAC3::~AudioSourceAC3() 
  620. {
  621. if (ac3File!=NULL) fclose(ac3File);
  622. }
  623. BOOL AudioSourceAC3::init() 
  624. {
  625. WAVEFORMATEX *fmt, ac3WFmt;
  626. if( ac3File==NULL ) return FALSE;
  627. // extract WAVEFORMATEX from the AC3 file
  628. AC3FileSrc *ac3Src = new AC3FileSrc(ac3File);
  629. if( !ac3Src->Parse(&ac3WFmt) ) {
  630. delete ac3Src;
  631. return FALSE;
  632. }
  633. delete ac3Src;
  634. // allocate format structure
  635. if (!(fmt=(WAVEFORMATEX *) allocFormat(sizeof(WAVEFORMATEX)))) return FALSE;
  636. *fmt = ac3WFmt;
  637. {
  638. char szBuf[256];
  639. sprintf(szBuf, "FmtTag: 0x%x, SampFreq: %d, Channels: %d, bitrate: %d kb/s",
  640. fmt->wFormatTag,
  641. fmt->nSamplesPerSec,
  642. fmt->nChannels,
  643. (fmt->nAvgBytesPerSec*8)/1000);
  644. MessageBox(NULL,szBuf,"AC3 file parameters",MB_OK);
  645. }
  646. // get the length of the file
  647. fseek(ac3File,0,SEEK_END); 
  648. chunkDATA.cksize = ftell(ac3File);
  649. chunkDATA.dwDataOffset = 0;
  650. fseek(ac3File,0,SEEK_SET);
  651. bytesPerSample= getWaveFormat()->nBlockAlign; //getWaveFormat()->nAvgBytesPerSec / getWaveFormat()->nSamplesPerSec;
  652. lSampleFirst = 0;
  653. lSampleLast = chunkDATA.cksize / bytesPerSample;
  654. lCurrentSample= 0;
  655. streamInfo.fccType = streamtypeAUDIO;
  656. streamInfo.fccHandler = 0;
  657. streamInfo.dwFlags = 0;
  658. streamInfo.wPriority = 0;
  659. streamInfo.wLanguage = 0;
  660. streamInfo.dwInitialFrames = 0;
  661. streamInfo.dwScale = bytesPerSample;
  662. streamInfo.dwRate = getWaveFormat()->nAvgBytesPerSec;
  663. streamInfo.dwStart = 0;
  664. streamInfo.dwLength = chunkDATA.cksize / bytesPerSample;
  665. streamInfo.dwSuggestedBufferSize = 0;
  666. streamInfo.dwQuality = 0xffffffff;
  667. streamInfo.dwSampleSize = bytesPerSample;
  668. return TRUE;
  669. }
  670. int AudioSourceAC3::_read(LONG lStart, LONG lCount, LPVOID buffer, LONG cbBuffer, LONG *lBytesRead, LONG *lSamplesRead) 
  671. {
  672. LONG lBytes = lCount * bytesPerSample;
  673. if (lStart != lCurrentSample)
  674. if (-1 == fseek(ac3File, chunkDATA.dwDataOffset + bytesPerSample*lStart, SEEK_SET))
  675. return AVIERR_FILEREAD;
  676. if (lBytes != fread((char *)buffer, 1, lBytes, ac3File))
  677. return AVIERR_FILEREAD;
  678. *lSamplesRead = lCount;
  679. *lBytesRead = lBytes;
  680. lCurrentSample = lStart + lCount;
  681. return AVIERR_OK;
  682. }