input_flac.cpp

Go to the documentation of this file.
00001 #include "input_flac.h"
00002 #include "types.h"
00003 #include "utility.h"
00004 
00005 
00006 namespace audiere {
00007 
00008   FLACInputStream::FLACInputStream() {
00009     m_decoder = 0;
00010 
00011     m_channel_count = 0;
00012     m_sample_rate   = 0;
00013     m_sample_format = SF_S16;
00014 
00015     m_length = 0;
00016     m_position = 0;
00017   }
00018 
00019 
00020   FLACInputStream::~FLACInputStream() {
00021     if (m_decoder) {
00022       FLAC__seekable_stream_decoder_finish(m_decoder);
00023       FLAC__seekable_stream_decoder_delete(m_decoder);
00024       m_decoder = 0;
00025     }
00026   }
00027 
00028 
00029   bool
00030   FLACInputStream::initialize(FilePtr file) {
00031     m_file = file;
00032 
00033     // initialize the decoder
00034     m_decoder = FLAC__seekable_stream_decoder_new();
00035     if (!m_decoder) {
00036       m_file = 0;
00037       return false;
00038     }
00039 
00040 #define SET_CALLBACK(name)                                   \
00041   FLAC__seekable_stream_decoder_set_##name##_callback(       \
00042     m_decoder,                                               \
00043     name##_callback)
00044 
00045     // set callbacks
00046     FLAC__seekable_stream_decoder_set_client_data      (m_decoder, this);
00047     SET_CALLBACK(read);
00048     SET_CALLBACK(seek);
00049     SET_CALLBACK(tell);
00050     SET_CALLBACK(length);
00051     SET_CALLBACK(eof);
00052     SET_CALLBACK(write);
00053     SET_CALLBACK(metadata);
00054     SET_CALLBACK(error);
00055 
00056     FLAC__SeekableStreamDecoderState state =
00057       FLAC__seekable_stream_decoder_init(m_decoder);
00058     if (state != FLAC__SEEKABLE_STREAM_DECODER_OK) {
00059       FLAC__seekable_stream_decoder_finish(m_decoder);
00060       FLAC__seekable_stream_decoder_delete(m_decoder);
00061       m_decoder = 0;
00062       m_file = 0;
00063       return false;
00064     }
00065 
00066     // make sure we have metadata before we return!
00067     if (!FLAC__seekable_stream_decoder_process_until_end_of_metadata(m_decoder)) {
00068       FLAC__seekable_stream_decoder_finish(m_decoder);
00069       FLAC__seekable_stream_decoder_delete(m_decoder);
00070       m_decoder = 0;
00071       m_file = 0;
00072       return false;
00073     }
00074 
00075     // process one frame so we can do something!
00076     if (!FLAC__seekable_stream_decoder_process_single(m_decoder)) {
00077       FLAC__seekable_stream_decoder_finish(m_decoder);
00078       FLAC__seekable_stream_decoder_delete(m_decoder);
00079       m_decoder = 0;
00080       m_file = 0;
00081       return false;
00082     }
00083 
00084     // get info about the flac file
00085     m_channel_count = FLAC__seekable_stream_decoder_get_channels(m_decoder);
00086     m_sample_rate   = FLAC__seekable_stream_decoder_get_sample_rate(m_decoder);
00087     int bps         = FLAC__seekable_stream_decoder_get_bits_per_sample(m_decoder);
00088     if (bps == 16) {
00089       m_sample_format = SF_S16;
00090     } else if (bps == 8) {
00091       m_sample_format = SF_U8;
00092     } else {
00093       return false;
00094     }
00095 
00096     return true;
00097   }
00098 
00099 
00100   void
00101   FLACInputStream::getFormat(
00102     int& channel_count,
00103     int& sample_rate,
00104     SampleFormat& sample_format)
00105   {
00106     channel_count = m_channel_count;
00107     sample_rate   = m_sample_rate;
00108     sample_format = m_sample_format;
00109   }
00110 
00111 
00112   int
00113   FLACInputStream::doRead(int frame_count, void* samples) {
00114     const int frame_size = m_channel_count * GetSampleSize(m_sample_format);
00115     u8* out = (u8*)samples;
00116     
00117     // we keep reading till we finish topping up!
00118     int frames_read = 0;
00119     while (frames_read < frame_count) {
00120       
00121       // if the buffer is empty, ask FLAC to fill it p
00122       if (m_buffer.getSize() < frame_size) {
00123         if (!FLAC__seekable_stream_decoder_process_single(m_decoder)) {
00124           return frames_read;
00125         }
00126 
00127         // if the buffer still has a size of 0, we are probably at the
00128         // end of the stream
00129         if (m_buffer.getSize() < frame_size) {
00130           return frames_read;
00131         }
00132       }
00133 
00134       // read what we've got!
00135       const int to_read = std::min(
00136         frame_count - frames_read,
00137         m_buffer.getSize() / frame_size);
00138       m_buffer.read(out, to_read * frame_size);
00139       out += to_read * frame_size;
00140       frames_read += to_read;
00141     }
00142 
00143     return frames_read;
00144   }
00145 
00146 
00147   void
00148   FLACInputStream::reset() {
00149     m_file->seek(0, File::BEGIN);
00150     FLAC__seekable_stream_decoder_seek_absolute(m_decoder, 0);
00151     m_position = 0;
00152     m_buffer.clear();
00153   }
00154 
00155 
00156   bool
00157   FLACInputStream::isSeekable() {
00158     return (m_length != 0);
00159   }
00160 
00161 
00162   int
00163   FLACInputStream::getLength() {
00164     return m_length;
00165   }
00166 
00167 
00168   void
00169   FLACInputStream::setPosition(int position) {
00170     if (FLAC__seekable_stream_decoder_seek_absolute(m_decoder, position)) {
00171       m_position = position;
00172     }
00173   }
00174 
00175 
00176   int
00177   FLACInputStream::getPosition() {
00178     int bytes_per_frame = m_channel_count * GetSampleSize(m_sample_format);
00179     return m_position - (m_buffer.getSize() / bytes_per_frame);
00180   }
00181 
00182 
00183   FLAC__StreamDecoderWriteStatus
00184   FLACInputStream::write(
00185     const FLAC__Frame* frame,
00186     const FLAC__int32* const buffer[])
00187   {
00188     int channel_count = frame->header.channels;
00189     int samples_per_channel = frame->header.blocksize;
00190     int bytes_per_sample = frame->header.bits_per_sample / 8;
00191     int total_size = channel_count * samples_per_channel * bytes_per_sample;
00192 
00193     m_multiplexer.ensureSize(total_size);
00194 
00195     // do the multiplexing/interleaving
00196     if (bytes_per_sample == 1) {
00197       u8* out = (u8*)m_multiplexer.get();
00198       for (int s = 0; s < samples_per_channel; ++s) {
00199         for (int c = 0; c < channel_count; ++c) {
00200           // is this right?
00201           *out++ = (u8)buffer[c][s];
00202         }
00203       }
00204     } else if (bytes_per_sample == 2) {
00205       s16* out = (s16*)m_multiplexer.get();
00206       for (int s = 0; s < samples_per_channel; ++s) {
00207         for (int c = 0; c < channel_count; ++c) {
00208           *out++ = (s16)buffer[c][s];
00209         }
00210       }
00211     } else {
00212       return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
00213     }
00214 
00215     m_buffer.write(m_multiplexer.get(), total_size);
00216     m_position += samples_per_channel;
00217     return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
00218   }
00219 
00220 
00221   FLAC__SeekableStreamDecoderReadStatus FLACInputStream::read_callback(
00222     const FLAC__SeekableStreamDecoder* decoder,
00223     FLAC__byte buffer[],
00224     unsigned *bytes,
00225     void* client_data)
00226   {
00227     *bytes = getFile(client_data)->read(buffer, *bytes);
00228     if (*bytes == 0) {
00229       return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
00230     } else {
00231       return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
00232     }
00233   }
00234 
00235 
00236   FLAC__SeekableStreamDecoderSeekStatus FLACInputStream::seek_callback(
00237     const FLAC__SeekableStreamDecoder* decoder,
00238     FLAC__uint64 absolute_byte_offset,
00239     void* client_data)
00240   {
00241     if (getFile(client_data)->seek(static_cast<int>(absolute_byte_offset), File::BEGIN)) {
00242       return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
00243     } else {
00244       return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
00245     }
00246   }
00247 
00248 
00249   FLAC__SeekableStreamDecoderTellStatus FLACInputStream::tell_callback(
00250     const FLAC__SeekableStreamDecoder* decoder,
00251     FLAC__uint64* absolute_byte_offset,
00252     void* client_data)
00253   {
00254     *absolute_byte_offset = getFile(client_data)->tell();
00255     return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
00256   }
00257 
00258 
00259   FLAC__SeekableStreamDecoderLengthStatus FLACInputStream::length_callback(
00260     const FLAC__SeekableStreamDecoder* decoder,
00261     FLAC__uint64* stream_length,
00262     void* client_data)
00263   {
00264     *stream_length = GetFileLength(getFile(client_data));
00265     return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
00266   }
00267 
00268 
00269   FLAC__bool FLACInputStream::eof_callback(
00270     const FLAC__SeekableStreamDecoder* decoder,
00271     void* client_data)
00272   {
00273     File* file = getFile(client_data);
00274     return (file->tell() == GetFileLength(file));
00275   }
00276 
00277 
00278   FLAC__StreamDecoderWriteStatus FLACInputStream::write_callback(
00279     const FLAC__SeekableStreamDecoder* decoder,
00280     const FLAC__Frame* frame,
00281     const FLAC__int32* const buffer[],
00282     void* client_data)
00283   {
00284     return getStream(client_data)->write(frame, buffer);
00285   }
00286 
00287 
00288   void FLACInputStream::metadata_callback(
00289     const FLAC__SeekableStreamDecoder* decoder,
00290     const FLAC__StreamMetadata *metadata,
00291     void* client_data)
00292   {
00293     if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
00294       FLAC__uint64 length = metadata->data.stream_info.total_samples;
00295       getStream(client_data)->m_length = static_cast<int>(length);
00296     }
00297   }
00298 
00299 
00300   void FLACInputStream::error_callback(
00301     const FLAC__SeekableStreamDecoder* decoder,
00302     FLAC__StreamDecoderErrorStatus status,
00303     void* client_data)
00304   {
00305     // don't handle any errors
00306   }
00307 
00308 
00309   FLACInputStream* FLACInputStream::getStream(void* client_data) {
00310     return static_cast<FLACInputStream*>(client_data);
00311   }
00312 
00313   File* FLACInputStream::getFile(void* client_data) {
00314     return getStream(client_data)->m_file.get();
00315   }
00316 }

Generated on Mon Feb 13 23:07:46 2006 for audiere by  doxygen 1.4.6