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

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 
00009   class MyFLACDecoder : public FLAC::Decoder::SeekableStream {
00010   public:
00011     MyFLACDecoder(FLACInputStream* stream) {
00012       m_stream = stream;
00013     }
00014 
00015     File* getFile() {
00016       return m_stream->m_file.get();
00017     }
00018 
00019     FLAC__SeekableStreamDecoderReadStatus read_callback(
00020       FLAC__byte buffer[],
00021       unsigned *bytes)
00022     {
00023       *bytes = getFile()->read(buffer, *bytes);
00024       if (*bytes == 0) {
00025         return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_ERROR;
00026       } else {
00027         return FLAC__SEEKABLE_STREAM_DECODER_READ_STATUS_OK;
00028       }
00029     }
00030 
00031     FLAC__SeekableStreamDecoderSeekStatus seek_callback(
00032       FLAC__uint64 absolute_byte_offset)
00033     {
00034       if (getFile()->seek(absolute_byte_offset, File::BEGIN)) {
00035         return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_OK;
00036       } else {
00037         return FLAC__SEEKABLE_STREAM_DECODER_SEEK_STATUS_ERROR;
00038       }
00039     }
00040 
00041     FLAC__SeekableStreamDecoderTellStatus tell_callback(
00042       FLAC__uint64* absolute_byte_offset)
00043     {
00044       *absolute_byte_offset = getFile()->tell();
00045       return FLAC__SEEKABLE_STREAM_DECODER_TELL_STATUS_OK;
00046     }
00047 
00048     FLAC__SeekableStreamDecoderLengthStatus length_callback(
00049       FLAC__uint64* stream_length)
00050     {
00051       *stream_length = GetFileLength(getFile());
00052       return FLAC__SEEKABLE_STREAM_DECODER_LENGTH_STATUS_OK;
00053     }
00054 
00055     bool eof_callback() {
00056       return (getFile()->tell() == GetFileLength(getFile()));
00057     }
00058 
00059     FLAC__StreamDecoderWriteStatus write_callback(
00060       const FLAC__Frame* frame,
00061       const FLAC__int32* const buffer[])
00062     {
00063       return m_stream->write(frame, buffer);
00064     }
00065 
00066     void metadata_callback(const FLAC__StreamMetadata *metadata) {
00067       if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
00068         m_stream->m_length = metadata->data.stream_info.total_samples;
00069       }
00070     }
00071 
00072     void error_callback(FLAC__StreamDecoderErrorStatus status) {
00073       // don't handle any errors
00074     }
00075 
00076   private:
00077     FLACInputStream* m_stream;
00078   };
00079 
00080 
00081 
00082 
00083   FLACInputStream::FLACInputStream() {
00084     m_decoder = 0;
00085 
00086     m_channel_count = 0;
00087     m_sample_rate   = 0;
00088     m_sample_format = SF_S16;
00089 
00090     m_length = 0;
00091     m_position = 0;
00092   }
00093 
00094 
00095   FLACInputStream::~FLACInputStream() {
00096     delete m_decoder;
00097   }
00098 
00099 
00100   bool
00101   FLACInputStream::initialize(File* file) {
00102     m_file = file;
00103 
00104     // initialize the decoder
00105     m_decoder = new MyFLACDecoder(this);
00106     int status = m_decoder->init();
00107     if (status != FLAC__SEEKABLE_STREAM_DECODER_OK) {
00108       delete m_decoder;
00109       m_decoder = 0;
00110       m_file = 0;
00111       return false;
00112     }
00113 
00114     // process one frame so we can do something!
00115     if (!m_decoder->process_until_end_of_metadata()) {
00116       delete m_decoder;
00117       m_decoder = 0;
00118       m_file = 0;
00119       return false;
00120     }
00121 
00122     // process one frame so we can do something!
00123     if (!m_decoder->process_single()) {
00124       delete m_decoder;
00125       m_decoder = 0;
00126       m_file = 0;
00127       return false;
00128     }
00129 
00130     // get info about the flac file
00131     m_channel_count = m_decoder->get_channels();
00132     m_sample_rate   = m_decoder->get_sample_rate();
00133     int bps         = m_decoder->get_bits_per_sample();
00134     if (bps == 16) {
00135       m_sample_format = SF_S16;
00136     } else {
00137       m_sample_format = SF_U8;
00138     }
00139 
00140     return true;
00141   }
00142 
00143 
00144   void
00145   FLACInputStream::getFormat(
00146     int& channel_count,
00147     int& sample_rate,
00148     SampleFormat& sample_format)
00149   {
00150     channel_count = m_channel_count;
00151     sample_rate   = m_sample_rate;
00152     sample_format = m_sample_format;
00153   }
00154 
00155 
00156   int
00157   FLACInputStream::read(int frame_count, void* samples) {
00158     const int frame_size = m_channel_count * GetSampleSize(m_sample_format);
00159     u8* out = (u8*)samples;
00160     
00161     // we keep reading till we finish topping up!
00162     int frames_read = 0;
00163     while (frames_read < frame_count) {
00164       
00165       // if the buffer is empty, ask FLAC to fill it p
00166       if (m_buffer.getSize() < frame_size) {
00167         if (!m_decoder->process_single()) {
00168           return frames_read;
00169         }
00170 
00171         // if the buffer still has a size of 0, we are probably at the
00172         // end of the stream
00173         if (m_buffer.getSize() < frame_size) {
00174           return frames_read;
00175         }
00176       }
00177 
00178       // read what we've got!
00179       const int to_read = std::min(
00180         frame_count - frames_read,
00181         m_buffer.getSize() / frame_size);
00182       m_buffer.read(out, to_read * frame_size);
00183       out += to_read * frame_size;
00184       frames_read += to_read;
00185     }
00186 
00187     return frames_read;
00188   }
00189 
00190 
00191   void
00192   FLACInputStream::reset() {
00193     m_file->seek(0, File::BEGIN);
00194     m_decoder->seek_absolute(0);
00195     m_position = 0;
00196     m_buffer.clear();
00197   }
00198 
00199 
00200   bool
00201   FLACInputStream::isSeekable() {
00202     return (m_length != 0);
00203   }
00204 
00205 
00206   int
00207   FLACInputStream::getLength() {
00208     return m_length;
00209   }
00210 
00211 
00212   void
00213   FLACInputStream::setPosition(int position) {
00214     if (m_decoder->seek_absolute(position)) {
00215       m_position = position;
00216     }
00217   }
00218 
00219 
00220   int
00221   FLACInputStream::getPosition() {
00222     int bytes_per_frame = m_channel_count * GetSampleSize(m_sample_format);
00223     return m_position - (m_buffer.getSize() / bytes_per_frame);
00224   }
00225 
00226 
00227   FLAC__StreamDecoderWriteStatus
00228   FLACInputStream::write(
00229     const FLAC__Frame* frame,
00230     const FLAC__int32* const buffer[])
00231   {
00232     int channel_count = frame->header.channels;
00233     int samples_per_channel = frame->header.blocksize;
00234     int bytes_per_sample = frame->header.bits_per_sample / 8;
00235     int total_size = channel_count * samples_per_channel * bytes_per_sample;
00236 
00237     m_multiplexer.ensureSize(total_size);
00238 
00239     // do the multiplexing/interleaving
00240     if (bytes_per_sample == 1) {
00241       u8* out = (u8*)m_multiplexer.get();
00242       for (int s = 0; s < samples_per_channel; ++s) {
00243         for (int c = 0; c < channel_count; ++c) {
00244           // is this right?
00245           *out++ = (u8)buffer[c][s];
00246         }
00247       }
00248     } else if (bytes_per_sample == 2) {
00249       s16* out = (s16*)m_multiplexer.get();
00250       for (int s = 0; s < samples_per_channel; ++s) {
00251         for (int c = 0; c < channel_count; ++c) {
00252           *out++ = (s16)buffer[c][s];
00253         }
00254       }
00255     } else {
00256       return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
00257     }
00258 
00259     m_buffer.write(m_multiplexer.get(), total_size);
00260     m_position += samples_per_channel;
00261     return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
00262   }
00263 
00264 }

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