1/* test_libFLAC++ - Unit tester for libFLAC++ 2 * Copyright (C) 2002,2003,2004,2005,2006,2007 Josh Coalson 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 2 7 * of the License, or (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 */ 18 19#if HAVE_CONFIG_H 20# include <config.h> 21#endif 22 23#include <errno.h> 24#include <stdio.h> 25#include <stdlib.h> 26#include <string.h> 27#if defined _MSC_VER || defined __MINGW32__ 28#if _MSC_VER <= 1600 /* @@@ [2G limit] */ 29#define fseeko fseek 30#define ftello ftell 31#endif 32#endif 33#include "decoders.h" 34#include "FLAC/assert.h" 35#include "FLAC/metadata.h" // for ::FLAC__metadata_object_is_equal() 36#include "FLAC++/decoder.h" 37#include "share/grabbag.h" 38extern "C" { 39#include "test_libs_common/file_utils_flac.h" 40#include "test_libs_common/metadata_utils.h" 41} 42 43#ifdef _MSC_VER 44// warning C4800: 'int' : forcing to bool 'true' or 'false' (performance warning) 45#pragma warning ( disable : 4800 ) 46#endif 47 48typedef enum { 49 LAYER_STREAM = 0, /* FLAC__stream_decoder_init_stream() without seeking */ 50 LAYER_SEEKABLE_STREAM, /* FLAC__stream_decoder_init_stream() with seeking */ 51 LAYER_FILE, /* FLAC__stream_decoder_init_FILE() */ 52 LAYER_FILENAME /* FLAC__stream_decoder_init_file() */ 53} Layer; 54 55static const char * const LayerString[] = { 56 "Stream", 57 "Seekable Stream", 58 "FILE*", 59 "Filename" 60}; 61 62static ::FLAC__StreamMetadata streaminfo_, padding_, seektable_, application1_, application2_, vorbiscomment_, cuesheet_, picture_, unknown_; 63static ::FLAC__StreamMetadata *expected_metadata_sequence_[9]; 64static unsigned num_expected_; 65static off_t flacfilesize_; 66 67static const char *flacfilename(bool is_ogg) 68{ 69 return is_ogg? "metadata.oga" : "metadata.flac"; 70} 71 72static bool die_(const char *msg) 73{ 74 printf("ERROR: %s\n", msg); 75 return false; 76} 77 78static FLAC__bool die_s_(const char *msg, const FLAC::Decoder::Stream *decoder) 79{ 80 FLAC::Decoder::Stream::State state = decoder->get_state(); 81 82 if(msg) 83 printf("FAILED, %s", msg); 84 else 85 printf("FAILED"); 86 87 printf(", state = %u (%s)\n", (unsigned)((::FLAC__StreamDecoderState)state), state.as_cstring()); 88 89 return false; 90} 91 92static void init_metadata_blocks_() 93{ 94 mutils__init_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_, &picture_, &unknown_); 95} 96 97static void free_metadata_blocks_() 98{ 99 mutils__free_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_, &picture_, &unknown_); 100} 101 102static bool generate_file_(FLAC__bool is_ogg) 103{ 104 printf("\n\ngenerating %sFLAC file for decoder tests...\n", is_ogg? "Ogg ":""); 105 106 num_expected_ = 0; 107 expected_metadata_sequence_[num_expected_++] = &padding_; 108 expected_metadata_sequence_[num_expected_++] = &seektable_; 109 expected_metadata_sequence_[num_expected_++] = &application1_; 110 expected_metadata_sequence_[num_expected_++] = &application2_; 111 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; 112 expected_metadata_sequence_[num_expected_++] = &cuesheet_; 113 expected_metadata_sequence_[num_expected_++] = &picture_; 114 expected_metadata_sequence_[num_expected_++] = &unknown_; 115 /* WATCHOUT: for Ogg FLAC the encoder should move the VORBIS_COMMENT block to the front, right after STREAMINFO */ 116 117 if(!file_utils__generate_flacfile(is_ogg, flacfilename(is_ogg), &flacfilesize_, 512 * 1024, &streaminfo_, expected_metadata_sequence_, num_expected_)) 118 return die_("creating the encoded file"); 119 120 return true; 121} 122 123 124class DecoderCommon { 125public: 126 Layer layer_; 127 unsigned current_metadata_number_; 128 bool ignore_errors_; 129 bool error_occurred_; 130 131 DecoderCommon(Layer layer): layer_(layer), current_metadata_number_(0), ignore_errors_(false), error_occurred_(false) { } 132 ::FLAC__StreamDecoderWriteStatus common_write_callback_(const ::FLAC__Frame *frame); 133 void common_metadata_callback_(const ::FLAC__StreamMetadata *metadata); 134 void common_error_callback_(::FLAC__StreamDecoderErrorStatus status); 135}; 136 137::FLAC__StreamDecoderWriteStatus DecoderCommon::common_write_callback_(const ::FLAC__Frame *frame) 138{ 139 if(error_occurred_) 140 return ::FLAC__STREAM_DECODER_WRITE_STATUS_ABORT; 141 142 if( 143 (frame->header.number_type == ::FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER && frame->header.number.frame_number == 0) || 144 (frame->header.number_type == ::FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER && frame->header.number.sample_number == 0) 145 ) { 146 printf("content... "); 147 fflush(stdout); 148 } 149 150 return ::FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE; 151} 152 153void DecoderCommon::common_metadata_callback_(const ::FLAC__StreamMetadata *metadata) 154{ 155 if(error_occurred_) 156 return; 157 158 printf("%d... ", current_metadata_number_); 159 fflush(stdout); 160 161 if(current_metadata_number_ >= num_expected_) { 162 (void)die_("got more metadata blocks than expected"); 163 error_occurred_ = true; 164 } 165 else { 166 if(!::FLAC__metadata_object_is_equal(expected_metadata_sequence_[current_metadata_number_], metadata)) { 167 (void)die_("metadata block mismatch"); 168 error_occurred_ = true; 169 } 170 } 171 current_metadata_number_++; 172} 173 174void DecoderCommon::common_error_callback_(::FLAC__StreamDecoderErrorStatus status) 175{ 176 if(!ignore_errors_) { 177 printf("ERROR: got error callback: err = %u (%s)\n", (unsigned)status, ::FLAC__StreamDecoderErrorStatusString[status]); 178 error_occurred_ = true; 179 } 180} 181 182class StreamDecoder : public FLAC::Decoder::Stream, public DecoderCommon { 183public: 184 FILE *file_; 185 186 StreamDecoder(Layer layer): FLAC::Decoder::Stream(), DecoderCommon(layer), file_(0) { } 187 ~StreamDecoder() { } 188 189 // from FLAC::Decoder::Stream 190 ::FLAC__StreamDecoderReadStatus read_callback(FLAC__byte buffer[], size_t *bytes); 191 ::FLAC__StreamDecoderSeekStatus seek_callback(FLAC__uint64 absolute_byte_offset); 192 ::FLAC__StreamDecoderTellStatus tell_callback(FLAC__uint64 *absolute_byte_offset); 193 ::FLAC__StreamDecoderLengthStatus length_callback(FLAC__uint64 *stream_length); 194 bool eof_callback(); 195 ::FLAC__StreamDecoderWriteStatus write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[]); 196 void metadata_callback(const ::FLAC__StreamMetadata *metadata); 197 void error_callback(::FLAC__StreamDecoderErrorStatus status); 198 199 bool test_respond(bool is_ogg); 200}; 201 202::FLAC__StreamDecoderReadStatus StreamDecoder::read_callback(FLAC__byte buffer[], size_t *bytes) 203{ 204 const size_t requested_bytes = *bytes; 205 206 if(error_occurred_) 207 return ::FLAC__STREAM_DECODER_READ_STATUS_ABORT; 208 209 if(feof(file_)) { 210 *bytes = 0; 211 return ::FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; 212 } 213 else if(requested_bytes > 0) { 214 *bytes = ::fread(buffer, 1, requested_bytes, file_); 215 if(*bytes == 0) { 216 if(feof(file_)) 217 return ::FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM; 218 else 219 return ::FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; 220 } 221 else { 222 return ::FLAC__STREAM_DECODER_READ_STATUS_CONTINUE; 223 } 224 } 225 else 226 return ::FLAC__STREAM_DECODER_READ_STATUS_ABORT; /* abort to avoid a deadlock */ 227} 228 229::FLAC__StreamDecoderSeekStatus StreamDecoder::seek_callback(FLAC__uint64 absolute_byte_offset) 230{ 231 if(layer_ == LAYER_STREAM) 232 return ::FLAC__STREAM_DECODER_SEEK_STATUS_UNSUPPORTED; 233 234 if(error_occurred_) 235 return ::FLAC__STREAM_DECODER_SEEK_STATUS_ERROR; 236 237 if(fseeko(file_, (off_t)absolute_byte_offset, SEEK_SET) < 0) { 238 error_occurred_ = true; 239 return ::FLAC__STREAM_DECODER_SEEK_STATUS_ERROR; 240 } 241 242 return ::FLAC__STREAM_DECODER_SEEK_STATUS_OK; 243} 244 245::FLAC__StreamDecoderTellStatus StreamDecoder::tell_callback(FLAC__uint64 *absolute_byte_offset) 246{ 247 if(layer_ == LAYER_STREAM) 248 return ::FLAC__STREAM_DECODER_TELL_STATUS_UNSUPPORTED; 249 250 if(error_occurred_) 251 return ::FLAC__STREAM_DECODER_TELL_STATUS_ERROR; 252 253 off_t offset = ftello(file_); 254 *absolute_byte_offset = (FLAC__uint64)offset; 255 256 if(offset < 0) { 257 error_occurred_ = true; 258 return ::FLAC__STREAM_DECODER_TELL_STATUS_ERROR; 259 } 260 261 return ::FLAC__STREAM_DECODER_TELL_STATUS_OK; 262} 263 264::FLAC__StreamDecoderLengthStatus StreamDecoder::length_callback(FLAC__uint64 *stream_length) 265{ 266 if(layer_ == LAYER_STREAM) 267 return ::FLAC__STREAM_DECODER_LENGTH_STATUS_UNSUPPORTED; 268 269 if(error_occurred_) 270 return ::FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR; 271 272 *stream_length = (FLAC__uint64)flacfilesize_; 273 return ::FLAC__STREAM_DECODER_LENGTH_STATUS_OK; 274} 275 276bool StreamDecoder::eof_callback() 277{ 278 if(layer_ == LAYER_STREAM) 279 return false; 280 281 if(error_occurred_) 282 return true; 283 284 return (bool)feof(file_); 285} 286 287::FLAC__StreamDecoderWriteStatus StreamDecoder::write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[]) 288{ 289 (void)buffer; 290 291 return common_write_callback_(frame); 292} 293 294void StreamDecoder::metadata_callback(const ::FLAC__StreamMetadata *metadata) 295{ 296 common_metadata_callback_(metadata); 297} 298 299void StreamDecoder::error_callback(::FLAC__StreamDecoderErrorStatus status) 300{ 301 common_error_callback_(status); 302} 303 304bool StreamDecoder::test_respond(bool is_ogg) 305{ 306 ::FLAC__StreamDecoderInitStatus init_status; 307 308 if(!set_md5_checking(true)) { 309 printf("FAILED at set_md5_checking(), returned false\n"); 310 return false; 311 } 312 313 printf("testing init%s()... ", is_ogg? "_ogg":""); 314 init_status = is_ogg? init_ogg() : init(); 315 if(init_status != ::FLAC__STREAM_DECODER_INIT_STATUS_OK) 316 return die_s_(0, this); 317 printf("OK\n"); 318 319 current_metadata_number_ = 0; 320 321 if(fseeko(file_, 0, SEEK_SET) < 0) { 322 printf("FAILED rewinding input, errno = %d\n", errno); 323 return false; 324 } 325 326 printf("testing process_until_end_of_stream()... "); 327 if(!process_until_end_of_stream()) { 328 State state = get_state(); 329 printf("FAILED, returned false, state = %u (%s)\n", (unsigned)((::FLAC__StreamDecoderState)state), state.as_cstring()); 330 return false; 331 } 332 printf("OK\n"); 333 334 printf("testing finish()... "); 335 if(!finish()) { 336 State state = get_state(); 337 printf("FAILED, returned false, state = %u (%s)\n", (unsigned)((::FLAC__StreamDecoderState)state), state.as_cstring()); 338 return false; 339 } 340 printf("OK\n"); 341 342 return true; 343} 344 345class FileDecoder : public FLAC::Decoder::File, public DecoderCommon { 346public: 347 FileDecoder(Layer layer): FLAC::Decoder::File(), DecoderCommon(layer) { } 348 ~FileDecoder() { } 349 350 // from FLAC::Decoder::Stream 351 ::FLAC__StreamDecoderWriteStatus write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[]); 352 void metadata_callback(const ::FLAC__StreamMetadata *metadata); 353 void error_callback(::FLAC__StreamDecoderErrorStatus status); 354 355 bool test_respond(bool is_ogg); 356}; 357 358::FLAC__StreamDecoderWriteStatus FileDecoder::write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[]) 359{ 360 (void)buffer; 361 return common_write_callback_(frame); 362} 363 364void FileDecoder::metadata_callback(const ::FLAC__StreamMetadata *metadata) 365{ 366 common_metadata_callback_(metadata); 367} 368 369void FileDecoder::error_callback(::FLAC__StreamDecoderErrorStatus status) 370{ 371 common_error_callback_(status); 372} 373 374bool FileDecoder::test_respond(bool is_ogg) 375{ 376 ::FLAC__StreamDecoderInitStatus init_status; 377 378 if(!set_md5_checking(true)) { 379 printf("FAILED at set_md5_checking(), returned false\n"); 380 return false; 381 } 382 383 switch(layer_) { 384 case LAYER_FILE: 385 { 386 printf("opening %sFLAC file... ", is_ogg? "Ogg ":""); 387 FILE *file = ::fopen(flacfilename(is_ogg), "rb"); 388 if(0 == file) { 389 printf("ERROR (%s)\n", strerror(errno)); 390 return false; 391 } 392 printf("OK\n"); 393 394 printf("testing init%s()... ", is_ogg? "_ogg":""); 395 init_status = is_ogg? init_ogg(file) : init(file); 396 } 397 break; 398 case LAYER_FILENAME: 399 printf("testing init%s()... ", is_ogg? "_ogg":""); 400 init_status = is_ogg? init_ogg(flacfilename(is_ogg)) : init(flacfilename(is_ogg)); 401 break; 402 default: 403 die_("internal error 001"); 404 return false; 405 } 406 if(init_status != ::FLAC__STREAM_DECODER_INIT_STATUS_OK) 407 return die_s_(0, this); 408 printf("OK\n"); 409 410 current_metadata_number_ = 0; 411 412 printf("testing process_until_end_of_stream()... "); 413 if(!process_until_end_of_stream()) { 414 State state = get_state(); 415 printf("FAILED, returned false, state = %u (%s)\n", (unsigned)((::FLAC__StreamDecoderState)state), state.as_cstring()); 416 return false; 417 } 418 printf("OK\n"); 419 420 printf("testing finish()... "); 421 if(!finish()) { 422 State state = get_state(); 423 printf("FAILED, returned false, state = %u (%s)\n", (unsigned)((::FLAC__StreamDecoderState)state), state.as_cstring()); 424 return false; 425 } 426 printf("OK\n"); 427 428 return true; 429} 430 431 432static FLAC::Decoder::Stream *new_by_layer(Layer layer) 433{ 434 if(layer < LAYER_FILE) 435 return new StreamDecoder(layer); 436 else 437 return new FileDecoder(layer); 438} 439 440static bool test_stream_decoder(Layer layer, bool is_ogg) 441{ 442 FLAC::Decoder::Stream *decoder; 443 ::FLAC__StreamDecoderInitStatus init_status; 444 bool expect; 445 446 printf("\n+++ libFLAC++ unit test: FLAC::Decoder::%s (layer: %s, format: %s)\n\n", layer<LAYER_FILE? "Stream":"File", LayerString[layer], is_ogg? "Ogg FLAC" : "FLAC"); 447 448 // 449 // test new -> delete 450 // 451 printf("allocating decoder instance... "); 452 decoder = new_by_layer(layer); 453 if(0 == decoder) { 454 printf("FAILED, new returned NULL\n"); 455 return false; 456 } 457 printf("OK\n"); 458 459 printf("testing is_valid()... "); 460 if(!decoder->is_valid()) { 461 printf("FAILED, returned false\n"); 462 return false; 463 } 464 printf("OK\n"); 465 466 printf("freeing decoder instance... "); 467 delete decoder; 468 printf("OK\n"); 469 470 // 471 // test new -> init -> delete 472 // 473 printf("allocating decoder instance... "); 474 decoder = new_by_layer(layer); 475 if(0 == decoder) { 476 printf("FAILED, new returned NULL\n"); 477 return false; 478 } 479 printf("OK\n"); 480 481 printf("testing is_valid()... "); 482 if(!decoder->is_valid()) { 483 printf("FAILED, returned false\n"); 484 return false; 485 } 486 printf("OK\n"); 487 488 printf("testing init%s()... ", is_ogg? "_ogg":""); 489 switch(layer) { 490 case LAYER_STREAM: 491 case LAYER_SEEKABLE_STREAM: 492 dynamic_cast<StreamDecoder*>(decoder)->file_ = stdin; 493 init_status = is_ogg? decoder->init_ogg() : decoder->init(); 494 break; 495 case LAYER_FILE: 496 init_status = is_ogg? 497 dynamic_cast<FLAC::Decoder::File*>(decoder)->init_ogg(stdin) : 498 dynamic_cast<FLAC::Decoder::File*>(decoder)->init(stdin); 499 break; 500 case LAYER_FILENAME: 501 init_status = is_ogg? 502 dynamic_cast<FLAC::Decoder::File*>(decoder)->init_ogg(flacfilename(is_ogg)) : 503 dynamic_cast<FLAC::Decoder::File*>(decoder)->init(flacfilename(is_ogg)); 504 break; 505 default: 506 die_("internal error 006"); 507 return false; 508 } 509 if(init_status != ::FLAC__STREAM_DECODER_INIT_STATUS_OK) 510 return die_s_(0, decoder); 511 printf("OK\n"); 512 513 printf("freeing decoder instance... "); 514 delete decoder; 515 printf("OK\n"); 516 517 // 518 // test normal usage 519 // 520 num_expected_ = 0; 521 expected_metadata_sequence_[num_expected_++] = &streaminfo_; 522 523 printf("allocating decoder instance... "); 524 decoder = new_by_layer(layer); 525 if(0 == decoder) { 526 printf("FAILED, new returned NULL\n"); 527 return false; 528 } 529 printf("OK\n"); 530 531 printf("testing is_valid()... "); 532 if(!decoder->is_valid()) { 533 printf("FAILED, returned false\n"); 534 return false; 535 } 536 printf("OK\n"); 537 538 if(is_ogg) { 539 printf("testing set_ogg_serial_number()... "); 540 if(!decoder->set_ogg_serial_number(file_utils__ogg_serial_number)) 541 return die_s_("returned false", decoder); 542 printf("OK\n"); 543 } 544 545 if(!decoder->set_md5_checking(true)) { 546 printf("FAILED at set_md5_checking(), returned false\n"); 547 return false; 548 } 549 550 switch(layer) { 551 case LAYER_STREAM: 552 case LAYER_SEEKABLE_STREAM: 553 printf("opening %sFLAC file... ", is_ogg? "Ogg ":""); 554 dynamic_cast<StreamDecoder*>(decoder)->file_ = ::fopen(flacfilename(is_ogg), "rb"); 555 if(0 == dynamic_cast<StreamDecoder*>(decoder)->file_) { 556 printf("ERROR (%s)\n", strerror(errno)); 557 return false; 558 } 559 printf("OK\n"); 560 561 printf("testing init%s()... ", is_ogg? "_ogg":""); 562 init_status = is_ogg? decoder->init_ogg() : decoder->init(); 563 break; 564 case LAYER_FILE: 565 { 566 printf("opening FLAC file... "); 567 FILE *file = ::fopen(flacfilename(is_ogg), "rb"); 568 if(0 == file) { 569 printf("ERROR (%s)\n", strerror(errno)); 570 return false; 571 } 572 printf("OK\n"); 573 574 printf("testing init%s()... ", is_ogg? "_ogg":""); 575 init_status = is_ogg? 576 dynamic_cast<FLAC::Decoder::File*>(decoder)->init_ogg(file) : 577 dynamic_cast<FLAC::Decoder::File*>(decoder)->init(file); 578 } 579 break; 580 case LAYER_FILENAME: 581 printf("testing init%s()... ", is_ogg? "_ogg":""); 582 init_status = is_ogg? 583 dynamic_cast<FLAC::Decoder::File*>(decoder)->init_ogg(flacfilename(is_ogg)) : 584 dynamic_cast<FLAC::Decoder::File*>(decoder)->init(flacfilename(is_ogg)); 585 break; 586 default: 587 die_("internal error 009"); 588 return false; 589 } 590 if(init_status != ::FLAC__STREAM_DECODER_INIT_STATUS_OK) 591 return die_s_(0, decoder); 592 printf("OK\n"); 593 594 printf("testing get_state()... "); 595 FLAC::Decoder::Stream::State state = decoder->get_state(); 596 printf("returned state = %u (%s)... OK\n", (unsigned)((::FLAC__StreamDecoderState)state), state.as_cstring()); 597 598 dynamic_cast<DecoderCommon*>(decoder)->current_metadata_number_ = 0; 599 dynamic_cast<DecoderCommon*>(decoder)->ignore_errors_ = false; 600 dynamic_cast<DecoderCommon*>(decoder)->error_occurred_ = false; 601 602 printf("testing get_md5_checking()... "); 603 if(!decoder->get_md5_checking()) { 604 printf("FAILED, returned false, expected true\n"); 605 return false; 606 } 607 printf("OK\n"); 608 609 printf("testing process_until_end_of_metadata()... "); 610 if(!decoder->process_until_end_of_metadata()) 611 return die_s_("returned false", decoder); 612 printf("OK\n"); 613 614 printf("testing process_single()... "); 615 if(!decoder->process_single()) 616 return die_s_("returned false", decoder); 617 printf("OK\n"); 618 619 printf("testing skip_single_frame()... "); 620 if(!decoder->skip_single_frame()) 621 return die_s_("returned false", decoder); 622 printf("OK\n"); 623 624 if(layer < LAYER_FILE) { 625 printf("testing flush()... "); 626 if(!decoder->flush()) 627 return die_s_("returned false", decoder); 628 printf("OK\n"); 629 630 dynamic_cast<DecoderCommon*>(decoder)->ignore_errors_ = true; 631 printf("testing process_single()... "); 632 if(!decoder->process_single()) 633 return die_s_("returned false", decoder); 634 printf("OK\n"); 635 dynamic_cast<DecoderCommon*>(decoder)->ignore_errors_ = false; 636 } 637 638 expect = (layer != LAYER_STREAM); 639 printf("testing seek_absolute()... "); 640 if(decoder->seek_absolute(0) != expect) 641 return die_s_(expect? "returned false" : "returned true", decoder); 642 printf("OK\n"); 643 644 printf("testing process_until_end_of_stream()... "); 645 if(!decoder->process_until_end_of_stream()) 646 return die_s_("returned false", decoder); 647 printf("OK\n"); 648 649 expect = (layer != LAYER_STREAM); 650 printf("testing seek_absolute()... "); 651 if(decoder->seek_absolute(0) != expect) 652 return die_s_(expect? "returned false" : "returned true", decoder); 653 printf("OK\n"); 654 655 printf("testing get_channels()... "); 656 { 657 unsigned channels = decoder->get_channels(); 658 if(channels != streaminfo_.data.stream_info.channels) { 659 printf("FAILED, returned %u, expected %u\n", channels, streaminfo_.data.stream_info.channels); 660 return false; 661 } 662 } 663 printf("OK\n"); 664 665 printf("testing get_bits_per_sample()... "); 666 { 667 unsigned bits_per_sample = decoder->get_bits_per_sample(); 668 if(bits_per_sample != streaminfo_.data.stream_info.bits_per_sample) { 669 printf("FAILED, returned %u, expected %u\n", bits_per_sample, streaminfo_.data.stream_info.bits_per_sample); 670 return false; 671 } 672 } 673 printf("OK\n"); 674 675 printf("testing get_sample_rate()... "); 676 { 677 unsigned sample_rate = decoder->get_sample_rate(); 678 if(sample_rate != streaminfo_.data.stream_info.sample_rate) { 679 printf("FAILED, returned %u, expected %u\n", sample_rate, streaminfo_.data.stream_info.sample_rate); 680 return false; 681 } 682 } 683 printf("OK\n"); 684 685 printf("testing get_blocksize()... "); 686 { 687 unsigned blocksize = decoder->get_blocksize(); 688 /* value could be anything since we're at the last block, so accept any reasonable answer */ 689 printf("returned %u... %s\n", blocksize, blocksize>0? "OK" : "FAILED"); 690 if(blocksize == 0) 691 return false; 692 } 693 694 printf("testing get_channel_assignment()... "); 695 { 696 ::FLAC__ChannelAssignment ca = decoder->get_channel_assignment(); 697 printf("returned %u (%s)... OK\n", (unsigned)ca, ::FLAC__ChannelAssignmentString[ca]); 698 } 699 700 if(layer < LAYER_FILE) { 701 printf("testing reset()... "); 702 if(!decoder->reset()) 703 return die_s_("returned false", decoder); 704 printf("OK\n"); 705 706 if(layer == LAYER_STREAM) { 707 /* after a reset() we have to rewind the input ourselves */ 708 printf("rewinding input... "); 709 if(fseeko(dynamic_cast<StreamDecoder*>(decoder)->file_, 0, SEEK_SET) < 0) { 710 printf("FAILED, errno = %d\n", errno); 711 return false; 712 } 713 printf("OK\n"); 714 } 715 716 dynamic_cast<DecoderCommon*>(decoder)->current_metadata_number_ = 0; 717 718 printf("testing process_until_end_of_stream()... "); 719 if(!decoder->process_until_end_of_stream()) 720 return die_s_("returned false", decoder); 721 printf("OK\n"); 722 } 723 724 printf("testing finish()... "); 725 if(!decoder->finish()) { 726 FLAC::Decoder::Stream::State state = decoder->get_state(); 727 printf("FAILED, returned false, state = %u (%s)\n", (unsigned)((::FLAC__StreamDecoderState)state), state.as_cstring()); 728 return false; 729 } 730 printf("OK\n"); 731 732 /* 733 * respond all 734 */ 735 736 printf("testing set_metadata_respond_all()... "); 737 if(!decoder->set_metadata_respond_all()) { 738 printf("FAILED, returned false\n"); 739 return false; 740 } 741 printf("OK\n"); 742 743 num_expected_ = 0; 744 if(is_ogg) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */ 745 expected_metadata_sequence_[num_expected_++] = &streaminfo_; 746 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; 747 expected_metadata_sequence_[num_expected_++] = &padding_; 748 expected_metadata_sequence_[num_expected_++] = &seektable_; 749 expected_metadata_sequence_[num_expected_++] = &application1_; 750 expected_metadata_sequence_[num_expected_++] = &application2_; 751 expected_metadata_sequence_[num_expected_++] = &cuesheet_; 752 expected_metadata_sequence_[num_expected_++] = &picture_; 753 expected_metadata_sequence_[num_expected_++] = &unknown_; 754 } 755 else { 756 expected_metadata_sequence_[num_expected_++] = &streaminfo_; 757 expected_metadata_sequence_[num_expected_++] = &padding_; 758 expected_metadata_sequence_[num_expected_++] = &seektable_; 759 expected_metadata_sequence_[num_expected_++] = &application1_; 760 expected_metadata_sequence_[num_expected_++] = &application2_; 761 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; 762 expected_metadata_sequence_[num_expected_++] = &cuesheet_; 763 expected_metadata_sequence_[num_expected_++] = &picture_; 764 expected_metadata_sequence_[num_expected_++] = &unknown_; 765 } 766 767 if(!(layer < LAYER_FILE? dynamic_cast<StreamDecoder*>(decoder)->test_respond(is_ogg) : dynamic_cast<FileDecoder*>(decoder)->test_respond(is_ogg))) 768 return false; 769 770 /* 771 * ignore all 772 */ 773 774 printf("testing set_metadata_ignore_all()... "); 775 if(!decoder->set_metadata_ignore_all()) { 776 printf("FAILED, returned false\n"); 777 return false; 778 } 779 printf("OK\n"); 780 781 num_expected_ = 0; 782 783 if(!(layer < LAYER_FILE? dynamic_cast<StreamDecoder*>(decoder)->test_respond(is_ogg) : dynamic_cast<FileDecoder*>(decoder)->test_respond(is_ogg))) 784 return false; 785 786 /* 787 * respond all, ignore VORBIS_COMMENT 788 */ 789 790 printf("testing set_metadata_respond_all()... "); 791 if(!decoder->set_metadata_respond_all()) { 792 printf("FAILED, returned false\n"); 793 return false; 794 } 795 printf("OK\n"); 796 797 printf("testing set_metadata_ignore(VORBIS_COMMENT)... "); 798 if(!decoder->set_metadata_ignore(FLAC__METADATA_TYPE_VORBIS_COMMENT)) { 799 printf("FAILED, returned false\n"); 800 return false; 801 } 802 printf("OK\n"); 803 804 num_expected_ = 0; 805 expected_metadata_sequence_[num_expected_++] = &streaminfo_; 806 expected_metadata_sequence_[num_expected_++] = &padding_; 807 expected_metadata_sequence_[num_expected_++] = &seektable_; 808 expected_metadata_sequence_[num_expected_++] = &application1_; 809 expected_metadata_sequence_[num_expected_++] = &application2_; 810 expected_metadata_sequence_[num_expected_++] = &cuesheet_; 811 expected_metadata_sequence_[num_expected_++] = &picture_; 812 expected_metadata_sequence_[num_expected_++] = &unknown_; 813 814 if(!(layer < LAYER_FILE? dynamic_cast<StreamDecoder*>(decoder)->test_respond(is_ogg) : dynamic_cast<FileDecoder*>(decoder)->test_respond(is_ogg))) 815 return false; 816 817 /* 818 * respond all, ignore APPLICATION 819 */ 820 821 printf("testing set_metadata_respond_all()... "); 822 if(!decoder->set_metadata_respond_all()) { 823 printf("FAILED, returned false\n"); 824 return false; 825 } 826 printf("OK\n"); 827 828 printf("testing set_metadata_ignore(APPLICATION)... "); 829 if(!decoder->set_metadata_ignore(FLAC__METADATA_TYPE_APPLICATION)) { 830 printf("FAILED, returned false\n"); 831 return false; 832 } 833 printf("OK\n"); 834 835 num_expected_ = 0; 836 if(is_ogg) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */ 837 expected_metadata_sequence_[num_expected_++] = &streaminfo_; 838 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; 839 expected_metadata_sequence_[num_expected_++] = &padding_; 840 expected_metadata_sequence_[num_expected_++] = &seektable_; 841 expected_metadata_sequence_[num_expected_++] = &cuesheet_; 842 expected_metadata_sequence_[num_expected_++] = &picture_; 843 expected_metadata_sequence_[num_expected_++] = &unknown_; 844 } 845 else { 846 expected_metadata_sequence_[num_expected_++] = &streaminfo_; 847 expected_metadata_sequence_[num_expected_++] = &padding_; 848 expected_metadata_sequence_[num_expected_++] = &seektable_; 849 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; 850 expected_metadata_sequence_[num_expected_++] = &cuesheet_; 851 expected_metadata_sequence_[num_expected_++] = &picture_; 852 expected_metadata_sequence_[num_expected_++] = &unknown_; 853 } 854 855 if(!(layer < LAYER_FILE? dynamic_cast<StreamDecoder*>(decoder)->test_respond(is_ogg) : dynamic_cast<FileDecoder*>(decoder)->test_respond(is_ogg))) 856 return false; 857 858 /* 859 * respond all, ignore APPLICATION id of app#1 860 */ 861 862 printf("testing set_metadata_respond_all()... "); 863 if(!decoder->set_metadata_respond_all()) { 864 printf("FAILED, returned false\n"); 865 return false; 866 } 867 printf("OK\n"); 868 869 printf("testing set_metadata_ignore_application(of app block #1)... "); 870 if(!decoder->set_metadata_ignore_application(application1_.data.application.id)) { 871 printf("FAILED, returned false\n"); 872 return false; 873 } 874 printf("OK\n"); 875 876 num_expected_ = 0; 877 if(is_ogg) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */ 878 expected_metadata_sequence_[num_expected_++] = &streaminfo_; 879 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; 880 expected_metadata_sequence_[num_expected_++] = &padding_; 881 expected_metadata_sequence_[num_expected_++] = &seektable_; 882 expected_metadata_sequence_[num_expected_++] = &application2_; 883 expected_metadata_sequence_[num_expected_++] = &cuesheet_; 884 expected_metadata_sequence_[num_expected_++] = &picture_; 885 expected_metadata_sequence_[num_expected_++] = &unknown_; 886 } 887 else { 888 expected_metadata_sequence_[num_expected_++] = &streaminfo_; 889 expected_metadata_sequence_[num_expected_++] = &padding_; 890 expected_metadata_sequence_[num_expected_++] = &seektable_; 891 expected_metadata_sequence_[num_expected_++] = &application2_; 892 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; 893 expected_metadata_sequence_[num_expected_++] = &cuesheet_; 894 expected_metadata_sequence_[num_expected_++] = &picture_; 895 expected_metadata_sequence_[num_expected_++] = &unknown_; 896 } 897 898 if(!(layer < LAYER_FILE? dynamic_cast<StreamDecoder*>(decoder)->test_respond(is_ogg) : dynamic_cast<FileDecoder*>(decoder)->test_respond(is_ogg))) 899 return false; 900 901 /* 902 * respond all, ignore APPLICATION id of app#1 & app#2 903 */ 904 905 printf("testing set_metadata_respond_all()... "); 906 if(!decoder->set_metadata_respond_all()) { 907 printf("FAILED, returned false\n"); 908 return false; 909 } 910 printf("OK\n"); 911 912 printf("testing set_metadata_ignore_application(of app block #1)... "); 913 if(!decoder->set_metadata_ignore_application(application1_.data.application.id)) { 914 printf("FAILED, returned false\n"); 915 return false; 916 } 917 printf("OK\n"); 918 919 printf("testing set_metadata_ignore_application(of app block #2)... "); 920 if(!decoder->set_metadata_ignore_application(application2_.data.application.id)) { 921 printf("FAILED, returned false\n"); 922 return false; 923 } 924 printf("OK\n"); 925 926 num_expected_ = 0; 927 if(is_ogg) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */ 928 expected_metadata_sequence_[num_expected_++] = &streaminfo_; 929 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; 930 expected_metadata_sequence_[num_expected_++] = &padding_; 931 expected_metadata_sequence_[num_expected_++] = &seektable_; 932 expected_metadata_sequence_[num_expected_++] = &cuesheet_; 933 expected_metadata_sequence_[num_expected_++] = &picture_; 934 expected_metadata_sequence_[num_expected_++] = &unknown_; 935 } 936 else { 937 expected_metadata_sequence_[num_expected_++] = &streaminfo_; 938 expected_metadata_sequence_[num_expected_++] = &padding_; 939 expected_metadata_sequence_[num_expected_++] = &seektable_; 940 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; 941 expected_metadata_sequence_[num_expected_++] = &cuesheet_; 942 expected_metadata_sequence_[num_expected_++] = &picture_; 943 expected_metadata_sequence_[num_expected_++] = &unknown_; 944 } 945 946 if(!(layer < LAYER_FILE? dynamic_cast<StreamDecoder*>(decoder)->test_respond(is_ogg) : dynamic_cast<FileDecoder*>(decoder)->test_respond(is_ogg))) 947 return false; 948 949 /* 950 * ignore all, respond VORBIS_COMMENT 951 */ 952 953 printf("testing set_metadata_ignore_all()... "); 954 if(!decoder->set_metadata_ignore_all()) { 955 printf("FAILED, returned false\n"); 956 return false; 957 } 958 printf("OK\n"); 959 960 printf("testing set_metadata_respond(VORBIS_COMMENT)... "); 961 if(!decoder->set_metadata_respond(FLAC__METADATA_TYPE_VORBIS_COMMENT)) { 962 printf("FAILED, returned false\n"); 963 return false; 964 } 965 printf("OK\n"); 966 967 num_expected_ = 0; 968 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; 969 970 if(!(layer < LAYER_FILE? dynamic_cast<StreamDecoder*>(decoder)->test_respond(is_ogg) : dynamic_cast<FileDecoder*>(decoder)->test_respond(is_ogg))) 971 return false; 972 973 /* 974 * ignore all, respond APPLICATION 975 */ 976 977 printf("testing set_metadata_ignore_all()... "); 978 if(!decoder->set_metadata_ignore_all()) { 979 printf("FAILED, returned false\n"); 980 return false; 981 } 982 printf("OK\n"); 983 984 printf("testing set_metadata_respond(APPLICATION)... "); 985 if(!decoder->set_metadata_respond(FLAC__METADATA_TYPE_APPLICATION)) { 986 printf("FAILED, returned false\n"); 987 return false; 988 } 989 printf("OK\n"); 990 991 num_expected_ = 0; 992 expected_metadata_sequence_[num_expected_++] = &application1_; 993 expected_metadata_sequence_[num_expected_++] = &application2_; 994 995 if(!(layer < LAYER_FILE? dynamic_cast<StreamDecoder*>(decoder)->test_respond(is_ogg) : dynamic_cast<FileDecoder*>(decoder)->test_respond(is_ogg))) 996 return false; 997 998 /* 999 * ignore all, respond APPLICATION id of app#1 1000 */ 1001 1002 printf("testing set_metadata_ignore_all()... "); 1003 if(!decoder->set_metadata_ignore_all()) { 1004 printf("FAILED, returned false\n"); 1005 return false; 1006 } 1007 printf("OK\n"); 1008 1009 printf("testing set_metadata_respond_application(of app block #1)... "); 1010 if(!decoder->set_metadata_respond_application(application1_.data.application.id)) { 1011 printf("FAILED, returned false\n"); 1012 return false; 1013 } 1014 printf("OK\n"); 1015 1016 num_expected_ = 0; 1017 expected_metadata_sequence_[num_expected_++] = &application1_; 1018 1019 if(!(layer < LAYER_FILE? dynamic_cast<StreamDecoder*>(decoder)->test_respond(is_ogg) : dynamic_cast<FileDecoder*>(decoder)->test_respond(is_ogg))) 1020 return false; 1021 1022 /* 1023 * ignore all, respond APPLICATION id of app#1 & app#2 1024 */ 1025 1026 printf("testing set_metadata_ignore_all()... "); 1027 if(!decoder->set_metadata_ignore_all()) { 1028 printf("FAILED, returned false\n"); 1029 return false; 1030 } 1031 printf("OK\n"); 1032 1033 printf("testing set_metadata_respond_application(of app block #1)... "); 1034 if(!decoder->set_metadata_respond_application(application1_.data.application.id)) { 1035 printf("FAILED, returned false\n"); 1036 return false; 1037 } 1038 printf("OK\n"); 1039 1040 printf("testing set_metadata_respond_application(of app block #2)... "); 1041 if(!decoder->set_metadata_respond_application(application2_.data.application.id)) { 1042 printf("FAILED, returned false\n"); 1043 return false; 1044 } 1045 printf("OK\n"); 1046 1047 num_expected_ = 0; 1048 expected_metadata_sequence_[num_expected_++] = &application1_; 1049 expected_metadata_sequence_[num_expected_++] = &application2_; 1050 1051 if(!(layer < LAYER_FILE? dynamic_cast<StreamDecoder*>(decoder)->test_respond(is_ogg) : dynamic_cast<FileDecoder*>(decoder)->test_respond(is_ogg))) 1052 return false; 1053 1054 /* 1055 * respond all, ignore APPLICATION, respond APPLICATION id of app#1 1056 */ 1057 1058 printf("testing set_metadata_respond_all()... "); 1059 if(!decoder->set_metadata_respond_all()) { 1060 printf("FAILED, returned false\n"); 1061 return false; 1062 } 1063 printf("OK\n"); 1064 1065 printf("testing set_metadata_ignore(APPLICATION)... "); 1066 if(!decoder->set_metadata_ignore(FLAC__METADATA_TYPE_APPLICATION)) { 1067 printf("FAILED, returned false\n"); 1068 return false; 1069 } 1070 printf("OK\n"); 1071 1072 printf("testing set_metadata_respond_application(of app block #1)... "); 1073 if(!decoder->set_metadata_respond_application(application1_.data.application.id)) { 1074 printf("FAILED, returned false\n"); 1075 return false; 1076 } 1077 printf("OK\n"); 1078 1079 num_expected_ = 0; 1080 if(is_ogg) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */ 1081 expected_metadata_sequence_[num_expected_++] = &streaminfo_; 1082 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; 1083 expected_metadata_sequence_[num_expected_++] = &padding_; 1084 expected_metadata_sequence_[num_expected_++] = &seektable_; 1085 expected_metadata_sequence_[num_expected_++] = &application1_; 1086 expected_metadata_sequence_[num_expected_++] = &cuesheet_; 1087 expected_metadata_sequence_[num_expected_++] = &picture_; 1088 expected_metadata_sequence_[num_expected_++] = &unknown_; 1089 } 1090 else { 1091 expected_metadata_sequence_[num_expected_++] = &streaminfo_; 1092 expected_metadata_sequence_[num_expected_++] = &padding_; 1093 expected_metadata_sequence_[num_expected_++] = &seektable_; 1094 expected_metadata_sequence_[num_expected_++] = &application1_; 1095 expected_metadata_sequence_[num_expected_++] = &vorbiscomment_; 1096 expected_metadata_sequence_[num_expected_++] = &cuesheet_; 1097 expected_metadata_sequence_[num_expected_++] = &picture_; 1098 expected_metadata_sequence_[num_expected_++] = &unknown_; 1099 } 1100 1101 if(!(layer < LAYER_FILE? dynamic_cast<StreamDecoder*>(decoder)->test_respond(is_ogg) : dynamic_cast<FileDecoder*>(decoder)->test_respond(is_ogg))) 1102 return false; 1103 1104 /* 1105 * ignore all, respond APPLICATION, ignore APPLICATION id of app#1 1106 */ 1107 1108 printf("testing set_metadata_ignore_all()... "); 1109 if(!decoder->set_metadata_ignore_all()) { 1110 printf("FAILED, returned false\n"); 1111 return false; 1112 } 1113 printf("OK\n"); 1114 1115 printf("testing set_metadata_respond(APPLICATION)... "); 1116 if(!decoder->set_metadata_respond(FLAC__METADATA_TYPE_APPLICATION)) { 1117 printf("FAILED, returned false\n"); 1118 return false; 1119 } 1120 printf("OK\n"); 1121 1122 printf("testing set_metadata_ignore_application(of app block #1)... "); 1123 if(!decoder->set_metadata_ignore_application(application1_.data.application.id)) { 1124 printf("FAILED, returned false\n"); 1125 return false; 1126 } 1127 printf("OK\n"); 1128 1129 num_expected_ = 0; 1130 expected_metadata_sequence_[num_expected_++] = &application2_; 1131 1132 if(!(layer < LAYER_FILE? dynamic_cast<StreamDecoder*>(decoder)->test_respond(is_ogg) : dynamic_cast<FileDecoder*>(decoder)->test_respond(is_ogg))) 1133 return false; 1134 1135 if(layer < LAYER_FILE) /* for LAYER_FILE, FLAC__stream_decoder_finish() closes the file */ 1136 ::fclose(dynamic_cast<StreamDecoder*>(decoder)->file_); 1137 1138 printf("freeing decoder instance... "); 1139 delete decoder; 1140 printf("OK\n"); 1141 1142 printf("\nPASSED!\n"); 1143 1144 return true; 1145} 1146 1147bool test_decoders() 1148{ 1149 FLAC__bool is_ogg = false; 1150 1151 while(1) { 1152 init_metadata_blocks_(); 1153 1154 if(!generate_file_(is_ogg)) 1155 return false; 1156 1157 if(!test_stream_decoder(LAYER_STREAM, is_ogg)) 1158 return false; 1159 1160 if(!test_stream_decoder(LAYER_SEEKABLE_STREAM, is_ogg)) 1161 return false; 1162 1163 if(!test_stream_decoder(LAYER_FILE, is_ogg)) 1164 return false; 1165 1166 if(!test_stream_decoder(LAYER_FILENAME, is_ogg)) 1167 return false; 1168 1169 (void) grabbag__file_remove_file(flacfilename(is_ogg)); 1170 1171 free_metadata_blocks_(); 1172 1173 if(!FLAC_API_SUPPORTS_OGG_FLAC || is_ogg) 1174 break; 1175 is_ogg = true; 1176 } 1177 1178 return true; 1179} 1180