00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <string.h>
00011 #include "input_mp3.h"
00012 #include "utility.h"
00013 #include "debug.h"
00014
00015
00016
00017
00018
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* ) {
00033 return true;
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
00125 m_decoder->initialize("");
00126
00127
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
00158 if (m_buffer.getSize() < frame_size) {
00159 if (!m_decoder->run(FRAME_COUNT)) {
00160
00161 return frames_read;
00162 }
00163
00164
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
00199 m_decoder->initialize("");
00200
00201
00202 if (!m_decoder->run(FRAME_COUNT)) {
00203 return;
00204 }
00205 }
00206
00207
00208 bool
00209 MP3InputStream::initialize(char* ) {
00210
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 }