MPEGaudio.cpp
资源名称:NETVIDEO.rar [点击查看]
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:8k
源码类别:
流媒体/Mpeg4/MP4
开发平台:
Visual C++
- /*
- SMPEG - SDL MPEG Player Library
- Copyright (C) 1999 Loki Entertainment Software
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
- You should have received a copy of the GNU Library General Public
- License along with this library; if not, write to the Free
- Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
- /* A class based on the MPEG stream class, used to parse and play audio */
- #include "MPEGaudio.h"
- /*
- * The below is commented out in favor of our interface routines
- */
- #if 0
- #include "MPEGstream.h"
- MPEGaudio:: MPEGaudio(MPEGstream *stream, bool initSDL) : sdl_audio(initSDL)
- {
- /* Initialize MPEG audio */
- mpeg = stream;
- initialize();
- /* Just be paranoid. If all goes well, this will be set to true */
- valid_stream = false;
- /* Analyze the MPEG audio stream */
- if ( loadheader() ) {
- SDL_AudioSpec wanted;
- WantedSpec(&wanted);
- /* Calculate the samples per frame */
- samplesperframe = 32*wanted.channels;
- if( layer == 3 ) {
- samplesperframe *= 18;
- if ( version == 0 ) {
- samplesperframe *= 2;
- }
- } else {
- samplesperframe *= SCALEBLOCK;
- if ( layer == 2 ) {
- samplesperframe *= 3;
- }
- }
- if ( sdl_audio ) {
- /* Open the audio, get actual audio hardware format and convert */
- bool audio_active;
- SDL_AudioSpec actual;
- audio_active = (SDL_OpenAudio(&wanted, &actual) == 0);
- if ( audio_active ) {
- ActualSpec(&actual);
- valid_stream = true;
- } else {
- SetError(SDL_GetError());
- }
- SDL_PauseAudio(0);
- } else { /* The stream is always valid if we don't initialize SDL */
- valid_stream = true;
- }
- Volume(100);
- }
- /* For using system timestamp */
- for (int i=0; i<N_TIMESTAMPS; i++)
- timestamp[i] = -1;
- }
- MPEGaudio:: ~MPEGaudio()
- {
- #ifdef THREADED_AUDIO
- /* Stop the decode thread */
- StopDecoding();
- #endif
- /* Remove ourselves from the mixer hooks */
- Stop();
- if ( sdl_audio ) {
- /* Close up the audio so others may play */
- SDL_CloseAudio();
- }
- }
- bool
- MPEGaudio:: WantedSpec(SDL_AudioSpec *wanted)
- {
- wanted->freq = frequencies[version][frequency];
- #if SDL_BYTEORDER == SDL_LIL_ENDIAN
- wanted->format = AUDIO_S16LSB;
- #else
- wanted->format = AUDIO_S16MSB;
- #endif
- if ( outputstereo ) {
- wanted->channels = 2;
- } else {
- wanted->channels = 1;
- }
- wanted->samples = 4096;
- wanted->callback = Play_MPEGaudio;
- wanted->userdata = this;
- return true;
- }
- void
- MPEGaudio:: ActualSpec(const SDL_AudioSpec *actual)
- {
- /* Splay can optimize some of the conversion */
- if ( actual->channels == 1 && outputstereo ) {
- forcetomonoflag = true;
- }
- if ( actual->channels == 2 && !outputstereo ) {
- forcetostereoflag = true;
- samplesperframe *= 2;
- }
- /* FIXME: Create an audio conversion block */
- if ( (actual->freq/100) == ((frequencies[version][frequency]/2)/100) ) {
- downfrequency = 1;
- } else if ( actual->freq != frequencies[version][frequency] ) {
- #ifdef VERBOSE_WARNINGS
- fprintf(stderr, "Warning: wrong audio frequency (wanted %d, got %d)n",
- frequencies[version][frequency], actual->freq);
- #else
- ;
- #endif
- }
- #if SDL_BYTEORDER == SDL_LIL_ENDIAN
- if ( actual->format != AUDIO_S16LSB)
- #else
- if ( actual->format != AUDIO_S16MSB)
- #endif
- {
- fprintf(stderr, "Warning: incorrect audio formatn");
- }
- rate_in_s=((double)((actual->format&0xFF)/8)*actual->channels*actual->freq);
- stereo=((actual->channels-1) > 0);
- }
- #ifdef THREADED_AUDIO
- void
- MPEGaudio:: StartDecoding(void)
- {
- decoding = true;
- /* Create the ring buffer to hold audio */
- if ( ! ring ) {
- ring = new MPEG_ring(samplesperframe*2);
- }
- if ( ! decode_thread ) {
- decode_thread = SDL_CreateThread(Decode_MPEGaudio, this);
- }
- }
- void
- MPEGaudio:: StopDecoding(void)
- {
- decoding = false;
- if ( decode_thread ) {
- if( ring ) ring->ReleaseThreads();
- SDL_WaitThread(decode_thread, NULL);
- decode_thread = NULL;
- }
- if ( ring ) {
- delete ring;
- ring = NULL;
- }
- }
- #endif
- /* MPEG actions */
- double
- MPEGaudio:: Time(void)
- {
- double now;
- if ( frag_time ) {
- now = (play_time + (double)(SDL_GetTicks() - frag_time)/1000.0);
- } else {
- now = play_time;
- }
- return now;
- }
- void
- MPEGaudio:: Play(void)
- {
- ResetPause();
- if ( valid_stream ) {
- #ifdef THREADED_AUDIO
- StartDecoding();
- #endif
- playing = true;
- }
- }
- void
- MPEGaudio:: Stop(void)
- {
- if ( valid_stream ) {
- SDL_LockAudio();
- playing = false;
- SDL_UnlockAudio();
- }
- ResetPause();
- }
- void
- MPEGaudio:: Rewind(void)
- {
- Stop();
- #ifdef THREADED_AUDIO
- /* Stop the decode thread */
- StopDecoding();
- #endif
- clearrawdata();
- decodedframe = 0;
- currentframe = 0;
- frags_playing = 0;
- }
- void
- MPEGaudio:: ResetSynchro(double time)
- {
- play_time = time;
- frag_time = 0;
- /* Reinit the timestamp FIFO */
- for (int i=0; i<N_TIMESTAMPS; i++)
- timestamp[i] = -1;
- }
- void
- MPEGaudio:: Skip(float seconds)
- {
- /* Called only when there is no timestamp info in the MPEG */
- printf("Audio: Skipping %f seconds...n", seconds);
- while(seconds > 0)
- {
- seconds -= (float) samplesperframe / ((float) frequencies[version][frequency]*(1+inputstereo));
- if(!loadheader()) break;
- }
- }
- void
- MPEGaudio:: Volume(int vol)
- {
- if ( (vol >= 0) && (vol <= 100) ) {
- volume = (vol*SDL_MIX_MAXVOLUME)/100;
- }
- }
- MPEGstatus
- MPEGaudio:: Status(void)
- {
- if ( valid_stream ) {
- /* Has decoding stopped because of end of stream? */
- if ( mpeg->eof() && (decodedframe <= currentframe) ) {
- return(MPEG_STOPPED);
- }
- /* Have we been told to play? */
- if ( playing ) {
- return(MPEG_PLAYING);
- } else {
- return(MPEG_STOPPED);
- }
- } else {
- return(MPEG_ERROR);
- }
- }
- bool
- MPEGaudio:: GetAudioInfo(MPEG_AudioInfo *info)
- {
- if ( info ) {
- info->mpegversion = version;
- info->mode = mode;
- info->frequency = frequencies[version][frequency];
- info->layer = layer;
- info->bitrate = bitrate[version][layer-1][bitrateindex];
- info->current_frame = currentframe;
- }
- return true;
- }
- bool
- MPEGaudio:: fillbuffer(int size)
- {
- bitindex=0;
- _buffer_pos = mpeg->pos;
- return(mpeg->copy_data(_buffer, size) > 0);
- };
- #endif
- void
- MPEGaudio:: sync(void)
- {
- bitindex=(bitindex+7)&0xFFFFFFF8;
- }
- bool
- MPEGaudio:: issync(void)
- {
- return (bitindex&7) != 0;
- }
- int
- MPEGaudio::getbyte(void)
- {
- int r=(unsigned char)_buffer[bitindex>>3];
- bitindex+=8;
- return r;
- }
- int
- MPEGaudio::getbit(void)
- {
- register int r=(_buffer[bitindex>>3]>>(7-(bitindex&7)))&1;
- bitindex++;
- return r;
- }
- int
- MPEGaudio::getbits8(void)
- {
- register unsigned short a;
- { int offset=bitindex>>3;
- a=(((unsigned char)_buffer[offset])<<8) | ((unsigned char)_buffer[offset+1]);
- }
- a<<=(bitindex&7);
- bitindex+=8;
- return (int)((unsigned int)(a>>8));
- }
- int
- MPEGaudio::getbits9(int bits)
- {
- register unsigned short a;
- { int offset=bitindex>>3;
- a=(((unsigned char)_buffer[offset])<<8) | ((unsigned char)_buffer[offset+1]);
- }
- a<<=(bitindex&7);
- bitindex+=bits;
- return (int)((unsigned int)(a>>(16-bits)));
- }