bump version number to 1.1.0
[flac.git] / src / test_libOggFLAC++ / decoders.cpp
1 /* test_libOggFLAC++ - Unit tester for libOggFLAC++
2  * Copyright (C) 2002,2003  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 #include "decoders.h"
20 extern "C" {
21 #include "file_utils.h"
22 #include "metadata_utils.h"
23 }
24 #include "FLAC/assert.h"
25 #include "FLAC/metadata.h" // for ::FLAC__metadata_object_is_equal()
26 #include "OggFLAC++/decoder.h"
27 #include "share/grabbag.h"
28 #include <errno.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32
33 static ::FLAC__StreamMetadata streaminfo_, padding_, seektable_, application1_, application2_, vorbiscomment_, cuesheet_, unknown_;
34 static ::FLAC__StreamMetadata *expected_metadata_sequence_[8];
35 static unsigned num_expected_;
36 static const char *oggflacfilename_ = "metadata.ogg";
37 static unsigned oggflacfilesize_;
38
39 static bool die_(const char *msg)
40 {
41         printf("ERROR: %s\n", msg);
42         return false;
43 }
44
45 static void init_metadata_blocks_()
46 {
47         mutils__init_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_, &unknown_);
48 }
49
50 static void free_metadata_blocks_()
51 {
52         mutils__free_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_, &unknown_);
53 }
54
55 static bool generate_file_()
56 {
57         printf("\n\ngenerating Ogg FLAC file for decoder tests...\n");
58
59         num_expected_ = 0;
60         expected_metadata_sequence_[num_expected_++] = &padding_;
61         expected_metadata_sequence_[num_expected_++] = &seektable_;
62         expected_metadata_sequence_[num_expected_++] = &application1_;
63         expected_metadata_sequence_[num_expected_++] = &application2_;
64         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
65         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
66         expected_metadata_sequence_[num_expected_++] = &unknown_;
67
68         if(!file_utils__generate_oggflacfile(oggflacfilename_, &oggflacfilesize_, 512 * 1024, &streaminfo_, expected_metadata_sequence_, num_expected_))
69                 return die_("creating the encoded file");
70
71         return true;
72 }
73
74
75 class DecoderCommon {
76 public:
77         FILE *file_;
78         unsigned current_metadata_number_;
79         bool ignore_errors_;
80         bool error_occurred_;
81
82         DecoderCommon(): file_(0), current_metadata_number_(0), ignore_errors_(false), error_occurred_(false) { }
83         ::FLAC__StreamDecoderReadStatus common_read_callback_(FLAC__byte buffer[], unsigned *bytes);
84         ::FLAC__StreamDecoderWriteStatus common_write_callback_(const ::FLAC__Frame *frame);
85         void common_metadata_callback_(const ::FLAC__StreamMetadata *metadata);
86         void common_error_callback_(::FLAC__StreamDecoderErrorStatus status);
87 };
88
89 ::FLAC__StreamDecoderReadStatus DecoderCommon::common_read_callback_(FLAC__byte buffer[], unsigned *bytes)
90 {
91         if(error_occurred_)
92                 return ::FLAC__STREAM_DECODER_READ_STATUS_ABORT;
93
94         if(feof(file_))
95                 return ::FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
96         else if(*bytes > 0) {
97                 unsigned bytes_read = ::fread(buffer, 1, *bytes, file_);
98                 if(bytes_read == 0) {
99                         if(feof(file_))
100                                 return ::FLAC__STREAM_DECODER_READ_STATUS_END_OF_STREAM;
101                         else
102                                 return ::FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
103                 }
104                 else {
105                         *bytes = bytes_read;
106                         return ::FLAC__STREAM_DECODER_READ_STATUS_CONTINUE;
107                 }
108         }
109         else
110                 return ::FLAC__STREAM_DECODER_READ_STATUS_ABORT; /* abort to avoid a deadlock */
111 }
112
113 ::FLAC__StreamDecoderWriteStatus DecoderCommon::common_write_callback_(const ::FLAC__Frame *frame)
114 {
115         if(error_occurred_)
116                 return ::FLAC__STREAM_DECODER_WRITE_STATUS_ABORT;
117
118         if(
119                 (frame->header.number_type == ::FLAC__FRAME_NUMBER_TYPE_FRAME_NUMBER && frame->header.number.frame_number == 0) ||
120                 (frame->header.number_type == ::FLAC__FRAME_NUMBER_TYPE_SAMPLE_NUMBER && frame->header.number.sample_number == 0)
121         ) {
122                 printf("content... ");
123                 fflush(stdout);
124         }
125
126         return ::FLAC__STREAM_DECODER_WRITE_STATUS_CONTINUE;
127 }
128
129 void DecoderCommon::common_metadata_callback_(const ::FLAC__StreamMetadata *metadata)
130 {
131         if(error_occurred_)
132                 return;
133
134         printf("%d... ", current_metadata_number_);
135         fflush(stdout);
136
137         if(current_metadata_number_ >= num_expected_) {
138                 (void)die_("got more metadata blocks than expected");
139                 error_occurred_ = true;
140         }
141         else {
142                 if(!::FLAC__metadata_object_is_equal(expected_metadata_sequence_[current_metadata_number_], metadata)) {
143                         (void)die_("metadata block mismatch");
144                         error_occurred_ = true;
145                 }
146         }
147         current_metadata_number_++;
148 }
149
150 void DecoderCommon::common_error_callback_(::FLAC__StreamDecoderErrorStatus status)
151 {
152         if(!ignore_errors_) {
153                 printf("ERROR: got error callback: err = %u (%s)\n", (unsigned)status, ::FLAC__StreamDecoderErrorStatusString[status]);
154                 error_occurred_ = true;
155         }
156 }
157
158 class StreamDecoder : public OggFLAC::Decoder::Stream, public DecoderCommon {
159 public:
160         StreamDecoder(): OggFLAC::Decoder::Stream(), DecoderCommon() { }
161         ~StreamDecoder() { }
162
163         // from OggFLAC::Decoder::Stream
164         ::FLAC__StreamDecoderReadStatus read_callback(FLAC__byte buffer[], unsigned *bytes);
165         ::FLAC__StreamDecoderWriteStatus write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[]);
166         void metadata_callback(const ::FLAC__StreamMetadata *metadata);
167         void error_callback(::FLAC__StreamDecoderErrorStatus status);
168
169         bool die(const char *msg = 0) const;
170
171         bool test_respond();
172 };
173
174 ::FLAC__StreamDecoderReadStatus StreamDecoder::read_callback(FLAC__byte buffer[], unsigned *bytes)
175 {
176         return common_read_callback_(buffer, bytes);
177 }
178
179 ::FLAC__StreamDecoderWriteStatus StreamDecoder::write_callback(const ::FLAC__Frame *frame, const FLAC__int32 * const buffer[])
180 {
181         (void)buffer;
182
183         return common_write_callback_(frame);
184 }
185
186 void StreamDecoder::metadata_callback(const ::FLAC__StreamMetadata *metadata)
187 {
188         common_metadata_callback_(metadata);
189 }
190
191 void StreamDecoder::error_callback(::FLAC__StreamDecoderErrorStatus status)
192 {
193         common_error_callback_(status);
194 }
195
196 bool StreamDecoder::die(const char *msg) const
197 {
198         State state = get_state();
199
200         if(msg)
201                 printf("FAILED, %s", msg);
202         else
203                 printf("FAILED");
204
205         printf(", state = %u (%s)\n", (unsigned)((::OggFLAC__StreamDecoderState)state), state.as_cstring());
206
207         return false;
208 }
209
210 bool StreamDecoder::test_respond()
211 {
212         printf("testing init()... ");
213         if(init() != ::OggFLAC__STREAM_DECODER_OK)
214                 return die();
215         printf("OK\n");
216
217         current_metadata_number_ = 0;
218
219         if(::fseek(file_, 0, SEEK_SET) < 0) {
220                 printf("FAILED rewinding input, errno = %d\n", errno);
221                 return false;
222         }
223
224         printf("testing process_until_end_of_stream()... ");
225         if(!process_until_end_of_stream()) {
226                 State state = get_state();
227                 printf("FAILED, returned false, state = %u (%s)\n", (unsigned)((::OggFLAC__StreamDecoderState)state), state.as_cstring());
228                 return false;
229         }
230         printf("OK\n");
231
232         printf("testing finish()... ");
233         finish();
234         printf("OK\n");
235
236         return true;
237 }
238
239 static bool test_stream_decoder()
240 {
241         StreamDecoder *decoder;
242
243         printf("\n+++ libOggFLAC++ unit test: OggFLAC::Decoder::Stream\n\n");
244
245         //
246         // test new -> delete
247         //
248         printf("allocating decoder instance... ");
249         decoder = new StreamDecoder();
250         if(0 == decoder) {
251                 printf("FAILED, new returned NULL\n");
252                 return false;
253         }
254         printf("OK\n");
255
256         printf("testing is_valid()... ");
257         if(!decoder->is_valid()) {
258                 printf("FAILED, returned false\n");
259                 return false;
260         }
261         printf("OK\n");
262
263         printf("freeing decoder instance... ");
264         delete decoder;
265         printf("OK\n");
266
267         //
268         // test new -> init -> delete
269         //
270         printf("allocating decoder instance... ");
271         decoder = new StreamDecoder();
272         if(0 == decoder) {
273                 printf("FAILED, new returned NULL\n");
274                 return false;
275         }
276         printf("OK\n");
277
278         printf("testing is_valid()... ");
279         if(!decoder->is_valid()) {
280                 printf("FAILED, returned false\n");
281                 return false;
282         }
283         printf("OK\n");
284
285         printf("testing init()... ");
286         if(decoder->init() != ::OggFLAC__STREAM_DECODER_OK)
287                 return decoder->die();
288         printf("OK\n");
289
290         printf("freeing decoder instance... ");
291         delete decoder;
292         printf("OK\n");
293
294         //
295         // test normal usage
296         //
297         num_expected_ = 0;
298         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
299
300         printf("allocating decoder instance... ");
301         decoder = new StreamDecoder();
302         if(0 == decoder) {
303                 printf("FAILED, new returned NULL\n");
304                 return false;
305         }
306         printf("OK\n");
307
308         printf("testing is_valid()... ");
309         if(!decoder->is_valid()) {
310                 printf("FAILED, returned false\n");
311                 return false;
312         }
313         printf("OK\n");
314
315         printf("testing set_serial_number()... ");
316         if(!decoder->set_serial_number(file_utils__serial_number))
317                 return decoder->die("returned false");
318         printf("OK\n");
319
320         printf("testing init()... ");
321         if(decoder->init() != ::OggFLAC__STREAM_DECODER_OK)
322                 return decoder->die();
323         printf("OK\n");
324
325         printf("testing get_state()... ");
326         OggFLAC::Decoder::Stream::State state = decoder->get_state();
327         printf("returned state = %u (%s)... OK\n", (unsigned)((::OggFLAC__StreamDecoderState)state), state.as_cstring());
328
329         printf("testing get_FLAC_stream_decoder_state()... ");
330         FLAC::Decoder::Stream::State state_ = decoder->get_FLAC_stream_decoder_state();
331         printf("returned state = %u (%s)... OK\n", (unsigned)((::FLAC__StreamDecoderState)state_), state_.as_cstring());
332
333         decoder->current_metadata_number_ = 0;
334         decoder->ignore_errors_ = false;
335         decoder->error_occurred_ = false;
336
337         printf("opening Ogg FLAC file... ");
338         decoder->file_ = ::fopen(oggflacfilename_, "rb");
339         if(0 == decoder->file_) {
340                 printf("ERROR\n");
341                 return false;
342         }
343         printf("OK\n");
344
345         printf("testing process_until_end_of_metadata()... ");
346         if(!decoder->process_until_end_of_metadata())
347                 return decoder->die("returned false");
348         printf("OK\n");
349
350         printf("testing process_single()... ");
351         if(!decoder->process_single())
352                 return decoder->die("returned false");
353         printf("OK\n");
354
355         printf("testing flush()... ");
356         if(!decoder->flush())
357                 return decoder->die("returned false");
358         printf("OK\n");
359
360         decoder->ignore_errors_ = true;
361         printf("testing process_single()... ");
362         if(!decoder->process_single())
363                 return decoder->die("returned false");
364         printf("OK\n");
365         decoder->ignore_errors_ = false;
366
367         printf("testing process_until_end_of_stream()... ");
368         if(!decoder->process_until_end_of_stream())
369                 return decoder->die("returned false");
370         printf("OK\n");
371
372         printf("testing get_channels()... ");
373         {
374                 unsigned channels = decoder->get_channels();
375                 if(channels != streaminfo_.data.stream_info.channels) {
376                         printf("FAILED, returned %u, expected %u\n", channels, streaminfo_.data.stream_info.channels);
377                         return false;
378                 }
379         }
380         printf("OK\n");
381
382         printf("testing get_bits_per_sample()... ");
383         {
384                 unsigned bits_per_sample = decoder->get_bits_per_sample();
385                 if(bits_per_sample != streaminfo_.data.stream_info.bits_per_sample) {
386                         printf("FAILED, returned %u, expected %u\n", bits_per_sample, streaminfo_.data.stream_info.bits_per_sample);
387                         return false;
388                 }
389         }
390         printf("OK\n");
391
392         printf("testing get_sample_rate()... ");
393         {
394                 unsigned sample_rate = decoder->get_sample_rate();
395                 if(sample_rate != streaminfo_.data.stream_info.sample_rate) {
396                         printf("FAILED, returned %u, expected %u\n", sample_rate, streaminfo_.data.stream_info.sample_rate);
397                         return false;
398                 }
399         }
400         printf("OK\n");
401
402         printf("testing get_blocksize()... ");
403         {
404                 unsigned blocksize = decoder->get_blocksize();
405                 /* value could be anything since we're at the last block, so accept any answer */
406                 printf("returned %u... OK\n", blocksize);
407         }
408
409         printf("testing get_channel_assignment()... ");
410         {
411                 ::FLAC__ChannelAssignment ca = decoder->get_channel_assignment();
412                 printf("returned %u (%s)... OK\n", (unsigned)ca, ::FLAC__ChannelAssignmentString[ca]);
413         }
414
415         printf("testing reset()... ");
416         if(!decoder->reset())
417                 return decoder->die("returned false");
418         printf("OK\n");
419
420         decoder->current_metadata_number_ = 0;
421
422         printf("rewinding input... ");
423         if(::fseek(decoder->file_, 0, SEEK_SET) < 0) {
424                 printf("FAILED, errno = %d\n", errno);
425                 return false;
426         }
427         printf("OK\n");
428
429         printf("testing process_until_end_of_stream()... ");
430         if(!decoder->process_until_end_of_stream())
431                 return decoder->die("returned false");
432         printf("OK\n");
433
434         printf("testing finish()... ");
435         decoder->finish();
436         printf("OK\n");
437
438         /*
439          * respond all
440          */
441
442         printf("testing set_metadata_respond_all()... ");
443         if(!decoder->set_metadata_respond_all()) {
444                 printf("FAILED, returned false\n");
445                 return false;
446         }
447         printf("OK\n");
448
449         num_expected_ = 0;
450         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
451         expected_metadata_sequence_[num_expected_++] = &padding_;
452         expected_metadata_sequence_[num_expected_++] = &seektable_;
453         expected_metadata_sequence_[num_expected_++] = &application1_;
454         expected_metadata_sequence_[num_expected_++] = &application2_;
455         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
456         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
457         expected_metadata_sequence_[num_expected_++] = &unknown_;
458
459         if(!decoder->test_respond())
460                 return false;
461
462         /*
463          * ignore all
464          */
465
466         printf("testing set_metadata_ignore_all()... ");
467         if(!decoder->set_metadata_ignore_all()) {
468                 printf("FAILED, returned false\n");
469                 return false;
470         }
471         printf("OK\n");
472
473         num_expected_ = 0;
474
475         if(!decoder->test_respond())
476                 return false;
477
478         /*
479          * respond all, ignore VORBIS_COMMENT
480          */
481
482         printf("testing set_metadata_respond_all()... ");
483         if(!decoder->set_metadata_respond_all()) {
484                 printf("FAILED, returned false\n");
485                 return false;
486         }
487         printf("OK\n");
488
489         printf("testing set_metadata_ignore(VORBIS_COMMENT)... ");
490         if(!decoder->set_metadata_ignore(FLAC__METADATA_TYPE_VORBIS_COMMENT)) {
491                 printf("FAILED, returned false\n");
492                 return false;
493         }
494         printf("OK\n");
495
496         num_expected_ = 0;
497         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
498         expected_metadata_sequence_[num_expected_++] = &padding_;
499         expected_metadata_sequence_[num_expected_++] = &seektable_;
500         expected_metadata_sequence_[num_expected_++] = &application1_;
501         expected_metadata_sequence_[num_expected_++] = &application2_;
502         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
503         expected_metadata_sequence_[num_expected_++] = &unknown_;
504
505         if(!decoder->test_respond())
506                 return false;
507
508         /*
509          * respond all, ignore APPLICATION
510          */
511
512         printf("testing set_metadata_respond_all()... ");
513         if(!decoder->set_metadata_respond_all()) {
514                 printf("FAILED, returned false\n");
515                 return false;
516         }
517         printf("OK\n");
518
519         printf("testing set_metadata_ignore(APPLICATION)... ");
520         if(!decoder->set_metadata_ignore(FLAC__METADATA_TYPE_APPLICATION)) {
521                 printf("FAILED, returned false\n");
522                 return false;
523         }
524         printf("OK\n");
525
526         num_expected_ = 0;
527         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
528         expected_metadata_sequence_[num_expected_++] = &padding_;
529         expected_metadata_sequence_[num_expected_++] = &seektable_;
530         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
531         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
532         expected_metadata_sequence_[num_expected_++] = &unknown_;
533
534         if(!decoder->test_respond())
535                 return false;
536
537         /*
538          * respond all, ignore APPLICATION id of app#1
539          */
540
541         printf("testing set_metadata_respond_all()... ");
542         if(!decoder->set_metadata_respond_all()) {
543                 printf("FAILED, returned false\n");
544                 return false;
545         }
546         printf("OK\n");
547
548         printf("testing set_metadata_ignore_application(of app block #1)... ");
549         if(!decoder->set_metadata_ignore_application(application1_.data.application.id)) {
550                 printf("FAILED, returned false\n");
551                 return false;
552         }
553         printf("OK\n");
554
555         num_expected_ = 0;
556         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
557         expected_metadata_sequence_[num_expected_++] = &padding_;
558         expected_metadata_sequence_[num_expected_++] = &seektable_;
559         expected_metadata_sequence_[num_expected_++] = &application2_;
560         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
561         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
562         expected_metadata_sequence_[num_expected_++] = &unknown_;
563
564         if(!decoder->test_respond())
565                 return false;
566
567         /*
568          * respond all, ignore APPLICATION id of app#1 & app#2
569          */
570
571         printf("testing set_metadata_respond_all()... ");
572         if(!decoder->set_metadata_respond_all()) {
573                 printf("FAILED, returned false\n");
574                 return false;
575         }
576         printf("OK\n");
577
578         printf("testing set_metadata_ignore_application(of app block #1)... ");
579         if(!decoder->set_metadata_ignore_application(application1_.data.application.id)) {
580                 printf("FAILED, returned false\n");
581                 return false;
582         }
583         printf("OK\n");
584
585         printf("testing set_metadata_ignore_application(of app block #2)... ");
586         if(!decoder->set_metadata_ignore_application(application2_.data.application.id)) {
587                 printf("FAILED, returned false\n");
588                 return false;
589         }
590         printf("OK\n");
591
592         num_expected_ = 0;
593         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
594         expected_metadata_sequence_[num_expected_++] = &padding_;
595         expected_metadata_sequence_[num_expected_++] = &seektable_;
596         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
597         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
598         expected_metadata_sequence_[num_expected_++] = &unknown_;
599
600         if(!decoder->test_respond())
601                 return false;
602
603         /*
604          * ignore all, respond VORBIS_COMMENT
605          */
606
607         printf("testing set_metadata_ignore_all()... ");
608         if(!decoder->set_metadata_ignore_all()) {
609                 printf("FAILED, returned false\n");
610                 return false;
611         }
612         printf("OK\n");
613
614         printf("testing set_metadata_respond(VORBIS_COMMENT)... ");
615         if(!decoder->set_metadata_respond(FLAC__METADATA_TYPE_VORBIS_COMMENT)) {
616                 printf("FAILED, returned false\n");
617                 return false;
618         }
619         printf("OK\n");
620
621         num_expected_ = 0;
622         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
623
624         if(!decoder->test_respond())
625                 return false;
626
627         /*
628          * ignore all, respond APPLICATION
629          */
630
631         printf("testing set_metadata_ignore_all()... ");
632         if(!decoder->set_metadata_ignore_all()) {
633                 printf("FAILED, returned false\n");
634                 return false;
635         }
636         printf("OK\n");
637
638         printf("testing set_metadata_respond(APPLICATION)... ");
639         if(!decoder->set_metadata_respond(FLAC__METADATA_TYPE_APPLICATION)) {
640                 printf("FAILED, returned false\n");
641                 return false;
642         }
643         printf("OK\n");
644
645         num_expected_ = 0;
646         expected_metadata_sequence_[num_expected_++] = &application1_;
647         expected_metadata_sequence_[num_expected_++] = &application2_;
648
649         if(!decoder->test_respond())
650                 return false;
651
652         /*
653          * ignore all, respond APPLICATION id of app#1
654          */
655
656         printf("testing set_metadata_ignore_all()... ");
657         if(!decoder->set_metadata_ignore_all()) {
658                 printf("FAILED, returned false\n");
659                 return false;
660         }
661         printf("OK\n");
662
663         printf("testing set_metadata_respond_application(of app block #1)... ");
664         if(!decoder->set_metadata_respond_application(application1_.data.application.id)) {
665                 printf("FAILED, returned false\n");
666                 return false;
667         }
668         printf("OK\n");
669
670         num_expected_ = 0;
671         expected_metadata_sequence_[num_expected_++] = &application1_;
672
673         if(!decoder->test_respond())
674                 return false;
675
676         /*
677          * ignore all, respond APPLICATION id of app#1 & app#2
678          */
679
680         printf("testing set_metadata_ignore_all()... ");
681         if(!decoder->set_metadata_ignore_all()) {
682                 printf("FAILED, returned false\n");
683                 return false;
684         }
685         printf("OK\n");
686
687         printf("testing set_metadata_respond_application(of app block #1)... ");
688         if(!decoder->set_metadata_respond_application(application1_.data.application.id)) {
689                 printf("FAILED, returned false\n");
690                 return false;
691         }
692         printf("OK\n");
693
694         printf("testing set_metadata_respond_application(of app block #2)... ");
695         if(!decoder->set_metadata_respond_application(application2_.data.application.id)) {
696                 printf("FAILED, returned false\n");
697                 return false;
698         }
699         printf("OK\n");
700
701         num_expected_ = 0;
702         expected_metadata_sequence_[num_expected_++] = &application1_;
703         expected_metadata_sequence_[num_expected_++] = &application2_;
704
705         if(!decoder->test_respond())
706                 return false;
707
708         /*
709          * respond all, ignore APPLICATION, respond APPLICATION id of app#1
710          */
711
712         printf("testing set_metadata_respond_all()... ");
713         if(!decoder->set_metadata_respond_all()) {
714                 printf("FAILED, returned false\n");
715                 return false;
716         }
717         printf("OK\n");
718
719         printf("testing set_metadata_ignore(APPLICATION)... ");
720         if(!decoder->set_metadata_ignore(FLAC__METADATA_TYPE_APPLICATION)) {
721                 printf("FAILED, returned false\n");
722                 return false;
723         }
724         printf("OK\n");
725
726         printf("testing set_metadata_respond_application(of app block #1)... ");
727         if(!decoder->set_metadata_respond_application(application1_.data.application.id)) {
728                 printf("FAILED, returned false\n");
729                 return false;
730         }
731         printf("OK\n");
732
733         num_expected_ = 0;
734         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
735         expected_metadata_sequence_[num_expected_++] = &padding_;
736         expected_metadata_sequence_[num_expected_++] = &seektable_;
737         expected_metadata_sequence_[num_expected_++] = &application1_;
738         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
739         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
740         expected_metadata_sequence_[num_expected_++] = &unknown_;
741
742         if(!decoder->test_respond())
743                 return false;
744
745         /*
746          * ignore all, respond APPLICATION, ignore APPLICATION id of app#1
747          */
748
749         printf("testing set_metadata_ignore_all()... ");
750         if(!decoder->set_metadata_ignore_all()) {
751                 printf("FAILED, returned false\n");
752                 return false;
753         }
754         printf("OK\n");
755
756         printf("testing set_metadata_respond(APPLICATION)... ");
757         if(!decoder->set_metadata_respond(FLAC__METADATA_TYPE_APPLICATION)) {
758                 printf("FAILED, returned false\n");
759                 return false;
760         }
761         printf("OK\n");
762
763         printf("testing set_metadata_ignore_application(of app block #1)... ");
764         if(!decoder->set_metadata_ignore_application(application1_.data.application.id)) {
765                 printf("FAILED, returned false\n");
766                 return false;
767         }
768         printf("OK\n");
769
770         num_expected_ = 0;
771         expected_metadata_sequence_[num_expected_++] = &application2_;
772
773         if(!decoder->test_respond())
774                 return false;
775
776         /* done, now leave the sequence the way we found it... */
777         num_expected_ = 0;
778         expected_metadata_sequence_[num_expected_++] = &streaminfo_;
779         expected_metadata_sequence_[num_expected_++] = &padding_;
780         expected_metadata_sequence_[num_expected_++] = &seektable_;
781         expected_metadata_sequence_[num_expected_++] = &application1_;
782         expected_metadata_sequence_[num_expected_++] = &application2_;
783         expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
784         expected_metadata_sequence_[num_expected_++] = &cuesheet_;
785         expected_metadata_sequence_[num_expected_++] = &unknown_;
786
787         ::fclose(decoder->file_);
788
789         printf("freeing decoder instance... ");
790         delete decoder;
791         printf("OK\n");
792
793         printf("\nPASSED!\n");
794
795         return true;
796 }
797
798 bool test_decoders()
799 {
800         init_metadata_blocks_();
801         if(!generate_file_())
802                 return false;
803
804         if(!test_stream_decoder())
805                 return false;
806
807         (void) grabbag__file_remove_file(oggflacfilename_);
808         free_metadata_blocks_();
809
810         return true;
811 }