1 /* test_libFLAC - Unit tester for libFLAC
2 * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009 Josh Coalson
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.
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.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 #include "FLAC/assert.h"
29 #include "FLAC/stream_decoder.h"
30 #include "share/grabbag.h"
31 #include "share/compat.h"
32 #include "test_libs_common/file_utils_flac.h"
33 #include "test_libs_common/metadata_utils.h"
36 LAYER_STREAM
= 0, /* FLAC__stream_decoder_init_[ogg_]stream() without seeking */
37 LAYER_SEEKABLE_STREAM
, /* FLAC__stream_decoder_init_[ogg_]stream() with seeking */
38 LAYER_FILE
, /* FLAC__stream_decoder_init_[ogg_]FILE() */
39 LAYER_FILENAME
/* FLAC__stream_decoder_init_[ogg_]file() */
42 static const char * const LayerString
[] = {
52 unsigned current_metadata_number
;
53 FLAC__bool ignore_errors
;
54 FLAC__bool error_occurred
;
55 } StreamDecoderClientData
;
57 static FLAC__StreamMetadata streaminfo_
, padding_
, seektable_
, application1_
, application2_
, vorbiscomment_
, cuesheet_
, picture_
, unknown_
;
58 static FLAC__StreamMetadata
*expected_metadata_sequence_
[9];
59 static unsigned num_expected_
;
60 static FLAC__off_t flacfilesize_
;
62 static const char *flacfilename(FLAC__bool is_ogg
)
64 return is_ogg
? "metadata.oga" : "metadata.flac";
67 static FLAC__bool
die_(const char *msg
)
69 printf("ERROR: %s\n", msg
);
73 static FLAC__bool
die_s_(const char *msg
, const FLAC__StreamDecoder
*decoder
)
75 FLAC__StreamDecoderState state
= FLAC__stream_decoder_get_state(decoder
);
78 printf("FAILED, %s", msg
);
82 printf(", state = %u (%s)\n", (unsigned)state
, FLAC__StreamDecoderStateString
[state
]);
87 static void init_metadata_blocks_(void)
89 mutils__init_metadata_blocks(&streaminfo_
, &padding_
, &seektable_
, &application1_
, &application2_
, &vorbiscomment_
, &cuesheet_
, &picture_
, &unknown_
);
92 static void free_metadata_blocks_(void)
94 mutils__free_metadata_blocks(&streaminfo_
, &padding_
, &seektable_
, &application1_
, &application2_
, &vorbiscomment_
, &cuesheet_
, &picture_
, &unknown_
);
97 static FLAC__bool
generate_file_(FLAC__bool is_ogg
)
99 printf("\n\ngenerating %sFLAC file for decoder tests...\n", is_ogg
? "Ogg ":"");
102 expected_metadata_sequence_
[num_expected_
++] = &padding_
;
103 expected_metadata_sequence_
[num_expected_
++] = &seektable_
;
104 expected_metadata_sequence_
[num_expected_
++] = &application1_
;
105 expected_metadata_sequence_
[num_expected_
++] = &application2_
;
106 expected_metadata_sequence_
[num_expected_
++] = &vorbiscomment_
;
107 expected_metadata_sequence_
[num_expected_
++] = &cuesheet_
;
108 expected_metadata_sequence_
[num_expected_
++] = &picture_
;
109 expected_metadata_sequence_
[num_expected_
++] = &unknown_
;
110 /* WATCHOUT: for Ogg FLAC the encoder should move the VORBIS_COMMENT block to the front, right after STREAMINFO */
112 if(!file_utils__generate_flacfile(is_ogg
, flacfilename(is_ogg
), &flacfilesize_
, 512 * 1024, &streaminfo_
, expected_metadata_sequence_
, num_expected_
))
113 return die_("creating the encoded file");
118 static FLAC__StreamDecoderReadStatus
stream_decoder_read_callback_(const FLAC__StreamDecoder
*decoder
, FLAC__byte buffer
[], size_t *bytes
, void *client_data
)
120 StreamDecoderClientData
*dcd
= (StreamDecoderClientData
*)client_data
;
121 const size_t requested_bytes
= *bytes
;
126 printf("ERROR: client_data in read callback is NULL\n");
127 return FLAC__STREAM_DECODER_READ_STATUS_ABORT
;
130 if(dcd
->error_occurred
)
131 return FLAC__STREAM_DECODER_READ_STATUS_ABORT
;
133 if(feof(dcd
->file
)) {
135 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM
;
137 else if(requested_bytes
> 0) {
138 *bytes
= fread(buffer
, 1, requested_bytes
, dcd
->file
);
141 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM
;
143 return FLAC__STREAM_DECODER_READ_STATUS_ABORT
;
146 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE
;
150 return FLAC__STREAM_DECODER_READ_STATUS_ABORT
; /* abort to avoid a deadlock */
153 static FLAC__StreamDecoderSeekStatus
stream_decoder_seek_callback_(const FLAC__StreamDecoder
*decoder
, FLAC__uint64 absolute_byte_offset
, void *client_data
)
155 StreamDecoderClientData
*dcd
= (StreamDecoderClientData
*)client_data
;
160 printf("ERROR: client_data in seek callback is NULL\n");
161 return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR
;
164 if(dcd
->error_occurred
)
165 return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR
;
167 if(fseeko(dcd
->file
, (FLAC__off_t
)absolute_byte_offset
, SEEK_SET
) < 0) {
168 dcd
->error_occurred
= true;
169 return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR
;
172 return FLAC__STREAM_DECODER_SEEK_STATUS_OK
;
175 static FLAC__StreamDecoderTellStatus
stream_decoder_tell_callback_(const FLAC__StreamDecoder
*decoder
, FLAC__uint64
*absolute_byte_offset
, void *client_data
)
177 StreamDecoderClientData
*dcd
= (StreamDecoderClientData
*)client_data
;
183 printf("ERROR: client_data in tell callback is NULL\n");
184 return FLAC__STREAM_DECODER_TELL_STATUS_ERROR
;
187 if(dcd
->error_occurred
)
188 return FLAC__STREAM_DECODER_TELL_STATUS_ERROR
;
190 offset
= ftello(dcd
->file
);
191 *absolute_byte_offset
= (FLAC__uint64
)offset
;
194 dcd
->error_occurred
= true;
195 return FLAC__STREAM_DECODER_TELL_STATUS_ERROR
;
198 return FLAC__STREAM_DECODER_TELL_STATUS_OK
;
201 static FLAC__StreamDecoderLengthStatus
stream_decoder_length_callback_(const FLAC__StreamDecoder
*decoder
, FLAC__uint64
*stream_length
, void *client_data
)
203 StreamDecoderClientData
*dcd
= (StreamDecoderClientData
*)client_data
;
208 printf("ERROR: client_data in length callback is NULL\n");
209 return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR
;
212 if(dcd
->error_occurred
)
213 return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR
;
215 *stream_length
= (FLAC__uint64
)flacfilesize_
;
216 return FLAC__STREAM_DECODER_LENGTH_STATUS_OK
;
219 static FLAC__bool
stream_decoder_eof_callback_(const FLAC__StreamDecoder
*decoder
, void *client_data
)
221 StreamDecoderClientData
*dcd
= (StreamDecoderClientData
*)client_data
;
226 printf("ERROR: client_data in eof callback is NULL\n");
230 if(dcd
->error_occurred
)
233 return feof(dcd
->file
);
236 static FLAC__StreamDecoderWriteStatus
stream_decoder_write_callback_(const FLAC__StreamDecoder
*decoder
, const FLAC__Frame
*frame
, const FLAC__int32
* const buffer
[], void *client_data
)
238 StreamDecoderClientData
*dcd
= (StreamDecoderClientData
*)client_data
;
240 (void)decoder
, (void)buffer
;
243 printf("ERROR: client_data in write callback is NULL\n");
244 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT
;
247 if(dcd
->error_occurred
)
248 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT
;
251 (frame
->header
.number_type
== FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER
&& frame
->header
.number
.frame_number
== 0) ||
252 (frame
->header
.number_type
== FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER
&& frame
->header
.number
.sample_number
== 0)
254 printf("content... ");
258 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE
;
261 static void stream_decoder_metadata_callback_(const FLAC__StreamDecoder
*decoder
, const FLAC__StreamMetadata
*metadata
, void *client_data
)
263 StreamDecoderClientData
*dcd
= (StreamDecoderClientData
*)client_data
;
268 printf("ERROR: client_data in metadata callback is NULL\n");
272 if(dcd
->error_occurred
)
275 printf("%d... ", dcd
->current_metadata_number
);
278 if(dcd
->current_metadata_number
>= num_expected_
) {
279 (void)die_("got more metadata blocks than expected");
280 dcd
->error_occurred
= true;
283 if(!mutils__compare_block(expected_metadata_sequence_
[dcd
->current_metadata_number
], metadata
)) {
284 (void)die_("metadata block mismatch");
285 dcd
->error_occurred
= true;
288 dcd
->current_metadata_number
++;
291 static void stream_decoder_error_callback_(const FLAC__StreamDecoder
*decoder
, FLAC__StreamDecoderErrorStatus status
, void *client_data
)
293 StreamDecoderClientData
*dcd
= (StreamDecoderClientData
*)client_data
;
298 printf("ERROR: client_data in error callback is NULL\n");
302 if(!dcd
->ignore_errors
) {
303 printf("ERROR: got error callback: err = %u (%s)\n", (unsigned)status
, FLAC__StreamDecoderErrorStatusString
[status
]);
304 dcd
->error_occurred
= true;
308 static FLAC__bool
stream_decoder_test_respond_(FLAC__StreamDecoder
*decoder
, StreamDecoderClientData
*dcd
, FLAC__bool is_ogg
)
310 FLAC__StreamDecoderInitStatus init_status
;
312 if(!FLAC__stream_decoder_set_md5_checking(decoder
, true))
313 return die_s_("at FLAC__stream_decoder_set_md5_checking(), returned false", decoder
);
315 /* for FLAC__stream_encoder_init_FILE(), the FLAC__stream_encoder_finish() closes the file so we have to keep re-opening: */
316 if(dcd
->layer
== LAYER_FILE
) {
317 printf("opening %sFLAC file... ", is_ogg
? "Ogg ":"");
318 dcd
->file
= fopen(flacfilename(is_ogg
), "rb");
320 printf("ERROR (%s)\n", strerror(errno
));
328 printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg
? "ogg_":"");
329 init_status
= is_ogg
?
330 FLAC__stream_decoder_init_ogg_stream(decoder
, stream_decoder_read_callback_
, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, dcd
) :
331 FLAC__stream_decoder_init_stream(decoder
, stream_decoder_read_callback_
, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, dcd
)
334 case LAYER_SEEKABLE_STREAM
:
335 printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg
? "ogg_":"");
336 init_status
= is_ogg
?
337 FLAC__stream_decoder_init_ogg_stream(decoder
, stream_decoder_read_callback_
, stream_decoder_seek_callback_
, stream_decoder_tell_callback_
, stream_decoder_length_callback_
, stream_decoder_eof_callback_
, stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, dcd
) :
338 FLAC__stream_decoder_init_stream(decoder
, stream_decoder_read_callback_
, stream_decoder_seek_callback_
, stream_decoder_tell_callback_
, stream_decoder_length_callback_
, stream_decoder_eof_callback_
, stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, dcd
);
341 printf("testing FLAC__stream_decoder_init_%sFILE()... ", is_ogg
? "ogg_":"");
342 init_status
= is_ogg
?
343 FLAC__stream_decoder_init_ogg_FILE(decoder
, dcd
->file
, stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, dcd
) :
344 FLAC__stream_decoder_init_FILE(decoder
, dcd
->file
, stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, dcd
);
347 printf("testing FLAC__stream_decoder_init_%sfile()... ", is_ogg
? "ogg_":"");
348 init_status
= is_ogg
?
349 FLAC__stream_decoder_init_ogg_file(decoder
, flacfilename(is_ogg
), stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, dcd
) :
350 FLAC__stream_decoder_init_file(decoder
, flacfilename(is_ogg
), stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, dcd
);
353 die_("internal error 000");
356 if(init_status
!= FLAC__STREAM_DECODER_INIT_STATUS_OK
)
357 return die_s_(0, decoder
);
360 dcd
->current_metadata_number
= 0;
362 if(dcd
->layer
< LAYER_FILE
&& fseeko(dcd
->file
, 0, SEEK_SET
) < 0) {
363 printf("FAILED rewinding input, errno = %d\n", errno
);
367 printf("testing FLAC__stream_decoder_process_until_end_of_stream()... ");
368 if(!FLAC__stream_decoder_process_until_end_of_stream(decoder
))
369 return die_s_("returned false", decoder
);
372 printf("testing FLAC__stream_decoder_finish()... ");
373 if(!FLAC__stream_decoder_finish(decoder
))
374 return die_s_("returned false", decoder
);
380 static FLAC__bool
test_stream_decoder(Layer layer
, FLAC__bool is_ogg
)
382 FLAC__StreamDecoder
*decoder
;
383 FLAC__StreamDecoderInitStatus init_status
;
384 FLAC__StreamDecoderState state
;
385 StreamDecoderClientData decoder_client_data
;
388 decoder_client_data
.layer
= layer
;
390 printf("\n+++ libFLAC unit test: FLAC__StreamDecoder (layer: %s, format: %s)\n\n", LayerString
[layer
], is_ogg
? "Ogg FLAC" : "FLAC");
392 printf("testing FLAC__stream_decoder_new()... ");
393 decoder
= FLAC__stream_decoder_new();
395 printf("FAILED, returned NULL\n");
400 printf("testing FLAC__stream_decoder_delete()... ");
401 FLAC__stream_decoder_delete(decoder
);
404 printf("testing FLAC__stream_decoder_new()... ");
405 decoder
= FLAC__stream_decoder_new();
407 printf("FAILED, returned NULL\n");
414 case LAYER_SEEKABLE_STREAM
:
415 printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg
? "ogg_":"");
416 init_status
= is_ogg
?
417 FLAC__stream_decoder_init_ogg_stream(decoder
, 0, 0, 0, 0, 0, 0, 0, 0, 0) :
418 FLAC__stream_decoder_init_stream(decoder
, 0, 0, 0, 0, 0, 0, 0, 0, 0);
421 printf("testing FLAC__stream_decoder_init_%sFILE()... ", is_ogg
? "ogg_":"");
422 init_status
= is_ogg
?
423 FLAC__stream_decoder_init_ogg_FILE(decoder
, stdin
, 0, 0, 0, 0) :
424 FLAC__stream_decoder_init_FILE(decoder
, stdin
, 0, 0, 0, 0);
427 printf("testing FLAC__stream_decoder_init_%sfile()... ", is_ogg
? "ogg_":"");
428 init_status
= is_ogg
?
429 FLAC__stream_decoder_init_ogg_file(decoder
, flacfilename(is_ogg
), 0, 0, 0, 0) :
430 FLAC__stream_decoder_init_file(decoder
, flacfilename(is_ogg
), 0, 0, 0, 0);
433 die_("internal error 003");
436 if(init_status
!= FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS
)
437 return die_s_(0, decoder
);
440 printf("testing FLAC__stream_decoder_delete()... ");
441 FLAC__stream_decoder_delete(decoder
);
445 expected_metadata_sequence_
[num_expected_
++] = &streaminfo_
;
447 printf("testing FLAC__stream_decoder_new()... ");
448 decoder
= FLAC__stream_decoder_new();
450 printf("FAILED, returned NULL\n");
456 printf("testing FLAC__stream_decoder_set_ogg_serial_number()... ");
457 if(!FLAC__stream_decoder_set_ogg_serial_number(decoder
, file_utils__ogg_serial_number
))
458 return die_s_("returned false", decoder
);
462 printf("testing FLAC__stream_decoder_set_md5_checking()... ");
463 if(!FLAC__stream_decoder_set_md5_checking(decoder
, true))
464 return die_s_("returned false", decoder
);
467 if(layer
< LAYER_FILENAME
) {
468 printf("opening %sFLAC file... ", is_ogg
? "Ogg ":"");
469 decoder_client_data
.file
= fopen(flacfilename(is_ogg
), "rb");
470 if(0 == decoder_client_data
.file
) {
471 printf("ERROR (%s)\n", strerror(errno
));
479 printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg
? "ogg_":"");
480 init_status
= is_ogg
?
481 FLAC__stream_decoder_init_ogg_stream(decoder
, stream_decoder_read_callback_
, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, &decoder_client_data
) :
482 FLAC__stream_decoder_init_stream(decoder
, stream_decoder_read_callback_
, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, &decoder_client_data
);
484 case LAYER_SEEKABLE_STREAM
:
485 printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg
? "ogg_":"");
486 init_status
= is_ogg
?
487 FLAC__stream_decoder_init_ogg_stream(decoder
, stream_decoder_read_callback_
, stream_decoder_seek_callback_
, stream_decoder_tell_callback_
, stream_decoder_length_callback_
, stream_decoder_eof_callback_
, stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, &decoder_client_data
) :
488 FLAC__stream_decoder_init_stream(decoder
, stream_decoder_read_callback_
, stream_decoder_seek_callback_
, stream_decoder_tell_callback_
, stream_decoder_length_callback_
, stream_decoder_eof_callback_
, stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, &decoder_client_data
);
491 printf("testing FLAC__stream_decoder_init_%sFILE()... ", is_ogg
? "ogg_":"");
492 init_status
= is_ogg
?
493 FLAC__stream_decoder_init_ogg_FILE(decoder
, decoder_client_data
.file
, stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, &decoder_client_data
) :
494 FLAC__stream_decoder_init_FILE(decoder
, decoder_client_data
.file
, stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, &decoder_client_data
);
497 printf("testing FLAC__stream_decoder_init_%sfile()... ", is_ogg
? "ogg_":"");
498 init_status
= is_ogg
?
499 FLAC__stream_decoder_init_ogg_file(decoder
, flacfilename(is_ogg
), stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, &decoder_client_data
) :
500 FLAC__stream_decoder_init_file(decoder
, flacfilename(is_ogg
), stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, &decoder_client_data
);
503 die_("internal error 009");
506 if(init_status
!= FLAC__STREAM_DECODER_INIT_STATUS_OK
)
507 return die_s_(0, decoder
);
510 printf("testing FLAC__stream_decoder_get_state()... ");
511 state
= FLAC__stream_decoder_get_state(decoder
);
512 printf("returned state = %u (%s)... OK\n", state
, FLAC__StreamDecoderStateString
[state
]);
514 decoder_client_data
.current_metadata_number
= 0;
515 decoder_client_data
.ignore_errors
= false;
516 decoder_client_data
.error_occurred
= false;
518 printf("testing FLAC__stream_decoder_get_md5_checking()... ");
519 if(!FLAC__stream_decoder_get_md5_checking(decoder
)) {
520 printf("FAILED, returned false, expected true\n");
525 printf("testing FLAC__stream_decoder_process_until_end_of_metadata()... ");
526 if(!FLAC__stream_decoder_process_until_end_of_metadata(decoder
))
527 return die_s_("returned false", decoder
);
530 printf("testing FLAC__stream_decoder_process_single()... ");
531 if(!FLAC__stream_decoder_process_single(decoder
))
532 return die_s_("returned false", decoder
);
535 printf("testing FLAC__stream_decoder_skip_single_frame()... ");
536 if(!FLAC__stream_decoder_skip_single_frame(decoder
))
537 return die_s_("returned false", decoder
);
540 if(layer
< LAYER_FILE
) {
541 printf("testing FLAC__stream_decoder_flush()... ");
542 if(!FLAC__stream_decoder_flush(decoder
))
543 return die_s_("returned false", decoder
);
546 decoder_client_data
.ignore_errors
= true;
547 printf("testing FLAC__stream_decoder_process_single()... ");
548 if(!FLAC__stream_decoder_process_single(decoder
))
549 return die_s_("returned false", decoder
);
551 decoder_client_data
.ignore_errors
= false;
554 expect
= (layer
!= LAYER_STREAM
);
555 printf("testing FLAC__stream_decoder_seek_absolute()... ");
556 if(FLAC__stream_decoder_seek_absolute(decoder
, 0) != expect
)
557 return die_s_(expect
? "returned false" : "returned true", decoder
);
560 printf("testing FLAC__stream_decoder_process_until_end_of_stream()... ");
561 if(!FLAC__stream_decoder_process_until_end_of_stream(decoder
))
562 return die_s_("returned false", decoder
);
565 expect
= (layer
!= LAYER_STREAM
);
566 printf("testing FLAC__stream_decoder_seek_absolute()... ");
567 if(FLAC__stream_decoder_seek_absolute(decoder
, 0) != expect
)
568 return die_s_(expect
? "returned false" : "returned true", decoder
);
571 printf("testing FLAC__stream_decoder_get_channels()... ");
573 unsigned channels
= FLAC__stream_decoder_get_channels(decoder
);
574 if(channels
!= streaminfo_
.data
.stream_info
.channels
) {
575 printf("FAILED, returned %u, expected %u\n", channels
, streaminfo_
.data
.stream_info
.channels
);
581 printf("testing FLAC__stream_decoder_get_bits_per_sample()... ");
583 unsigned bits_per_sample
= FLAC__stream_decoder_get_bits_per_sample(decoder
);
584 if(bits_per_sample
!= streaminfo_
.data
.stream_info
.bits_per_sample
) {
585 printf("FAILED, returned %u, expected %u\n", bits_per_sample
, streaminfo_
.data
.stream_info
.bits_per_sample
);
591 printf("testing FLAC__stream_decoder_get_sample_rate()... ");
593 unsigned sample_rate
= FLAC__stream_decoder_get_sample_rate(decoder
);
594 if(sample_rate
!= streaminfo_
.data
.stream_info
.sample_rate
) {
595 printf("FAILED, returned %u, expected %u\n", sample_rate
, streaminfo_
.data
.stream_info
.sample_rate
);
601 printf("testing FLAC__stream_decoder_get_blocksize()... ");
603 unsigned blocksize
= FLAC__stream_decoder_get_blocksize(decoder
);
604 /* value could be anything since we're at the last block, so accept any reasonable answer */
605 printf("returned %u... %s\n", blocksize
, blocksize
>0? "OK" : "FAILED");
610 printf("testing FLAC__stream_decoder_get_channel_assignment()... ");
612 FLAC__ChannelAssignment ca
= FLAC__stream_decoder_get_channel_assignment(decoder
);
613 printf("returned %u (%s)... OK\n", (unsigned)ca
, FLAC__ChannelAssignmentString
[ca
]);
616 if(layer
< LAYER_FILE
) {
617 printf("testing FLAC__stream_decoder_reset()... ");
618 if(!FLAC__stream_decoder_reset(decoder
)) {
619 state
= FLAC__stream_decoder_get_state(decoder
);
620 printf("FAILED, returned false, state = %u (%s)\n", state
, FLAC__StreamDecoderStateString
[state
]);
625 if(layer
== LAYER_STREAM
) {
626 /* after a reset() we have to rewind the input ourselves */
627 printf("rewinding input... ");
628 if(fseeko(decoder_client_data
.file
, 0, SEEK_SET
) < 0) {
629 printf("FAILED, errno = %d\n", errno
);
635 decoder_client_data
.current_metadata_number
= 0;
637 printf("testing FLAC__stream_decoder_process_until_end_of_stream()... ");
638 if(!FLAC__stream_decoder_process_until_end_of_stream(decoder
))
639 return die_s_("returned false", decoder
);
643 printf("testing FLAC__stream_decoder_finish()... ");
644 if(!FLAC__stream_decoder_finish(decoder
))
645 return die_s_("returned false", decoder
);
652 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
653 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder
))
654 return die_s_("returned false", decoder
);
658 if(is_ogg
) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
659 expected_metadata_sequence_
[num_expected_
++] = &streaminfo_
;
660 expected_metadata_sequence_
[num_expected_
++] = &vorbiscomment_
;
661 expected_metadata_sequence_
[num_expected_
++] = &padding_
;
662 expected_metadata_sequence_
[num_expected_
++] = &seektable_
;
663 expected_metadata_sequence_
[num_expected_
++] = &application1_
;
664 expected_metadata_sequence_
[num_expected_
++] = &application2_
;
665 expected_metadata_sequence_
[num_expected_
++] = &cuesheet_
;
666 expected_metadata_sequence_
[num_expected_
++] = &picture_
;
667 expected_metadata_sequence_
[num_expected_
++] = &unknown_
;
670 expected_metadata_sequence_
[num_expected_
++] = &streaminfo_
;
671 expected_metadata_sequence_
[num_expected_
++] = &padding_
;
672 expected_metadata_sequence_
[num_expected_
++] = &seektable_
;
673 expected_metadata_sequence_
[num_expected_
++] = &application1_
;
674 expected_metadata_sequence_
[num_expected_
++] = &application2_
;
675 expected_metadata_sequence_
[num_expected_
++] = &vorbiscomment_
;
676 expected_metadata_sequence_
[num_expected_
++] = &cuesheet_
;
677 expected_metadata_sequence_
[num_expected_
++] = &picture_
;
678 expected_metadata_sequence_
[num_expected_
++] = &unknown_
;
681 if(!stream_decoder_test_respond_(decoder
, &decoder_client_data
, is_ogg
))
688 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
689 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder
))
690 return die_s_("returned false", decoder
);
695 if(!stream_decoder_test_respond_(decoder
, &decoder_client_data
, is_ogg
))
699 * respond all, ignore VORBIS_COMMENT
702 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
703 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder
))
704 return die_s_("returned false", decoder
);
707 printf("testing FLAC__stream_decoder_set_metadata_ignore(VORBIS_COMMENT)... ");
708 if(!FLAC__stream_decoder_set_metadata_ignore(decoder
, FLAC__METADATA_TYPE_VORBIS_COMMENT
))
709 return die_s_("returned false", decoder
);
713 expected_metadata_sequence_
[num_expected_
++] = &streaminfo_
;
714 expected_metadata_sequence_
[num_expected_
++] = &padding_
;
715 expected_metadata_sequence_
[num_expected_
++] = &seektable_
;
716 expected_metadata_sequence_
[num_expected_
++] = &application1_
;
717 expected_metadata_sequence_
[num_expected_
++] = &application2_
;
718 expected_metadata_sequence_
[num_expected_
++] = &cuesheet_
;
719 expected_metadata_sequence_
[num_expected_
++] = &picture_
;
720 expected_metadata_sequence_
[num_expected_
++] = &unknown_
;
722 if(!stream_decoder_test_respond_(decoder
, &decoder_client_data
, is_ogg
))
726 * respond all, ignore APPLICATION
729 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
730 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder
))
731 return die_s_("returned false", decoder
);
734 printf("testing FLAC__stream_decoder_set_metadata_ignore(APPLICATION)... ");
735 if(!FLAC__stream_decoder_set_metadata_ignore(decoder
, FLAC__METADATA_TYPE_APPLICATION
))
736 return die_s_("returned false", decoder
);
740 if(is_ogg
) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
741 expected_metadata_sequence_
[num_expected_
++] = &streaminfo_
;
742 expected_metadata_sequence_
[num_expected_
++] = &vorbiscomment_
;
743 expected_metadata_sequence_
[num_expected_
++] = &padding_
;
744 expected_metadata_sequence_
[num_expected_
++] = &seektable_
;
745 expected_metadata_sequence_
[num_expected_
++] = &cuesheet_
;
746 expected_metadata_sequence_
[num_expected_
++] = &picture_
;
747 expected_metadata_sequence_
[num_expected_
++] = &unknown_
;
750 expected_metadata_sequence_
[num_expected_
++] = &streaminfo_
;
751 expected_metadata_sequence_
[num_expected_
++] = &padding_
;
752 expected_metadata_sequence_
[num_expected_
++] = &seektable_
;
753 expected_metadata_sequence_
[num_expected_
++] = &vorbiscomment_
;
754 expected_metadata_sequence_
[num_expected_
++] = &cuesheet_
;
755 expected_metadata_sequence_
[num_expected_
++] = &picture_
;
756 expected_metadata_sequence_
[num_expected_
++] = &unknown_
;
759 if(!stream_decoder_test_respond_(decoder
, &decoder_client_data
, is_ogg
))
763 * respond all, ignore APPLICATION id of app#1
766 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
767 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder
))
768 return die_s_("returned false", decoder
);
771 printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #1)... ");
772 if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder
, application1_
.data
.application
.id
))
773 return die_s_("returned false", decoder
);
777 if(is_ogg
) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
778 expected_metadata_sequence_
[num_expected_
++] = &streaminfo_
;
779 expected_metadata_sequence_
[num_expected_
++] = &vorbiscomment_
;
780 expected_metadata_sequence_
[num_expected_
++] = &padding_
;
781 expected_metadata_sequence_
[num_expected_
++] = &seektable_
;
782 expected_metadata_sequence_
[num_expected_
++] = &application2_
;
783 expected_metadata_sequence_
[num_expected_
++] = &cuesheet_
;
784 expected_metadata_sequence_
[num_expected_
++] = &picture_
;
785 expected_metadata_sequence_
[num_expected_
++] = &unknown_
;
788 expected_metadata_sequence_
[num_expected_
++] = &streaminfo_
;
789 expected_metadata_sequence_
[num_expected_
++] = &padding_
;
790 expected_metadata_sequence_
[num_expected_
++] = &seektable_
;
791 expected_metadata_sequence_
[num_expected_
++] = &application2_
;
792 expected_metadata_sequence_
[num_expected_
++] = &vorbiscomment_
;
793 expected_metadata_sequence_
[num_expected_
++] = &cuesheet_
;
794 expected_metadata_sequence_
[num_expected_
++] = &picture_
;
795 expected_metadata_sequence_
[num_expected_
++] = &unknown_
;
798 if(!stream_decoder_test_respond_(decoder
, &decoder_client_data
, is_ogg
))
802 * respond all, ignore APPLICATION id of app#1 & app#2
805 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
806 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder
))
807 return die_s_("returned false", decoder
);
810 printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #1)... ");
811 if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder
, application1_
.data
.application
.id
))
812 return die_s_("returned false", decoder
);
815 printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #2)... ");
816 if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder
, application2_
.data
.application
.id
))
817 return die_s_("returned false", decoder
);
821 if(is_ogg
) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
822 expected_metadata_sequence_
[num_expected_
++] = &streaminfo_
;
823 expected_metadata_sequence_
[num_expected_
++] = &vorbiscomment_
;
824 expected_metadata_sequence_
[num_expected_
++] = &padding_
;
825 expected_metadata_sequence_
[num_expected_
++] = &seektable_
;
826 expected_metadata_sequence_
[num_expected_
++] = &cuesheet_
;
827 expected_metadata_sequence_
[num_expected_
++] = &picture_
;
828 expected_metadata_sequence_
[num_expected_
++] = &unknown_
;
831 expected_metadata_sequence_
[num_expected_
++] = &streaminfo_
;
832 expected_metadata_sequence_
[num_expected_
++] = &padding_
;
833 expected_metadata_sequence_
[num_expected_
++] = &seektable_
;
834 expected_metadata_sequence_
[num_expected_
++] = &vorbiscomment_
;
835 expected_metadata_sequence_
[num_expected_
++] = &cuesheet_
;
836 expected_metadata_sequence_
[num_expected_
++] = &picture_
;
837 expected_metadata_sequence_
[num_expected_
++] = &unknown_
;
840 if(!stream_decoder_test_respond_(decoder
, &decoder_client_data
, is_ogg
))
844 * ignore all, respond VORBIS_COMMENT
847 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
848 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder
))
849 return die_s_("returned false", decoder
);
852 printf("testing FLAC__stream_decoder_set_metadata_respond(VORBIS_COMMENT)... ");
853 if(!FLAC__stream_decoder_set_metadata_respond(decoder
, FLAC__METADATA_TYPE_VORBIS_COMMENT
))
854 return die_s_("returned false", decoder
);
858 expected_metadata_sequence_
[num_expected_
++] = &vorbiscomment_
;
860 if(!stream_decoder_test_respond_(decoder
, &decoder_client_data
, is_ogg
))
864 * ignore all, respond APPLICATION
867 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
868 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder
))
869 return die_s_("returned false", decoder
);
872 printf("testing FLAC__stream_decoder_set_metadata_respond(APPLICATION)... ");
873 if(!FLAC__stream_decoder_set_metadata_respond(decoder
, FLAC__METADATA_TYPE_APPLICATION
))
874 return die_s_("returned false", decoder
);
878 expected_metadata_sequence_
[num_expected_
++] = &application1_
;
879 expected_metadata_sequence_
[num_expected_
++] = &application2_
;
881 if(!stream_decoder_test_respond_(decoder
, &decoder_client_data
, is_ogg
))
885 * ignore all, respond APPLICATION id of app#1
888 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
889 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder
))
890 return die_s_("returned false", decoder
);
893 printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #1)... ");
894 if(!FLAC__stream_decoder_set_metadata_respond_application(decoder
, application1_
.data
.application
.id
))
895 return die_s_("returned false", decoder
);
899 expected_metadata_sequence_
[num_expected_
++] = &application1_
;
901 if(!stream_decoder_test_respond_(decoder
, &decoder_client_data
, is_ogg
))
905 * ignore all, respond APPLICATION id of app#1 & app#2
908 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
909 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder
))
910 return die_s_("returned false", decoder
);
913 printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #1)... ");
914 if(!FLAC__stream_decoder_set_metadata_respond_application(decoder
, application1_
.data
.application
.id
))
915 return die_s_("returned false", decoder
);
918 printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #2)... ");
919 if(!FLAC__stream_decoder_set_metadata_respond_application(decoder
, application2_
.data
.application
.id
))
920 return die_s_("returned false", decoder
);
924 expected_metadata_sequence_
[num_expected_
++] = &application1_
;
925 expected_metadata_sequence_
[num_expected_
++] = &application2_
;
927 if(!stream_decoder_test_respond_(decoder
, &decoder_client_data
, is_ogg
))
931 * respond all, ignore APPLICATION, respond APPLICATION id of app#1
934 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
935 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder
))
936 return die_s_("returned false", decoder
);
939 printf("testing FLAC__stream_decoder_set_metadata_ignore(APPLICATION)... ");
940 if(!FLAC__stream_decoder_set_metadata_ignore(decoder
, FLAC__METADATA_TYPE_APPLICATION
))
941 return die_s_("returned false", decoder
);
944 printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #1)... ");
945 if(!FLAC__stream_decoder_set_metadata_respond_application(decoder
, application1_
.data
.application
.id
))
946 return die_s_("returned false", decoder
);
950 if(is_ogg
) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
951 expected_metadata_sequence_
[num_expected_
++] = &streaminfo_
;
952 expected_metadata_sequence_
[num_expected_
++] = &vorbiscomment_
;
953 expected_metadata_sequence_
[num_expected_
++] = &padding_
;
954 expected_metadata_sequence_
[num_expected_
++] = &seektable_
;
955 expected_metadata_sequence_
[num_expected_
++] = &application1_
;
956 expected_metadata_sequence_
[num_expected_
++] = &cuesheet_
;
957 expected_metadata_sequence_
[num_expected_
++] = &picture_
;
958 expected_metadata_sequence_
[num_expected_
++] = &unknown_
;
961 expected_metadata_sequence_
[num_expected_
++] = &streaminfo_
;
962 expected_metadata_sequence_
[num_expected_
++] = &padding_
;
963 expected_metadata_sequence_
[num_expected_
++] = &seektable_
;
964 expected_metadata_sequence_
[num_expected_
++] = &application1_
;
965 expected_metadata_sequence_
[num_expected_
++] = &vorbiscomment_
;
966 expected_metadata_sequence_
[num_expected_
++] = &cuesheet_
;
967 expected_metadata_sequence_
[num_expected_
++] = &picture_
;
968 expected_metadata_sequence_
[num_expected_
++] = &unknown_
;
971 if(!stream_decoder_test_respond_(decoder
, &decoder_client_data
, is_ogg
))
975 * ignore all, respond APPLICATION, ignore APPLICATION id of app#1
978 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
979 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder
))
980 return die_s_("returned false", decoder
);
983 printf("testing FLAC__stream_decoder_set_metadata_respond(APPLICATION)... ");
984 if(!FLAC__stream_decoder_set_metadata_respond(decoder
, FLAC__METADATA_TYPE_APPLICATION
))
985 return die_s_("returned false", decoder
);
988 printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #1)... ");
989 if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder
, application1_
.data
.application
.id
))
990 return die_s_("returned false", decoder
);
994 expected_metadata_sequence_
[num_expected_
++] = &application2_
;
996 if(!stream_decoder_test_respond_(decoder
, &decoder_client_data
, is_ogg
))
999 if(layer
< LAYER_FILE
) /* for LAYER_FILE, FLAC__stream_decoder_finish() closes the file */
1000 fclose(decoder_client_data
.file
);
1002 printf("testing FLAC__stream_decoder_delete()... ");
1003 FLAC__stream_decoder_delete(decoder
);
1006 printf("\nPASSED!\n");
1011 FLAC__bool
test_decoders(void)
1013 FLAC__bool is_ogg
= false;
1016 init_metadata_blocks_();
1018 if(!generate_file_(is_ogg
))
1021 if(!test_stream_decoder(LAYER_STREAM
, is_ogg
))
1024 if(!test_stream_decoder(LAYER_SEEKABLE_STREAM
, is_ogg
))
1027 if(!test_stream_decoder(LAYER_FILE
, is_ogg
))
1030 if(!test_stream_decoder(LAYER_FILENAME
, is_ogg
))
1033 (void) grabbag__file_remove_file(flacfilename(is_ogg
));
1035 free_metadata_blocks_();
1037 if(!FLAC_API_SUPPORTS_OGG_FLAC
|| is_ogg
)