1/* libFLAC++ - Free Lossless Audio Codec library 2 * Copyright (C) 2002,2003,2004,2005,2006,2007 Josh Coalson 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * - Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * - Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * - Neither the name of the Xiph.org Foundation nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR 23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 27 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 28 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32#include "FLAC++/decoder.h" 33#include "FLAC/assert.h" 34 35#ifdef _MSC_VER 36// warning C4800: 'int' : forcing to bool 'true' or 'false' (performance warning) 37#pragma warning ( disable : 4800 ) 38#endif 39 40namespace FLAC { 41 namespace Decoder { 42 43 // ------------------------------------------------------------ 44 // 45 // Stream 46 // 47 // ------------------------------------------------------------ 48 49 Stream::Stream(): 50 decoder_(::FLAC__stream_decoder_new()) 51 { } 52 53 Stream::~Stream() 54 { 55 if(0 != decoder_) { 56 (void)::FLAC__stream_decoder_finish(decoder_); 57 ::FLAC__stream_decoder_delete(decoder_); 58 } 59 } 60 61 bool Stream::is_valid() const 62 { 63 return 0 != decoder_; 64 } 65 66 bool Stream::set_ogg_serial_number(long value) 67 { 68 FLAC__ASSERT(is_valid()); 69 return (bool)::FLAC__stream_decoder_set_ogg_serial_number(decoder_, value); 70 } 71 72 bool Stream::set_md5_checking(bool value) 73 { 74 FLAC__ASSERT(is_valid()); 75 return (bool)::FLAC__stream_decoder_set_md5_checking(decoder_, value); 76 } 77 78 bool Stream::set_metadata_respond(::FLAC__MetadataType type) 79 { 80 FLAC__ASSERT(is_valid()); 81 return (bool)::FLAC__stream_decoder_set_metadata_respond(decoder_, type); 82 } 83 84 bool Stream::set_metadata_respond_application(const FLAC__byte id[4]) 85 { 86 FLAC__ASSERT(is_valid()); 87 return (bool)::FLAC__stream_decoder_set_metadata_respond_application(decoder_, id); 88 } 89 90 bool Stream::set_metadata_respond_all() 91 { 92 FLAC__ASSERT(is_valid()); 93 return (bool)::FLAC__stream_decoder_set_metadata_respond_all(decoder_); 94 } 95 96 bool Stream::set_metadata_ignore(::FLAC__MetadataType type) 97 { 98 FLAC__ASSERT(is_valid()); 99 return (bool)::FLAC__stream_decoder_set_metadata_ignore(decoder_, type); 100 } 101 102 bool Stream::set_metadata_ignore_application(const FLAC__byte id[4]) 103 { 104 FLAC__ASSERT(is_valid()); 105 return (bool)::FLAC__stream_decoder_set_metadata_ignore_application(decoder_, id); 106 } 107 108 bool Stream::set_metadata_ignore_all() 109 { 110 FLAC__ASSERT(is_valid()); 111 return (bool)::FLAC__stream_decoder_set_metadata_ignore_all(decoder_); 112 } 113 114 Stream::State Stream::get_state() const 115 { 116 FLAC__ASSERT(is_valid()); 117 return State(::FLAC__stream_decoder_get_state(decoder_)); 118 } 119 120 bool Stream::get_md5_checking() const 121 { 122 FLAC__ASSERT(is_valid()); 123 return (bool)::FLAC__stream_decoder_get_md5_checking(decoder_); 124 } 125 126 FLAC__uint64 Stream::get_total_samples() const 127 { 128 FLAC__ASSERT(is_valid()); 129 return ::FLAC__stream_decoder_get_total_samples(decoder_); 130 } 131 132 unsigned Stream::get_channels() const 133 { 134 FLAC__ASSERT(is_valid()); 135 return ::FLAC__stream_decoder_get_channels(decoder_); 136 } 137 138 ::FLAC__ChannelAssignment Stream::get_channel_assignment() const 139 { 140 FLAC__ASSERT(is_valid()); 141 return ::FLAC__stream_decoder_get_channel_assignment(decoder_); 142 } 143 144 unsigned Stream::get_bits_per_sample() const 145 { 146 FLAC__ASSERT(is_valid()); 147 return ::FLAC__stream_decoder_get_bits_per_sample(decoder_); 148 } 149 150 unsigned Stream::get_sample_rate() const 151 { 152 FLAC__ASSERT(is_valid()); 153 return ::FLAC__stream_decoder_get_sample_rate(decoder_); 154 } 155 156 unsigned Stream::get_blocksize() const 157 { 158 FLAC__ASSERT(is_valid()); 159 return ::FLAC__stream_decoder_get_blocksize(decoder_); 160 } 161 162 bool Stream::get_decode_position(FLAC__uint64 *position) const 163 { 164 FLAC__ASSERT(is_valid()); 165 return ::FLAC__stream_decoder_get_decode_position(decoder_, position); 166 } 167 168 ::FLAC__StreamDecoderInitStatus Stream::init() 169 { 170 FLAC__ASSERT(is_valid()); 171 return ::FLAC__stream_decoder_init_stream(decoder_, read_callback_, seek_callback_, tell_callback_, length_callback_, eof_callback_, write_callback_, metadata_callback_, error_callback_, /*client_data=*/(void*)this); 172 } 173 174 ::FLAC__StreamDecoderInitStatus Stream::init_ogg() 175 { 176 FLAC__ASSERT(is_valid()); 177 return ::FLAC__stream_decoder_init_ogg_stream(decoder_, read_callback_, seek_callback_, tell_callback_, length_callback_, eof_callback_, write_callback_, metadata_callback_, error_callback_, /*client_data=*/(void*)this); 178 } 179 180 bool Stream::finish() 181 { 182 FLAC__ASSERT(is_valid()); 183 return (bool)::FLAC__stream_decoder_finish(decoder_); 184 } 185 186 bool Stream::flush() 187 { 188 FLAC__ASSERT(is_valid()); 189 return (bool)::FLAC__stream_decoder_flush(decoder_); 190 } 191 192 bool Stream::reset() 193 { 194 FLAC__ASSERT(is_valid()); 195 return (bool)::FLAC__stream_decoder_reset(decoder_); 196 } 197 198 bool Stream::process_single() 199 { 200 FLAC__ASSERT(is_valid()); 201 return (bool)::FLAC__stream_decoder_process_single(decoder_); 202 } 203 204 bool Stream::process_until_end_of_metadata() 205 { 206 FLAC__ASSERT(is_valid()); 207 return (bool)::FLAC__stream_decoder_process_until_end_of_metadata(decoder_); 208 } 209 210 bool Stream::process_until_end_of_stream() 211 { 212 FLAC__ASSERT(is_valid()); 213 return (bool)::FLAC__stream_decoder_process_until_end_of_stream(decoder_); 214 } 215 216 bool Stream::skip_single_frame() 217 { 218 FLAC__ASSERT(is_valid()); 219 return (bool)::FLAC__stream_decoder_skip_single_frame(decoder_); 220 } 221 222 bool Stream::seek_absolute(FLAC__uint64 sample) 223 { 224 FLAC__ASSERT(is_valid()); 225 return (bool)::FLAC__stream_decoder_seek_absolute(decoder_, sample); 226 } 227 228 ::FLAC__StreamDecoderSeekStatus Stream::seek_callback(FLAC__uint64 absolute_byte_offset) 229 { 230 (void)absolute_byte_offset; 231 return ::FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED; 232 } 233 234 ::FLAC__StreamDecoderTellStatus Stream::tell_callback(FLAC__uint64 *absolute_byte_offset) 235 { 236 (void)absolute_byte_offset; 237 return ::FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED; 238 } 239 240 ::FLAC__StreamDecoderLengthStatus Stream::length_callback(FLAC__uint64 *stream_length) 241 { 242 (void)stream_length; 243 return ::FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED; 244 } 245 246 bool Stream::eof_callback() 247 { 248 return false; 249 } 250 251 void Stream::metadata_callback(const ::FLAC__StreamMetadata *metadata) 252 { 253 (void)metadata; 254 } 255 256 ::FLAC__StreamDecoderReadStatus Stream::read_callback_(const ::FLAC__StreamDecoder *decoder, FLAC__byte buffer[], size_t *bytes, void *client_data) 257 { 258 (void)decoder; 259 FLAC__ASSERT(0 != client_data); 260 Stream *instance = reinterpret_cast<Stream *>(client_data); 261 FLAC__ASSERT(0 != instance); 262 return instance->read_callback(buffer, bytes); 263 } 264 265 ::FLAC__StreamDecoderSeekStatus Stream::seek_callback_(const ::FLAC__StreamDecoder *decoder, FLAC__uint64 absolute_byte_offset, void *client_data) 266 { 267 (void) decoder; 268 FLAC__ASSERT(0 != client_data); 269 Stream *instance = reinterpret_cast<Stream *>(client_data); 270 FLAC__ASSERT(0 != instance); 271 return instance->seek_callback(absolute_byte_offset); 272 } 273 274 ::FLAC__StreamDecoderTellStatus Stream::tell_callback_(const ::FLAC__StreamDecoder *decoder, FLAC__uint64 *absolute_byte_offset, void *client_data) 275 { 276 (void) decoder; 277 FLAC__ASSERT(0 != client_data); 278 Stream *instance = reinterpret_cast<Stream *>(client_data); 279 FLAC__ASSERT(0 != instance); 280 return instance->tell_callback(absolute_byte_offset); 281 } 282 283 ::FLAC__StreamDecoderLengthStatus Stream::length_callback_(const ::FLAC__StreamDecoder *decoder, FLAC__uint64 *stream_length, void *client_data) 284 { 285 (void) decoder; 286 FLAC__ASSERT(0 != client_data); 287 Stream *instance = reinterpret_cast<Stream *>(client_data); 288 FLAC__ASSERT(0 != instance); 289 return instance->length_callback(stream_length); 290 } 291 292 FLAC__bool Stream::eof_callback_(const ::FLAC__StreamDecoder *decoder, void *client_data) 293 { 294 (void) decoder; 295 FLAC__ASSERT(0 != client_data); 296 Stream *instance = reinterpret_cast<Stream *>(client_data); 297 FLAC__ASSERT(0 != instance); 298 return instance->eof_callback(); 299 } 300 301 ::FLAC__StreamDecoderWriteStatus Stream::write_callback_(const ::FLAC__StreamDecoder *decoder, const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[], void *client_data) 302 { 303 (void)decoder; 304 FLAC__ASSERT(0 != client_data); 305 Stream *instance = reinterpret_cast<Stream *>(client_data); 306 FLAC__ASSERT(0 != instance); 307 return instance->write_callback(frame, buffer); 308 } 309 310 void Stream::metadata_callback_(const ::FLAC__StreamDecoder *decoder, const ::FLAC__StreamMetadata *metadata, void *client_data) 311 { 312 (void)decoder; 313 FLAC__ASSERT(0 != client_data); 314 Stream *instance = reinterpret_cast<Stream *>(client_data); 315 FLAC__ASSERT(0 != instance); 316 instance->metadata_callback(metadata); 317 } 318 319 void Stream::error_callback_(const ::FLAC__StreamDecoder *decoder, ::FLAC__StreamDecoderErrorStatus status, void *client_data) 320 { 321 (void)decoder; 322 FLAC__ASSERT(0 != client_data); 323 Stream *instance = reinterpret_cast<Stream *>(client_data); 324 FLAC__ASSERT(0 != instance); 325 instance->error_callback(status); 326 } 327 328 // ------------------------------------------------------------ 329 // 330 // File 331 // 332 // ------------------------------------------------------------ 333 334 File::File(): 335 Stream() 336 { } 337 338 File::~File() 339 { 340 } 341 342 ::FLAC__StreamDecoderInitStatus File::init(FILE *file) 343 { 344 FLAC__ASSERT(0 != decoder_); 345 return ::FLAC__stream_decoder_init_FILE(decoder_, file, write_callback_, metadata_callback_, error_callback_, /*client_data=*/(void*)this); 346 } 347 348 ::FLAC__StreamDecoderInitStatus File::init(const char *filename) 349 { 350 FLAC__ASSERT(0 != decoder_); 351 return ::FLAC__stream_decoder_init_file(decoder_, filename, write_callback_, metadata_callback_, error_callback_, /*client_data=*/(void*)this); 352 } 353 354 ::FLAC__StreamDecoderInitStatus File::init(const std::string &filename) 355 { 356 return init(filename.c_str()); 357 } 358 359 ::FLAC__StreamDecoderInitStatus File::init_ogg(FILE *file) 360 { 361 FLAC__ASSERT(0 != decoder_); 362 return ::FLAC__stream_decoder_init_ogg_FILE(decoder_, file, write_callback_, metadata_callback_, error_callback_, /*client_data=*/(void*)this); 363 } 364 365 ::FLAC__StreamDecoderInitStatus File::init_ogg(const char *filename) 366 { 367 FLAC__ASSERT(0 != decoder_); 368 return ::FLAC__stream_decoder_init_ogg_file(decoder_, filename, write_callback_, metadata_callback_, error_callback_, /*client_data=*/(void*)this); 369 } 370 371 ::FLAC__StreamDecoderInitStatus File::init_ogg(const std::string &filename) 372 { 373 return init_ogg(filename.c_str()); 374 } 375 376 // This is a dummy to satisfy the pure virtual from Stream; the 377 // read callback will never be called since we are initializing 378 // with FLAC__stream_decoder_init_FILE() or 379 // FLAC__stream_decoder_init_file() and those supply the read 380 // callback internally. 381 ::FLAC__StreamDecoderReadStatus File::read_callback(FLAC__byte buffer[], size_t *bytes) 382 { 383 (void)buffer, (void)bytes; 384 FLAC__ASSERT(false); 385 return ::FLAC__STREAM_DECODER_READ_STATUS_ABORT; // double protection 386 } 387 388 } 389} 390