Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

input_mp3.cpp

Go to the documentation of this file.
00001 /*
00002   THIS IS WRITTEN FOR CHAD AUSTIN FOR AUDIERE
00003   By Jacky Chong
00004 
00005   In short, this is some wierd shit I wrote up because Chad
00006   didn't want to touch this. Also, I have no idea what I've
00007   done as well to get it work as well.
00008 */
00009 
00010 #include <string.h>
00011 #include "input_mp3.h"
00012 #include "utility.h"
00013 #include "debug.h"
00014 
00015 
00016 // The number of MP3 frame that are processed at a time.  If this value
00017 // is smaller, the decoder should take less memory.  However, it may
00018 // skip on corrupt MP3s.
00019 static const int FRAME_COUNT = 10;
00020 
00021 
00022 namespace audiere {
00023 
00024 
00025   class MyLoader : public Soundinputstream {
00026   public:
00027     MyLoader(File* file) {
00028       m_file = file;
00029       m_eof = false;
00030     }
00031 
00032     bool open(char* /*filename*/) {
00033       return true; // already open!
00034     }
00035 
00036     void close() {
00037       m_file = 0;
00038     }
00039 
00040     int getbytedirect() {
00041       u8 b;
00042       if (m_file->read(&b, 1) == 1) {
00043         return b;
00044       } else {
00045         seterrorcode(SOUND_ERROR_FILEREADFAIL);
00046         m_eof = true;
00047         return -1;
00048       }
00049     }
00050 
00051     bool _readbuffer(char* buffer, int size) {
00052       if (m_file->read(buffer, size) == size) {
00053         return true;
00054       } else {
00055         seterrorcode(SOUND_ERROR_FILEREADFAIL);
00056         m_eof = true;
00057         return false;
00058       }
00059     }
00060 
00061     bool eof() {
00062       return m_eof;
00063     }
00064 
00065     int getblock(char* buffer, int size) {
00066       int read = m_file->read(buffer, size);
00067       if (read != size) {
00068         m_eof = true;
00069       }
00070       return size;
00071     }
00072 
00073     int getsize() {
00074       int pos = m_file->tell();
00075       m_file->seek(0, File::END);
00076       int size = m_file->tell();
00077       m_file->seek(pos, File::BEGIN);
00078       return size;
00079     }
00080 
00081     void setposition(int pos) {
00082       m_file->seek(pos, File::BEGIN);
00083       m_eof = false;
00084     }
00085 
00086     int getposition() {
00087       return m_file->tell();
00088     }
00089 
00090   private:
00091     RefPtr<File> m_file;
00092     bool m_eof;
00093   };
00094 
00095 
00096   MP3InputStream::MP3InputStream() {
00097     m_file = 0;
00098 
00099     m_channel_count = 2;
00100     m_sample_rate = 44100;
00101     m_sample_format = SF_S16;
00102 
00103     m_decoder = 0;
00104     m_loader = 0;
00105   }
00106 
00107   
00108   MP3InputStream::~MP3InputStream() {
00109     if (m_decoder) {
00110       delete m_decoder;
00111     }
00112     if (m_loader) {
00113       delete m_loader;
00114     }
00115   }
00116 
00117 
00118   bool
00119   MP3InputStream::initialize(File* file) {
00120     m_file = file;
00121     m_loader = new MyLoader(file);
00122     m_decoder = new Mpegtoraw(m_loader, this);
00123 
00124     // empty filename because we don't use it
00125     m_decoder->initialize("");
00126 
00127     // this should call setsoundtype with the format of the stream
00128     if (!m_decoder->run(FRAME_COUNT)) {
00129       return false;
00130     }
00131 
00132     return true;
00133   }
00134 
00135 
00136   void
00137   MP3InputStream::getFormat(
00138     int& channel_count, 
00139     int& sample_rate, 
00140     SampleFormat& sample_format) 
00141   {
00142     channel_count = m_channel_count;
00143     sample_rate = m_sample_rate;
00144     sample_format = m_sample_format;
00145   }
00146 
00147   
00148   int
00149   MP3InputStream::read(int frame_count, void* samples) {
00150     const int frame_size = m_channel_count * GetSampleSize(m_sample_format);
00151 
00152     int frames_read = 0;
00153     u8* out = (u8*)samples;
00154 
00155     while (frames_read < frame_count) {
00156 
00157       // no more samples?  ask the MP3 for more
00158       if (m_buffer.getSize() < frame_size) {
00159         if (!m_decoder->run(FRAME_COUNT)) {
00160           // done decoding?
00161           return frames_read;
00162         }
00163 
00164         // if the buffer is still empty, we are done
00165         if (m_buffer.getSize() < frame_size) {
00166           return frames_read;
00167         }
00168       }
00169 
00170       const int frames_left = frame_count - frames_read;
00171       const int frames_to_read = std::min(
00172         frames_left,
00173         m_buffer.getSize() / frame_size);
00174 
00175       m_buffer.read(out, frames_to_read * frame_size);
00176       out += frames_to_read * frame_size;
00177       frames_read += frames_to_read;
00178     }
00179 
00180     return frames_read;
00181   }
00182 
00183 
00184   void
00185   MP3InputStream::reset() {
00186     m_file->seek(0, File::BEGIN);
00187 
00188     if (m_decoder) {
00189       delete m_decoder;
00190     }
00191     if (m_loader) {
00192       delete m_loader;
00193     }
00194 
00195     m_loader = new MyLoader(m_file.get());
00196     m_decoder = new Mpegtoraw(m_loader, this);
00197 
00198     // empty filename because we don't use it
00199     m_decoder->initialize("");
00200 
00201     // this should call setsoundtype with the format of the stream
00202     if (!m_decoder->run(FRAME_COUNT)) {
00203       return;
00204     }
00205   }
00206 
00207 
00208   bool
00209   MP3InputStream::initialize(char* /*filename*/) {
00210     // nothing!
00211     return true;
00212   }
00213 
00214 
00215   bool
00216   MP3InputStream::setsoundtype(int stereo, int samplesize, int speed) {
00217     m_channel_count = (stereo ? 2 : 1);
00218     m_sample_rate = speed;
00219 
00220     if (samplesize == 8) {
00221       m_sample_format = SF_U8;
00222     } else if (samplesize == 16) {
00223       m_sample_format = SF_S16;
00224     } else {
00225       return false;
00226     }
00227 
00228     return true;
00229   }
00230 
00231 
00232   bool
00233   MP3InputStream::putblock(void* buffer, int size) {
00234     m_buffer.write(buffer, size);
00235     return true;
00236   }
00237 
00238 }

Generated on Sat Oct 12 01:43:03 2002 for audiere by doxygen1.2.17