MPEGaudio.cpp
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:8k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2.     SMPEG - SDL MPEG Player Library
  3.     Copyright (C) 1999  Loki Entertainment Software
  4.     This library is free software; you can redistribute it and/or
  5.     modify it under the terms of the GNU Library General Public
  6.     License as published by the Free Software Foundation; either
  7.     version 2 of the License, or (at your option) any later version.
  8.     This library is distributed in the hope that it will be useful,
  9.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  11.     Library General Public License for more details.
  12.     You should have received a copy of the GNU Library General Public
  13.     License along with this library; if not, write to the Free
  14.     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. */
  16. /* A class based on the MPEG stream class, used to parse and play audio */
  17. #include "MPEGaudio.h"
  18. /*
  19.  * The below is commented out in favor of our interface routines
  20.  */
  21. #if 0
  22. #include "MPEGstream.h"
  23. MPEGaudio:: MPEGaudio(MPEGstream *stream, bool initSDL) : sdl_audio(initSDL)
  24. {
  25.     /* Initialize MPEG audio */
  26.     mpeg = stream;
  27.     initialize();
  28.     /* Just be paranoid.  If all goes well, this will be set to true */
  29.     valid_stream = false;
  30.     /* Analyze the MPEG audio stream */
  31.     if ( loadheader() ) {
  32.         SDL_AudioSpec wanted;
  33.         WantedSpec(&wanted);
  34.         /* Calculate the samples per frame */
  35.         samplesperframe = 32*wanted.channels;
  36.         if( layer == 3 ) {
  37.             samplesperframe *= 18;
  38.             if ( version == 0 ) {
  39.                 samplesperframe *= 2;
  40.             }
  41.         } else {
  42.             samplesperframe *= SCALEBLOCK;
  43.             if ( layer == 2 ) {
  44.                 samplesperframe *= 3;
  45.             }
  46.         }
  47.         if ( sdl_audio ) {
  48.             /* Open the audio, get actual audio hardware format and convert */
  49.             bool audio_active;
  50.             SDL_AudioSpec actual;
  51.             audio_active = (SDL_OpenAudio(&wanted, &actual) == 0);
  52.             if ( audio_active ) {
  53.                 ActualSpec(&actual);
  54.                 valid_stream = true;
  55.             } else {
  56.                 SetError(SDL_GetError());
  57.             }
  58.             SDL_PauseAudio(0);
  59.         } else { /* The stream is always valid if we don't initialize SDL */
  60.             valid_stream = true; 
  61.         }
  62.         Volume(100);
  63.     }
  64.     /* For using system timestamp */
  65.     for (int i=0; i<N_TIMESTAMPS; i++)
  66.       timestamp[i] = -1;
  67. }
  68. MPEGaudio:: ~MPEGaudio()
  69. {
  70. #ifdef THREADED_AUDIO
  71.     /* Stop the decode thread */
  72.     StopDecoding();
  73. #endif
  74.     /* Remove ourselves from the mixer hooks */
  75.     Stop();
  76.     if ( sdl_audio ) {
  77.         /* Close up the audio so others may play */
  78.         SDL_CloseAudio();
  79.     }
  80. }
  81. bool
  82. MPEGaudio:: WantedSpec(SDL_AudioSpec *wanted)
  83. {
  84.     wanted->freq = frequencies[version][frequency];
  85. #if SDL_BYTEORDER == SDL_LIL_ENDIAN
  86.     wanted->format = AUDIO_S16LSB;
  87. #else
  88.     wanted->format = AUDIO_S16MSB;
  89. #endif
  90.     if ( outputstereo ) {
  91.         wanted->channels = 2;
  92.     } else {
  93.         wanted->channels = 1;
  94.     }
  95.     wanted->samples = 4096;
  96.     wanted->callback = Play_MPEGaudio;
  97.     wanted->userdata = this;
  98.     return true;
  99. }
  100. void
  101. MPEGaudio:: ActualSpec(const SDL_AudioSpec *actual)
  102. {
  103.     /* Splay can optimize some of the conversion */
  104.     if ( actual->channels == 1 && outputstereo ) {
  105.         forcetomonoflag = true;
  106.     }
  107.     if ( actual->channels == 2 && !outputstereo ) {
  108.         forcetostereoflag = true;
  109.         samplesperframe *= 2;
  110.     }
  111.     /* FIXME: Create an audio conversion block */
  112.     if ( (actual->freq/100) == ((frequencies[version][frequency]/2)/100) ) {
  113.         downfrequency = 1;
  114.     } else if ( actual->freq != frequencies[version][frequency] ) {
  115. #ifdef VERBOSE_WARNINGS
  116.         fprintf(stderr, "Warning: wrong audio frequency (wanted %d, got %d)n",
  117. frequencies[version][frequency], actual->freq);
  118. #else
  119. ;
  120. #endif
  121.     }
  122. #if SDL_BYTEORDER == SDL_LIL_ENDIAN
  123.     if ( actual->format != AUDIO_S16LSB)
  124. #else
  125.     if ( actual->format != AUDIO_S16MSB)
  126. #endif
  127.     {
  128.         fprintf(stderr, "Warning: incorrect audio formatn");
  129.     }
  130.     rate_in_s=((double)((actual->format&0xFF)/8)*actual->channels*actual->freq);
  131.     stereo=((actual->channels-1) > 0);
  132. }
  133. #ifdef THREADED_AUDIO
  134. void
  135. MPEGaudio:: StartDecoding(void)
  136. {
  137.     decoding = true;
  138.     /* Create the ring buffer to hold audio */
  139.     if ( ! ring ) {
  140.         ring = new MPEG_ring(samplesperframe*2);
  141.     }
  142.     if ( ! decode_thread ) {
  143.         decode_thread = SDL_CreateThread(Decode_MPEGaudio, this);
  144.     }
  145. }
  146. void
  147. MPEGaudio:: StopDecoding(void)
  148. {
  149.     decoding = false;
  150.     if ( decode_thread ) {
  151.         if( ring ) ring->ReleaseThreads();
  152.         SDL_WaitThread(decode_thread, NULL);
  153.         decode_thread = NULL;
  154.     }
  155.     if ( ring ) {
  156.         delete ring;
  157.         ring = NULL;
  158.     }
  159. }
  160. #endif
  161. /* MPEG actions */
  162. double
  163. MPEGaudio:: Time(void)
  164. {
  165.     double now;
  166.     if ( frag_time ) {
  167.         now = (play_time + (double)(SDL_GetTicks() - frag_time)/1000.0);
  168.     } else {
  169.         now = play_time;
  170.     }
  171.     return now;
  172. }
  173. void
  174. MPEGaudio:: Play(void)
  175. {
  176.     ResetPause();
  177.     if ( valid_stream ) {
  178. #ifdef THREADED_AUDIO
  179.         StartDecoding();
  180. #endif
  181.         playing = true;
  182.     }
  183. }
  184. void
  185. MPEGaudio:: Stop(void)
  186. {
  187.     if ( valid_stream ) {
  188.         SDL_LockAudio();
  189.         playing = false;
  190.         SDL_UnlockAudio();
  191.     }
  192.     ResetPause();
  193. }
  194. void
  195. MPEGaudio:: Rewind(void)
  196. {
  197.     Stop();
  198. #ifdef THREADED_AUDIO
  199.     /* Stop the decode thread */
  200.     StopDecoding();
  201. #endif
  202.     clearrawdata();
  203.     decodedframe = 0;
  204.     currentframe = 0;
  205.     frags_playing = 0;
  206. }
  207. void
  208. MPEGaudio:: ResetSynchro(double time)
  209. {
  210.     play_time = time;
  211.     frag_time = 0;
  212.     /* Reinit the timestamp FIFO */
  213.     for (int i=0; i<N_TIMESTAMPS; i++)
  214.       timestamp[i] = -1;
  215. }
  216. void
  217. MPEGaudio:: Skip(float seconds)
  218. {
  219.    /* Called only when there is no timestamp info in the MPEG */
  220.    printf("Audio: Skipping %f seconds...n", seconds);
  221.    while(seconds > 0)
  222.    {
  223.      seconds -= (float) samplesperframe / ((float) frequencies[version][frequency]*(1+inputstereo));
  224.      if(!loadheader()) break;
  225.    }
  226.  }
  227. void
  228. MPEGaudio:: Volume(int vol)
  229. {
  230.     if ( (vol >= 0) && (vol <= 100) ) {
  231.         volume = (vol*SDL_MIX_MAXVOLUME)/100;
  232.     }
  233. }
  234. MPEGstatus
  235. MPEGaudio:: Status(void)
  236. {
  237.     if ( valid_stream ) {
  238.         /* Has decoding stopped because of end of stream? */
  239.         if ( mpeg->eof() && (decodedframe <= currentframe) ) {
  240.             return(MPEG_STOPPED);
  241.         }
  242.         /* Have we been told to play? */
  243.         if ( playing ) {
  244.             return(MPEG_PLAYING);
  245.         } else {
  246.             return(MPEG_STOPPED);
  247.         }
  248.     } else {
  249.         return(MPEG_ERROR);
  250.     }
  251. }
  252. bool
  253. MPEGaudio:: GetAudioInfo(MPEG_AudioInfo *info)
  254. {
  255.     if ( info ) {
  256.       info->mpegversion = version;
  257.       info->mode = mode;
  258.       info->frequency = frequencies[version][frequency];
  259.       info->layer = layer;
  260.       info->bitrate = bitrate[version][layer-1][bitrateindex];
  261.       info->current_frame = currentframe;
  262.     }
  263.     return true;
  264. }
  265. bool
  266. MPEGaudio:: fillbuffer(int size)
  267.   {
  268.       bitindex=0;
  269.       _buffer_pos = mpeg->pos;
  270.       return(mpeg->copy_data(_buffer, size) > 0);
  271.   };
  272. #endif
  273. void
  274. MPEGaudio:: sync(void)
  275. {
  276.   bitindex=(bitindex+7)&0xFFFFFFF8;
  277. }
  278.   
  279. bool
  280. MPEGaudio:: issync(void)
  281. {
  282.   return (bitindex&7) != 0;
  283. }
  284.   
  285. int 
  286. MPEGaudio::getbyte(void) 
  287. {
  288.   int r=(unsigned char)_buffer[bitindex>>3];
  289.   bitindex+=8;
  290.   return r;
  291. }
  292.   
  293. int 
  294. MPEGaudio::getbit(void) 
  295. {
  296.   register int r=(_buffer[bitindex>>3]>>(7-(bitindex&7)))&1;
  297.   bitindex++;
  298.   return r;
  299. }
  300.   
  301. int 
  302. MPEGaudio::getbits8(void) 
  303. {
  304.   register unsigned short a;
  305.   { int offset=bitindex>>3;
  306.   a=(((unsigned char)_buffer[offset])<<8) | ((unsigned char)_buffer[offset+1]);
  307.   }
  308.   a<<=(bitindex&7);
  309.   bitindex+=8;
  310.   return (int)((unsigned int)(a>>8));
  311. }
  312.   
  313. int 
  314. MPEGaudio::getbits9(int bits) 
  315. {
  316.   register unsigned short a;
  317.   { int offset=bitindex>>3;
  318.   a=(((unsigned char)_buffer[offset])<<8) | ((unsigned char)_buffer[offset+1]);
  319.   }
  320.   a<<=(bitindex&7);
  321.   bitindex+=bits;
  322.   return (int)((unsigned int)(a>>(16-bits)));
  323. }