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
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
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
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
00123 if (!m_decoder->process_single()) {
00124 delete m_decoder;
00125 m_decoder = 0;
00126 m_file = 0;
00127 return false;
00128 }
00129
00130
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
00162 int frames_read = 0;
00163 while (frames_read < frame_count) {
00164
00165
00166 if (m_buffer.getSize() < frame_size) {
00167 if (!m_decoder->process_single()) {
00168 return frames_read;
00169 }
00170
00171
00172
00173 if (m_buffer.getSize() < frame_size) {
00174 return frames_read;
00175 }
00176 }
00177
00178
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
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
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 }