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