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 "share/safe_str.h"
33 #include "test_libs_common/file_utils_flac.h"
34 #include "test_libs_common/metadata_utils.h"
37 LAYER_STREAM
= 0, /* FLAC__stream_decoder_init_[ogg_]stream() without seeking */
38 LAYER_SEEKABLE_STREAM
, /* FLAC__stream_decoder_init_[ogg_]stream() with seeking */
39 LAYER_FILE
, /* FLAC__stream_decoder_init_[ogg_]FILE() */
40 LAYER_FILENAME
/* FLAC__stream_decoder_init_[ogg_]file() */
43 static const char * const LayerString
[] = {
54 unsigned current_metadata_number
;
55 FLAC__bool ignore_errors
;
56 FLAC__bool error_occurred
;
57 } StreamDecoderClientData
;
59 static FLAC__StreamMetadata streaminfo_
, padding_
, seektable_
, application1_
, application2_
, vorbiscomment_
, cuesheet_
, picture_
, unknown_
;
60 static FLAC__StreamMetadata
*expected_metadata_sequence_
[9];
61 static unsigned num_expected_
;
62 static FLAC__off_t flacfilesize_
;
64 static const char *flacfilename(FLAC__bool is_ogg
)
66 return is_ogg
? "metadata.oga" : "metadata.flac";
69 static FLAC__bool
die_(const char *msg
)
71 printf("ERROR: %s\n", msg
);
75 static FLAC__bool
die_s_(const char *msg
, const FLAC__StreamDecoder
*decoder
)
77 FLAC__StreamDecoderState state
= FLAC__stream_decoder_get_state(decoder
);
80 printf("FAILED, %s", msg
);
84 printf(", state = %u (%s)\n", (unsigned)state
, FLAC__StreamDecoderStateString
[state
]);
89 static void open_test_file(StreamDecoderClientData
* pdcd
, int is_ogg
, const char * mode
)
91 pdcd
->file
= fopen(flacfilename(is_ogg
), mode
);
92 safe_strncpy(pdcd
->filename
, flacfilename(is_ogg
), sizeof (pdcd
->filename
));
95 static void init_metadata_blocks_(void)
97 mutils__init_metadata_blocks(&streaminfo_
, &padding_
, &seektable_
, &application1_
, &application2_
, &vorbiscomment_
, &cuesheet_
, &picture_
, &unknown_
);
100 static void free_metadata_blocks_(void)
102 mutils__free_metadata_blocks(&streaminfo_
, &padding_
, &seektable_
, &application1_
, &application2_
, &vorbiscomment_
, &cuesheet_
, &picture_
, &unknown_
);
105 static FLAC__bool
generate_file_(FLAC__bool is_ogg
)
107 printf("\n\ngenerating %sFLAC file for decoder tests...\n", is_ogg
? "Ogg ":"");
110 expected_metadata_sequence_
[num_expected_
++] = &padding_
;
111 expected_metadata_sequence_
[num_expected_
++] = &seektable_
;
112 expected_metadata_sequence_
[num_expected_
++] = &application1_
;
113 expected_metadata_sequence_
[num_expected_
++] = &application2_
;
114 expected_metadata_sequence_
[num_expected_
++] = &vorbiscomment_
;
115 expected_metadata_sequence_
[num_expected_
++] = &cuesheet_
;
116 expected_metadata_sequence_
[num_expected_
++] = &picture_
;
117 expected_metadata_sequence_
[num_expected_
++] = &unknown_
;
118 /* WATCHOUT: for Ogg FLAC the encoder should move the VORBIS_COMMENT block to the front, right after STREAMINFO */
120 if(!file_utils__generate_flacfile(is_ogg
, flacfilename(is_ogg
), &flacfilesize_
, 512 * 1024, &streaminfo_
, expected_metadata_sequence_
, num_expected_
))
121 return die_("creating the encoded file");
126 static FLAC__StreamDecoderReadStatus
stream_decoder_read_callback_(const FLAC__StreamDecoder
*decoder
, FLAC__byte buffer
[], size_t *bytes
, void *client_data
)
128 StreamDecoderClientData
*dcd
= (StreamDecoderClientData
*)client_data
;
129 const size_t requested_bytes
= *bytes
;
134 printf("ERROR: client_data in read callback is NULL\n");
135 return FLAC__STREAM_DECODER_READ_STATUS_ABORT
;
138 if(dcd
->error_occurred
)
139 return FLAC__STREAM_DECODER_READ_STATUS_ABORT
;
141 if(feof(dcd
->file
)) {
143 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM
;
145 else if(requested_bytes
> 0) {
146 *bytes
= fread(buffer
, 1, requested_bytes
, dcd
->file
);
149 return FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM
;
151 return FLAC__STREAM_DECODER_READ_STATUS_ABORT
;
154 return FLAC__STREAM_DECODER_READ_STATUS_CONTINUE
;
158 return FLAC__STREAM_DECODER_READ_STATUS_ABORT
; /* abort to avoid a deadlock */
161 static FLAC__StreamDecoderSeekStatus
stream_decoder_seek_callback_(const FLAC__StreamDecoder
*decoder
, FLAC__uint64 absolute_byte_offset
, void *client_data
)
163 StreamDecoderClientData
*dcd
= (StreamDecoderClientData
*)client_data
;
168 printf("ERROR: client_data in seek callback is NULL\n");
169 return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR
;
172 if(dcd
->error_occurred
)
173 return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR
;
175 if(fseeko(dcd
->file
, (FLAC__off_t
)absolute_byte_offset
, SEEK_SET
) < 0) {
176 dcd
->error_occurred
= true;
177 return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR
;
180 return FLAC__STREAM_DECODER_SEEK_STATUS_OK
;
183 static FLAC__StreamDecoderTellStatus
stream_decoder_tell_callback_(const FLAC__StreamDecoder
*decoder
, FLAC__uint64
*absolute_byte_offset
, void *client_data
)
185 StreamDecoderClientData
*dcd
= (StreamDecoderClientData
*)client_data
;
191 printf("ERROR: client_data in tell callback is NULL\n");
192 return FLAC__STREAM_DECODER_TELL_STATUS_ERROR
;
195 if(dcd
->error_occurred
)
196 return FLAC__STREAM_DECODER_TELL_STATUS_ERROR
;
198 offset
= ftello(dcd
->file
);
199 *absolute_byte_offset
= (FLAC__uint64
)offset
;
202 dcd
->error_occurred
= true;
203 return FLAC__STREAM_DECODER_TELL_STATUS_ERROR
;
206 return FLAC__STREAM_DECODER_TELL_STATUS_OK
;
209 static FLAC__StreamDecoderLengthStatus
stream_decoder_length_callback_(const FLAC__StreamDecoder
*decoder
, FLAC__uint64
*stream_length
, void *client_data
)
211 StreamDecoderClientData
*dcd
= (StreamDecoderClientData
*)client_data
;
216 printf("ERROR: client_data in length callback is NULL\n");
217 return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR
;
220 if(dcd
->error_occurred
)
221 return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR
;
223 *stream_length
= (FLAC__uint64
)flacfilesize_
;
224 return FLAC__STREAM_DECODER_LENGTH_STATUS_OK
;
227 static FLAC__bool
stream_decoder_eof_callback_(const FLAC__StreamDecoder
*decoder
, void *client_data
)
229 StreamDecoderClientData
*dcd
= (StreamDecoderClientData
*)client_data
;
234 printf("ERROR: client_data in eof callback is NULL\n");
238 if(dcd
->error_occurred
)
241 return feof(dcd
->file
);
244 static FLAC__StreamDecoderWriteStatus
stream_decoder_write_callback_(const FLAC__StreamDecoder
*decoder
, const FLAC__Frame
*frame
, const FLAC__int32
* const buffer
[], void *client_data
)
246 StreamDecoderClientData
*dcd
= (StreamDecoderClientData
*)client_data
;
248 (void)decoder
, (void)buffer
;
251 printf("ERROR: client_data in write callback is NULL\n");
252 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT
;
255 if(dcd
->error_occurred
)
256 return FLAC__STREAM_DECODER_WRITE_STATUS_ABORT
;
259 (frame
->header
.number_type
== FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER
&& frame
->header
.number
.frame_number
== 0) ||
260 (frame
->header
.number_type
== FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER
&& frame
->header
.number
.sample_number
== 0)
262 printf("content... ");
266 return FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE
;
269 static void stream_decoder_metadata_callback_(const FLAC__StreamDecoder
*decoder
, const FLAC__StreamMetadata
*metadata
, void *client_data
)
271 StreamDecoderClientData
*dcd
= (StreamDecoderClientData
*)client_data
;
276 printf("ERROR: client_data in metadata callback is NULL\n");
280 if(dcd
->error_occurred
)
283 printf("%d... ", dcd
->current_metadata_number
);
286 if(dcd
->current_metadata_number
>= num_expected_
) {
287 (void)die_("got more metadata blocks than expected");
288 dcd
->error_occurred
= true;
291 if(!mutils__compare_block(expected_metadata_sequence_
[dcd
->current_metadata_number
], metadata
)) {
292 (void)die_("metadata block mismatch");
293 dcd
->error_occurred
= true;
296 dcd
->current_metadata_number
++;
299 static void stream_decoder_error_callback_(const FLAC__StreamDecoder
*decoder
, FLAC__StreamDecoderErrorStatus status
, void *client_data
)
301 StreamDecoderClientData
*dcd
= (StreamDecoderClientData
*)client_data
;
306 printf("ERROR: client_data in error callback is NULL\n");
310 if(!dcd
->ignore_errors
) {
311 printf("ERROR: got error callback: err = %u (%s)\n", (unsigned)status
, FLAC__StreamDecoderErrorStatusString
[status
]);
312 dcd
->error_occurred
= true;
316 static FLAC__bool
stream_decoder_test_respond_(FLAC__StreamDecoder
*decoder
, StreamDecoderClientData
*dcd
, FLAC__bool is_ogg
)
318 FLAC__StreamDecoderInitStatus init_status
;
320 if(!FLAC__stream_decoder_set_md5_checking(decoder
, true))
321 return die_s_("at FLAC__stream_decoder_set_md5_checking(), returned false", decoder
);
323 /* for FLAC__stream_encoder_init_FILE(), the FLAC__stream_encoder_finish() closes the file so we have to keep re-opening: */
324 if(dcd
->layer
== LAYER_FILE
) {
325 printf("opening %sFLAC file... ", is_ogg
? "Ogg ":"");
326 open_test_file(dcd
, is_ogg
, "rb");
328 printf("ERROR (%s)\n", strerror(errno
));
336 printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg
? "ogg_":"");
337 init_status
= is_ogg
?
338 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
) :
339 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
)
342 case LAYER_SEEKABLE_STREAM
:
343 printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg
? "ogg_":"");
344 init_status
= is_ogg
?
345 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
) :
346 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
);
349 printf("testing FLAC__stream_decoder_init_%sFILE()... ", is_ogg
? "ogg_":"");
350 init_status
= is_ogg
?
351 FLAC__stream_decoder_init_ogg_FILE(decoder
, dcd
->file
, stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, dcd
) :
352 FLAC__stream_decoder_init_FILE(decoder
, dcd
->file
, stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, dcd
);
355 printf("testing FLAC__stream_decoder_init_%sfile()... ", is_ogg
? "ogg_":"");
356 init_status
= is_ogg
?
357 FLAC__stream_decoder_init_ogg_file(decoder
, flacfilename(is_ogg
), stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, dcd
) :
358 FLAC__stream_decoder_init_file(decoder
, flacfilename(is_ogg
), stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, dcd
);
361 die_("internal error 000");
364 if(init_status
!= FLAC__STREAM_DECODER_INIT_STATUS_OK
)
365 return die_s_(0, decoder
);
368 dcd
->current_metadata_number
= 0;
370 if(dcd
->layer
< LAYER_FILE
&& fseeko(dcd
->file
, 0, SEEK_SET
) < 0) {
371 printf("FAILED rewinding input, errno = %d\n", errno
);
375 printf("testing FLAC__stream_decoder_process_until_end_of_stream()... ");
376 if(!FLAC__stream_decoder_process_until_end_of_stream(decoder
))
377 return die_s_("returned false", decoder
);
380 printf("testing FLAC__stream_decoder_finish()... ");
381 if(!FLAC__stream_decoder_finish(decoder
))
382 return die_s_("returned false", decoder
);
388 static FLAC__bool
test_stream_decoder(Layer layer
, FLAC__bool is_ogg
)
390 FLAC__StreamDecoder
*decoder
;
391 FLAC__StreamDecoderInitStatus init_status
;
392 FLAC__StreamDecoderState state
;
393 StreamDecoderClientData decoder_client_data
;
396 decoder_client_data
.layer
= layer
;
398 printf("\n+++ libFLAC unit test: FLAC__StreamDecoder (layer: %s, format: %s)\n\n", LayerString
[layer
], is_ogg
? "Ogg FLAC" : "FLAC");
400 printf("testing FLAC__stream_decoder_new()... ");
401 decoder
= FLAC__stream_decoder_new();
403 printf("FAILED, returned NULL\n");
408 printf("testing FLAC__stream_decoder_delete()... ");
409 FLAC__stream_decoder_delete(decoder
);
412 printf("testing FLAC__stream_decoder_new()... ");
413 decoder
= FLAC__stream_decoder_new();
415 printf("FAILED, returned NULL\n");
422 case LAYER_SEEKABLE_STREAM
:
423 printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg
? "ogg_":"");
424 init_status
= is_ogg
?
425 FLAC__stream_decoder_init_ogg_stream(decoder
, 0, 0, 0, 0, 0, 0, 0, 0, 0) :
426 FLAC__stream_decoder_init_stream(decoder
, 0, 0, 0, 0, 0, 0, 0, 0, 0);
429 printf("testing FLAC__stream_decoder_init_%sFILE()... ", is_ogg
? "ogg_":"");
430 init_status
= is_ogg
?
431 FLAC__stream_decoder_init_ogg_FILE(decoder
, stdin
, 0, 0, 0, 0) :
432 FLAC__stream_decoder_init_FILE(decoder
, stdin
, 0, 0, 0, 0);
435 printf("testing FLAC__stream_decoder_init_%sfile()... ", is_ogg
? "ogg_":"");
436 init_status
= is_ogg
?
437 FLAC__stream_decoder_init_ogg_file(decoder
, flacfilename(is_ogg
), 0, 0, 0, 0) :
438 FLAC__stream_decoder_init_file(decoder
, flacfilename(is_ogg
), 0, 0, 0, 0);
441 die_("internal error 003");
444 if(init_status
!= FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS
)
445 return die_s_(0, decoder
);
448 printf("testing FLAC__stream_decoder_delete()... ");
449 FLAC__stream_decoder_delete(decoder
);
453 expected_metadata_sequence_
[num_expected_
++] = &streaminfo_
;
455 printf("testing FLAC__stream_decoder_new()... ");
456 decoder
= FLAC__stream_decoder_new();
458 printf("FAILED, returned NULL\n");
464 printf("testing FLAC__stream_decoder_set_ogg_serial_number()... ");
465 if(!FLAC__stream_decoder_set_ogg_serial_number(decoder
, file_utils__ogg_serial_number
))
466 return die_s_("returned false", decoder
);
470 printf("testing FLAC__stream_decoder_set_md5_checking()... ");
471 if(!FLAC__stream_decoder_set_md5_checking(decoder
, true))
472 return die_s_("returned false", decoder
);
475 if(layer
< LAYER_FILENAME
) {
476 printf("opening %sFLAC file... ", is_ogg
? "Ogg ":"");
477 open_test_file(&decoder_client_data
, is_ogg
, "rb");
478 if(0 == decoder_client_data
.file
) {
479 printf("ERROR (%s)\n", strerror(errno
));
487 printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg
? "ogg_":"");
488 init_status
= is_ogg
?
489 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
) :
490 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
);
492 case LAYER_SEEKABLE_STREAM
:
493 printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg
? "ogg_":"");
494 init_status
= is_ogg
?
495 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
) :
496 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
);
499 printf("testing FLAC__stream_decoder_init_%sFILE()... ", is_ogg
? "ogg_":"");
500 init_status
= is_ogg
?
501 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
) :
502 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
);
505 printf("testing FLAC__stream_decoder_init_%sfile()... ", is_ogg
? "ogg_":"");
506 init_status
= is_ogg
?
507 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
) :
508 FLAC__stream_decoder_init_file(decoder
, flacfilename(is_ogg
), stream_decoder_write_callback_
, stream_decoder_metadata_callback_
, stream_decoder_error_callback_
, &decoder_client_data
);
511 die_("internal error 009");
514 if(init_status
!= FLAC__STREAM_DECODER_INIT_STATUS_OK
)
515 return die_s_(0, decoder
);
518 printf("testing FLAC__stream_decoder_get_state()... ");
519 state
= FLAC__stream_decoder_get_state(decoder
);
520 printf("returned state = %u (%s)... OK\n", state
, FLAC__StreamDecoderStateString
[state
]);
522 decoder_client_data
.current_metadata_number
= 0;
523 decoder_client_data
.ignore_errors
= false;
524 decoder_client_data
.error_occurred
= false;
526 printf("testing FLAC__stream_decoder_get_md5_checking()... ");
527 if(!FLAC__stream_decoder_get_md5_checking(decoder
)) {
528 printf("FAILED, returned false, expected true\n");
533 printf("testing FLAC__stream_decoder_process_until_end_of_metadata()... ");
534 if(!FLAC__stream_decoder_process_until_end_of_metadata(decoder
))
535 return die_s_("returned false", decoder
);
538 printf("testing FLAC__stream_decoder_process_single()... ");
539 if(!FLAC__stream_decoder_process_single(decoder
))
540 return die_s_("returned false", decoder
);
543 printf("testing FLAC__stream_decoder_skip_single_frame()... ");
544 if(!FLAC__stream_decoder_skip_single_frame(decoder
))
545 return die_s_("returned false", decoder
);
548 if(layer
< LAYER_FILE
) {
549 printf("testing FLAC__stream_decoder_flush()... ");
550 if(!FLAC__stream_decoder_flush(decoder
))
551 return die_s_("returned false", decoder
);
554 decoder_client_data
.ignore_errors
= true;
555 printf("testing FLAC__stream_decoder_process_single()... ");
556 if(!FLAC__stream_decoder_process_single(decoder
))
557 return die_s_("returned false", decoder
);
559 decoder_client_data
.ignore_errors
= false;
562 expect
= (layer
!= LAYER_STREAM
);
563 printf("testing FLAC__stream_decoder_seek_absolute()... ");
564 if(FLAC__stream_decoder_seek_absolute(decoder
, 0) != expect
)
565 return die_s_(expect
? "returned false" : "returned true", decoder
);
568 printf("testing FLAC__stream_decoder_process_until_end_of_stream()... ");
569 if(!FLAC__stream_decoder_process_until_end_of_stream(decoder
))
570 return die_s_("returned false", decoder
);
573 expect
= (layer
!= LAYER_STREAM
);
574 printf("testing FLAC__stream_decoder_seek_absolute()... ");
575 if(FLAC__stream_decoder_seek_absolute(decoder
, 0) != expect
)
576 return die_s_(expect
? "returned false" : "returned true", decoder
);
579 printf("testing FLAC__stream_decoder_get_channels()... ");
581 unsigned channels
= FLAC__stream_decoder_get_channels(decoder
);
582 if(channels
!= streaminfo_
.data
.stream_info
.channels
) {
583 printf("FAILED, returned %u, expected %u\n", channels
, streaminfo_
.data
.stream_info
.channels
);
589 printf("testing FLAC__stream_decoder_get_bits_per_sample()... ");
591 unsigned bits_per_sample
= FLAC__stream_decoder_get_bits_per_sample(decoder
);
592 if(bits_per_sample
!= streaminfo_
.data
.stream_info
.bits_per_sample
) {
593 printf("FAILED, returned %u, expected %u\n", bits_per_sample
, streaminfo_
.data
.stream_info
.bits_per_sample
);
599 printf("testing FLAC__stream_decoder_get_sample_rate()... ");
601 unsigned sample_rate
= FLAC__stream_decoder_get_sample_rate(decoder
);
602 if(sample_rate
!= streaminfo_
.data
.stream_info
.sample_rate
) {
603 printf("FAILED, returned %u, expected %u\n", sample_rate
, streaminfo_
.data
.stream_info
.sample_rate
);
609 printf("testing FLAC__stream_decoder_get_blocksize()... ");
611 unsigned blocksize
= FLAC__stream_decoder_get_blocksize(decoder
);
612 /* value could be anything since we're at the last block, so accept any reasonable answer */
613 printf("returned %u... %s\n", blocksize
, blocksize
>0? "OK" : "FAILED");
618 printf("testing FLAC__stream_decoder_get_channel_assignment()... ");
620 FLAC__ChannelAssignment ca
= FLAC__stream_decoder_get_channel_assignment(decoder
);
621 printf("returned %u (%s)... OK\n", (unsigned)ca
, FLAC__ChannelAssignmentString
[ca
]);
624 if(layer
< LAYER_FILE
) {
625 printf("testing FLAC__stream_decoder_reset()... ");
626 if(!FLAC__stream_decoder_reset(decoder
)) {
627 state
= FLAC__stream_decoder_get_state(decoder
);
628 printf("FAILED, returned false, state = %u (%s)\n", state
, FLAC__StreamDecoderStateString
[state
]);
633 if(layer
== LAYER_STREAM
) {
634 /* after a reset() we have to rewind the input ourselves */
635 printf("rewinding input... ");
636 if(fseeko(decoder_client_data
.file
, 0, SEEK_SET
) < 0) {
637 printf("FAILED, errno = %d\n", errno
);
643 decoder_client_data
.current_metadata_number
= 0;
645 printf("testing FLAC__stream_decoder_process_until_end_of_stream()... ");
646 if(!FLAC__stream_decoder_process_until_end_of_stream(decoder
))
647 return die_s_("returned false", decoder
);
651 printf("testing FLAC__stream_decoder_finish()... ");
652 if(!FLAC__stream_decoder_finish(decoder
))
653 return die_s_("returned false", decoder
);
660 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
661 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder
))
662 return die_s_("returned false", decoder
);
666 if(is_ogg
) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
667 expected_metadata_sequence_
[num_expected_
++] = &streaminfo_
;
668 expected_metadata_sequence_
[num_expected_
++] = &vorbiscomment_
;
669 expected_metadata_sequence_
[num_expected_
++] = &padding_
;
670 expected_metadata_sequence_
[num_expected_
++] = &seektable_
;
671 expected_metadata_sequence_
[num_expected_
++] = &application1_
;
672 expected_metadata_sequence_
[num_expected_
++] = &application2_
;
673 expected_metadata_sequence_
[num_expected_
++] = &cuesheet_
;
674 expected_metadata_sequence_
[num_expected_
++] = &picture_
;
675 expected_metadata_sequence_
[num_expected_
++] = &unknown_
;
678 expected_metadata_sequence_
[num_expected_
++] = &streaminfo_
;
679 expected_metadata_sequence_
[num_expected_
++] = &padding_
;
680 expected_metadata_sequence_
[num_expected_
++] = &seektable_
;
681 expected_metadata_sequence_
[num_expected_
++] = &application1_
;
682 expected_metadata_sequence_
[num_expected_
++] = &application2_
;
683 expected_metadata_sequence_
[num_expected_
++] = &vorbiscomment_
;
684 expected_metadata_sequence_
[num_expected_
++] = &cuesheet_
;
685 expected_metadata_sequence_
[num_expected_
++] = &picture_
;
686 expected_metadata_sequence_
[num_expected_
++] = &unknown_
;
689 if(!stream_decoder_test_respond_(decoder
, &decoder_client_data
, is_ogg
))
696 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
697 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder
))
698 return die_s_("returned false", decoder
);
703 if(!stream_decoder_test_respond_(decoder
, &decoder_client_data
, is_ogg
))
707 * respond all, ignore VORBIS_COMMENT
710 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
711 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder
))
712 return die_s_("returned false", decoder
);
715 printf("testing FLAC__stream_decoder_set_metadata_ignore(VORBIS_COMMENT)... ");
716 if(!FLAC__stream_decoder_set_metadata_ignore(decoder
, FLAC__METADATA_TYPE_VORBIS_COMMENT
))
717 return die_s_("returned false", decoder
);
721 expected_metadata_sequence_
[num_expected_
++] = &streaminfo_
;
722 expected_metadata_sequence_
[num_expected_
++] = &padding_
;
723 expected_metadata_sequence_
[num_expected_
++] = &seektable_
;
724 expected_metadata_sequence_
[num_expected_
++] = &application1_
;
725 expected_metadata_sequence_
[num_expected_
++] = &application2_
;
726 expected_metadata_sequence_
[num_expected_
++] = &cuesheet_
;
727 expected_metadata_sequence_
[num_expected_
++] = &picture_
;
728 expected_metadata_sequence_
[num_expected_
++] = &unknown_
;
730 if(!stream_decoder_test_respond_(decoder
, &decoder_client_data
, is_ogg
))
734 * respond all, ignore APPLICATION
737 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
738 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder
))
739 return die_s_("returned false", decoder
);
742 printf("testing FLAC__stream_decoder_set_metadata_ignore(APPLICATION)... ");
743 if(!FLAC__stream_decoder_set_metadata_ignore(decoder
, FLAC__METADATA_TYPE_APPLICATION
))
744 return die_s_("returned false", decoder
);
748 if(is_ogg
) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
749 expected_metadata_sequence_
[num_expected_
++] = &streaminfo_
;
750 expected_metadata_sequence_
[num_expected_
++] = &vorbiscomment_
;
751 expected_metadata_sequence_
[num_expected_
++] = &padding_
;
752 expected_metadata_sequence_
[num_expected_
++] = &seektable_
;
753 expected_metadata_sequence_
[num_expected_
++] = &cuesheet_
;
754 expected_metadata_sequence_
[num_expected_
++] = &picture_
;
755 expected_metadata_sequence_
[num_expected_
++] = &unknown_
;
758 expected_metadata_sequence_
[num_expected_
++] = &streaminfo_
;
759 expected_metadata_sequence_
[num_expected_
++] = &padding_
;
760 expected_metadata_sequence_
[num_expected_
++] = &seektable_
;
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_
;
767 if(!stream_decoder_test_respond_(decoder
, &decoder_client_data
, is_ogg
))
771 * respond all, ignore APPLICATION id of app#1
774 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
775 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder
))
776 return die_s_("returned false", decoder
);
779 printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #1)... ");
780 if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder
, application1_
.data
.application
.id
))
781 return die_s_("returned false", decoder
);
785 if(is_ogg
) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
786 expected_metadata_sequence_
[num_expected_
++] = &streaminfo_
;
787 expected_metadata_sequence_
[num_expected_
++] = &vorbiscomment_
;
788 expected_metadata_sequence_
[num_expected_
++] = &padding_
;
789 expected_metadata_sequence_
[num_expected_
++] = &seektable_
;
790 expected_metadata_sequence_
[num_expected_
++] = &application2_
;
791 expected_metadata_sequence_
[num_expected_
++] = &cuesheet_
;
792 expected_metadata_sequence_
[num_expected_
++] = &picture_
;
793 expected_metadata_sequence_
[num_expected_
++] = &unknown_
;
796 expected_metadata_sequence_
[num_expected_
++] = &streaminfo_
;
797 expected_metadata_sequence_
[num_expected_
++] = &padding_
;
798 expected_metadata_sequence_
[num_expected_
++] = &seektable_
;
799 expected_metadata_sequence_
[num_expected_
++] = &application2_
;
800 expected_metadata_sequence_
[num_expected_
++] = &vorbiscomment_
;
801 expected_metadata_sequence_
[num_expected_
++] = &cuesheet_
;
802 expected_metadata_sequence_
[num_expected_
++] = &picture_
;
803 expected_metadata_sequence_
[num_expected_
++] = &unknown_
;
806 if(!stream_decoder_test_respond_(decoder
, &decoder_client_data
, is_ogg
))
810 * respond all, ignore APPLICATION id of app#1 & app#2
813 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
814 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder
))
815 return die_s_("returned false", decoder
);
818 printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #1)... ");
819 if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder
, application1_
.data
.application
.id
))
820 return die_s_("returned false", decoder
);
823 printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #2)... ");
824 if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder
, application2_
.data
.application
.id
))
825 return die_s_("returned false", decoder
);
829 if(is_ogg
) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
830 expected_metadata_sequence_
[num_expected_
++] = &streaminfo_
;
831 expected_metadata_sequence_
[num_expected_
++] = &vorbiscomment_
;
832 expected_metadata_sequence_
[num_expected_
++] = &padding_
;
833 expected_metadata_sequence_
[num_expected_
++] = &seektable_
;
834 expected_metadata_sequence_
[num_expected_
++] = &cuesheet_
;
835 expected_metadata_sequence_
[num_expected_
++] = &picture_
;
836 expected_metadata_sequence_
[num_expected_
++] = &unknown_
;
839 expected_metadata_sequence_
[num_expected_
++] = &streaminfo_
;
840 expected_metadata_sequence_
[num_expected_
++] = &padding_
;
841 expected_metadata_sequence_
[num_expected_
++] = &seektable_
;
842 expected_metadata_sequence_
[num_expected_
++] = &vorbiscomment_
;
843 expected_metadata_sequence_
[num_expected_
++] = &cuesheet_
;
844 expected_metadata_sequence_
[num_expected_
++] = &picture_
;
845 expected_metadata_sequence_
[num_expected_
++] = &unknown_
;
848 if(!stream_decoder_test_respond_(decoder
, &decoder_client_data
, is_ogg
))
852 * ignore all, respond VORBIS_COMMENT
855 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
856 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder
))
857 return die_s_("returned false", decoder
);
860 printf("testing FLAC__stream_decoder_set_metadata_respond(VORBIS_COMMENT)... ");
861 if(!FLAC__stream_decoder_set_metadata_respond(decoder
, FLAC__METADATA_TYPE_VORBIS_COMMENT
))
862 return die_s_("returned false", decoder
);
866 expected_metadata_sequence_
[num_expected_
++] = &vorbiscomment_
;
868 if(!stream_decoder_test_respond_(decoder
, &decoder_client_data
, is_ogg
))
872 * ignore all, respond APPLICATION
875 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
876 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder
))
877 return die_s_("returned false", decoder
);
880 printf("testing FLAC__stream_decoder_set_metadata_respond(APPLICATION)... ");
881 if(!FLAC__stream_decoder_set_metadata_respond(decoder
, FLAC__METADATA_TYPE_APPLICATION
))
882 return die_s_("returned false", decoder
);
886 expected_metadata_sequence_
[num_expected_
++] = &application1_
;
887 expected_metadata_sequence_
[num_expected_
++] = &application2_
;
889 if(!stream_decoder_test_respond_(decoder
, &decoder_client_data
, is_ogg
))
893 * ignore all, respond APPLICATION id of app#1
896 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
897 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder
))
898 return die_s_("returned false", decoder
);
901 printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #1)... ");
902 if(!FLAC__stream_decoder_set_metadata_respond_application(decoder
, application1_
.data
.application
.id
))
903 return die_s_("returned false", decoder
);
907 expected_metadata_sequence_
[num_expected_
++] = &application1_
;
909 if(!stream_decoder_test_respond_(decoder
, &decoder_client_data
, is_ogg
))
913 * ignore all, respond APPLICATION id of app#1 & app#2
916 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
917 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder
))
918 return die_s_("returned false", decoder
);
921 printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #1)... ");
922 if(!FLAC__stream_decoder_set_metadata_respond_application(decoder
, application1_
.data
.application
.id
))
923 return die_s_("returned false", decoder
);
926 printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #2)... ");
927 if(!FLAC__stream_decoder_set_metadata_respond_application(decoder
, application2_
.data
.application
.id
))
928 return die_s_("returned false", decoder
);
932 expected_metadata_sequence_
[num_expected_
++] = &application1_
;
933 expected_metadata_sequence_
[num_expected_
++] = &application2_
;
935 if(!stream_decoder_test_respond_(decoder
, &decoder_client_data
, is_ogg
))
939 * respond all, ignore APPLICATION, respond APPLICATION id of app#1
942 printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
943 if(!FLAC__stream_decoder_set_metadata_respond_all(decoder
))
944 return die_s_("returned false", decoder
);
947 printf("testing FLAC__stream_decoder_set_metadata_ignore(APPLICATION)... ");
948 if(!FLAC__stream_decoder_set_metadata_ignore(decoder
, FLAC__METADATA_TYPE_APPLICATION
))
949 return die_s_("returned false", decoder
);
952 printf("testing FLAC__stream_decoder_set_metadata_respond_application(of app block #1)... ");
953 if(!FLAC__stream_decoder_set_metadata_respond_application(decoder
, application1_
.data
.application
.id
))
954 return die_s_("returned false", decoder
);
958 if(is_ogg
) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
959 expected_metadata_sequence_
[num_expected_
++] = &streaminfo_
;
960 expected_metadata_sequence_
[num_expected_
++] = &vorbiscomment_
;
961 expected_metadata_sequence_
[num_expected_
++] = &padding_
;
962 expected_metadata_sequence_
[num_expected_
++] = &seektable_
;
963 expected_metadata_sequence_
[num_expected_
++] = &application1_
;
964 expected_metadata_sequence_
[num_expected_
++] = &cuesheet_
;
965 expected_metadata_sequence_
[num_expected_
++] = &picture_
;
966 expected_metadata_sequence_
[num_expected_
++] = &unknown_
;
969 expected_metadata_sequence_
[num_expected_
++] = &streaminfo_
;
970 expected_metadata_sequence_
[num_expected_
++] = &padding_
;
971 expected_metadata_sequence_
[num_expected_
++] = &seektable_
;
972 expected_metadata_sequence_
[num_expected_
++] = &application1_
;
973 expected_metadata_sequence_
[num_expected_
++] = &vorbiscomment_
;
974 expected_metadata_sequence_
[num_expected_
++] = &cuesheet_
;
975 expected_metadata_sequence_
[num_expected_
++] = &picture_
;
976 expected_metadata_sequence_
[num_expected_
++] = &unknown_
;
979 if(!stream_decoder_test_respond_(decoder
, &decoder_client_data
, is_ogg
))
983 * ignore all, respond APPLICATION, ignore APPLICATION id of app#1
986 printf("testing FLAC__stream_decoder_set_metadata_ignore_all()... ");
987 if(!FLAC__stream_decoder_set_metadata_ignore_all(decoder
))
988 return die_s_("returned false", decoder
);
991 printf("testing FLAC__stream_decoder_set_metadata_respond(APPLICATION)... ");
992 if(!FLAC__stream_decoder_set_metadata_respond(decoder
, FLAC__METADATA_TYPE_APPLICATION
))
993 return die_s_("returned false", decoder
);
996 printf("testing FLAC__stream_decoder_set_metadata_ignore_application(of app block #1)... ");
997 if(!FLAC__stream_decoder_set_metadata_ignore_application(decoder
, application1_
.data
.application
.id
))
998 return die_s_("returned false", decoder
);
1002 expected_metadata_sequence_
[num_expected_
++] = &application2_
;
1004 if(!stream_decoder_test_respond_(decoder
, &decoder_client_data
, is_ogg
))
1007 if(layer
< LAYER_FILE
) /* for LAYER_FILE, FLAC__stream_decoder_finish() closes the file */
1008 fclose(decoder_client_data
.file
);
1010 printf("testing FLAC__stream_decoder_delete()... ");
1011 FLAC__stream_decoder_delete(decoder
);
1014 printf("\nPASSED!\n");
1019 FLAC__bool
test_decoders(void)
1021 FLAC__bool is_ogg
= false;
1024 init_metadata_blocks_();
1026 if(!generate_file_(is_ogg
))
1029 if(!test_stream_decoder(LAYER_STREAM
, is_ogg
))
1032 if(!test_stream_decoder(LAYER_SEEKABLE_STREAM
, is_ogg
))
1035 if(!test_stream_decoder(LAYER_FILE
, is_ogg
))
1038 if(!test_stream_decoder(LAYER_FILENAME
, is_ogg
))
1041 (void) grabbag__file_remove_file(flacfilename(is_ogg
));
1043 free_metadata_blocks_();
1045 if(!FLAC_API_SUPPORTS_OGG_FLAC
|| is_ogg
)