1 /* test_libOggFLAC++ - Unit tester for libOggFLAC++
2 * Copyright (C) 2002 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
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.
21 #include "file_utils.h"
23 #include "FLAC/assert.h"
24 #include "OggFLAC++/encoder.h"
29 static ::FLAC__StreamMetadata streaminfo_, padding_, seektable_, application1_, application2_, vorbiscomment_;
30 static ::FLAC__StreamMetadata *metadata_sequence_[] = { &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_ };
31 static const unsigned num_metadata_ = 5;
33 static void *malloc_or_die_(size_t size)
35 void *x = malloc(size);
37 fprintf(stderr, "ERROR: out of memory allocating %u bytes\n", (unsigned)size);
43 static void init_metadata_blocks_()
46 most of the actual numbers and data in the blocks don't matter,
47 we just want to make sure the encoder encodes them correctly
49 remember, the metadata interface gets tested after the encoders,
50 so we do all the metadata manipulation here without it.
53 /* min/max_framesize and md5sum don't get written at first, so we have to leave them 0 */
54 streaminfo_.is_last = false;
55 streaminfo_.type = ::FLAC__METADATA_TYPE_STREAMINFO;
56 streaminfo_.length = FLAC__STREAM_METADATA_STREAMINFO_LENGTH;
57 streaminfo_.data.stream_info.min_blocksize = 576;
58 streaminfo_.data.stream_info.max_blocksize = 576;
59 streaminfo_.data.stream_info.min_framesize = 0;
60 streaminfo_.data.stream_info.max_framesize = 0;
61 streaminfo_.data.stream_info.sample_rate = 44100;
62 streaminfo_.data.stream_info.channels = 1;
63 streaminfo_.data.stream_info.bits_per_sample = 8;
64 streaminfo_.data.stream_info.total_samples = 0;
65 memset(streaminfo_.data.stream_info.md5sum, 0, 16);
67 padding_.is_last = false;
68 padding_.type = ::FLAC__METADATA_TYPE_PADDING;
69 padding_.length = 1234;
71 seektable_.is_last = false;
72 seektable_.type = ::FLAC__METADATA_TYPE_SEEKTABLE;
73 seektable_.data.seek_table.num_points = 2;
74 seektable_.length = seektable_.data.seek_table.num_points * FLAC__STREAM_METADATA_SEEKPOINT_LENGTH;
75 seektable_.data.seek_table.points = (::FLAC__StreamMetadata_SeekPoint*)malloc_or_die_(seektable_.data.seek_table.num_points * sizeof(::FLAC__StreamMetadata_SeekPoint));
76 seektable_.data.seek_table.points[0].sample_number = 0;
77 seektable_.data.seek_table.points[0].stream_offset = 0;
78 seektable_.data.seek_table.points[0].frame_samples = streaminfo_.data.stream_info.min_blocksize;
79 seektable_.data.seek_table.points[1].sample_number = ::FLAC__STREAM_METADATA_SEEKPOINT_PLACEHOLDER;
80 seektable_.data.seek_table.points[1].stream_offset = 1000;
81 seektable_.data.seek_table.points[1].frame_samples = streaminfo_.data.stream_info.min_blocksize;
83 application1_.is_last = false;
84 application1_.type = ::FLAC__METADATA_TYPE_APPLICATION;
85 application1_.length = 8;
86 memcpy(application1_.data.application.id, "\xfe\xdc\xba\x98", 4);
87 application1_.data.application.data = (FLAC__byte*)malloc_or_die_(4);
88 memcpy(application1_.data.application.data, "\xf0\xe1\xd2\xc3", 4);
90 application2_.is_last = false;
91 application2_.type = ::FLAC__METADATA_TYPE_APPLICATION;
92 application2_.length = 4;
93 memcpy(application2_.data.application.id, "\x76\x54\x32\x10", 4);
94 application2_.data.application.data = 0;
96 vorbiscomment_.is_last = true;
97 vorbiscomment_.type = ::FLAC__METADATA_TYPE_VORBIS_COMMENT;
98 vorbiscomment_.length = (4 + 8) + 4 + (4 + 5) + (4 + 0);
99 vorbiscomment_.data.vorbis_comment.vendor_string.length = 8;
100 vorbiscomment_.data.vorbis_comment.vendor_string.entry = (FLAC__byte*)malloc_or_die_(8);
101 memcpy(vorbiscomment_.data.vorbis_comment.vendor_string.entry, "flac 1.x", 8);
102 vorbiscomment_.data.vorbis_comment.num_comments = 2;
103 vorbiscomment_.data.vorbis_comment.comments = (::FLAC__StreamMetadata_VorbisComment_Entry*)malloc_or_die_(vorbiscomment_.data.vorbis_comment.num_comments * sizeof(::FLAC__StreamMetadata_VorbisComment_Entry));
104 vorbiscomment_.data.vorbis_comment.comments[0].length = 5;
105 vorbiscomment_.data.vorbis_comment.comments[0].entry = (FLAC__byte*)malloc_or_die_(5);
106 memcpy(vorbiscomment_.data.vorbis_comment.comments[0].entry, "ab=cd", 5);
107 vorbiscomment_.data.vorbis_comment.comments[1].length = 0;
108 vorbiscomment_.data.vorbis_comment.comments[1].entry = 0;
111 static void free_metadata_blocks_()
113 free(seektable_.data.seek_table.points);
114 free(application1_.data.application.data);
115 free(vorbiscomment_.data.vorbis_comment.vendor_string.entry);
116 free(vorbiscomment_.data.vorbis_comment.comments[0].entry);
117 free(vorbiscomment_.data.vorbis_comment.comments);
120 class StreamEncoder : public OggFLAC::Encoder::Stream {
122 StreamEncoder(): OggFLAC::Encoder::Stream() { }
125 // from OggFLAC::Encoder::Stream
126 ::FLAC__StreamEncoderWriteStatus write_callback(const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame);
128 bool die(const char *msg = 0) const;
131 ::FLAC__StreamEncoderWriteStatus StreamEncoder::write_callback(const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame)
133 (void)buffer, (void)bytes, (void)samples, (void)current_frame;
135 return ::FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
138 bool StreamEncoder::die(const char *msg) const
140 State state = get_state();
143 printf("FAILED, %s", msg);
147 printf(", state = %u (%s)\n", (unsigned)((::OggFLAC__StreamEncoderState)state), state.as_cstring());
148 if(state == ::OggFLAC__STREAM_ENCODER_FLAC_STREAM_ENCODER_ERROR) {
149 FLAC::Encoder::Stream::State state_ = get_FLAC_stream_encoder_state();
150 printf(" FLAC stream encoder state = %u (%s)\n", (unsigned)((::FLAC__StreamEncoderState)state_), state_.as_cstring());
151 if(state_ == ::FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR) {
152 FLAC::Decoder::Stream::State dstate = get_verify_decoder_state();
153 printf(" verify decoder state = %u (%s)\n", (unsigned)((::FLAC__StreamDecoderState)dstate), dstate.as_cstring());
160 static bool test_stream_encoder()
162 StreamEncoder *encoder;
163 FLAC__int32 samples[1024];
164 FLAC__int32 *samples_array[1] = { samples };
167 printf("\n+++ libOggFLAC++ unit test: OggFLAC::Encoder::Stream\n\n");
169 printf("allocating encoder instance... ");
170 encoder = new StreamEncoder();
172 printf("FAILED, new returned NULL\n");
177 printf("testing is_valid()... ");
178 if(!encoder->is_valid()) {
179 printf("FAILED, returned false\n");
184 printf("testing set_serial_number()... ");
185 if(!encoder->set_serial_number(file_utils__serial_number))
186 return encoder->die("returned false");
189 printf("testing set_verify()... ");
190 if(!encoder->set_verify(true))
191 return encoder->die("returned false");
194 printf("testing set_streamable_subset()... ");
195 if(!encoder->set_streamable_subset(true))
196 return encoder->die("returned false");
199 printf("testing set_do_mid_side_stereo()... ");
200 if(!encoder->set_do_mid_side_stereo(false))
201 return encoder->die("returned false");
204 printf("testing set_loose_mid_side_stereo()... ");
205 if(!encoder->set_loose_mid_side_stereo(false))
206 return encoder->die("returned false");
209 printf("testing set_channels()... ");
210 if(!encoder->set_channels(streaminfo_.data.stream_info.channels))
211 return encoder->die("returned false");
214 printf("testing set_bits_per_sample()... ");
215 if(!encoder->set_bits_per_sample(streaminfo_.data.stream_info.bits_per_sample))
216 return encoder->die("returned false");
219 printf("testing set_sample_rate()... ");
220 if(!encoder->set_sample_rate(streaminfo_.data.stream_info.sample_rate))
221 return encoder->die("returned false");
224 printf("testing set_blocksize()... ");
225 if(!encoder->set_blocksize(streaminfo_.data.stream_info.min_blocksize))
226 return encoder->die("returned false");
229 printf("testing set_max_lpc_order()... ");
230 if(!encoder->set_max_lpc_order(0))
231 return encoder->die("returned false");
234 printf("testing set_qlp_coeff_precision()... ");
235 if(!encoder->set_qlp_coeff_precision(0))
236 return encoder->die("returned false");
239 printf("testing set_do_qlp_coeff_prec_search()... ");
240 if(!encoder->set_do_qlp_coeff_prec_search(false))
241 return encoder->die("returned false");
244 printf("testing set_do_escape_coding()... ");
245 if(!encoder->set_do_escape_coding(false))
246 return encoder->die("returned false");
249 printf("testing set_do_exhaustive_model_search()... ");
250 if(!encoder->set_do_exhaustive_model_search(false))
251 return encoder->die("returned false");
254 printf("testing set_min_residual_partition_order()... ");
255 if(!encoder->set_min_residual_partition_order(0))
256 return encoder->die("returned false");
259 printf("testing set_max_residual_partition_order()... ");
260 if(!encoder->set_max_residual_partition_order(0))
261 return encoder->die("returned false");
264 printf("testing set_rice_parameter_search_dist()... ");
265 if(!encoder->set_rice_parameter_search_dist(0))
266 return encoder->die("returned false");
269 printf("testing set_total_samples_estimate()... ");
270 if(!encoder->set_total_samples_estimate(streaminfo_.data.stream_info.total_samples))
271 return encoder->die("returned false");
274 printf("testing set_metadata()... ");
275 if(!encoder->set_metadata(metadata_sequence_, num_metadata_))
276 return encoder->die("returned false");
279 printf("testing init()... ");
280 if(encoder->init() != ::OggFLAC__STREAM_ENCODER_OK)
281 return encoder->die();
284 printf("testing get_state()... ");
285 OggFLAC::Encoder::Stream::State state = encoder->get_state();
286 printf("returned state = %u (%s)... OK\n", (unsigned)((::OggFLAC__StreamEncoderState)state), state.as_cstring());
288 printf("testing get_FLAC_stream_encoder_state()... ");
289 FLAC::Encoder::Stream::State state_ = encoder->get_FLAC_stream_encoder_state();
290 printf("returned state = %u (%s)... OK\n", (unsigned)((::FLAC__StreamEncoderState)state_), state_.as_cstring());
292 printf("testing get_verify_decoder_state()... ");
293 FLAC::Decoder::Stream::State dstate = encoder->get_verify_decoder_state();
294 printf("returned state = %u (%s)... OK\n", (unsigned)((::FLAC__StreamDecoderState)dstate), dstate.as_cstring());
297 FLAC__uint64 absolute_sample;
298 unsigned frame_number;
301 FLAC__int32 expected;
304 printf("testing get_verify_decoder_error_stats()... ");
305 encoder->get_verify_decoder_error_stats(&absolute_sample, &frame_number, &channel, &sample, &expected, &got);
309 printf("testing get_verify()... ");
310 if(encoder->get_verify() != true) {
311 printf("FAILED, expected true, got false\n");
316 printf("testing get_streamable_subset()... ");
317 if(encoder->get_streamable_subset() != true) {
318 printf("FAILED, expected true, got false\n");
323 printf("testing get_do_mid_side_stereo()... ");
324 if(encoder->get_do_mid_side_stereo() != false) {
325 printf("FAILED, expected false, got true\n");
330 printf("testing get_loose_mid_side_stereo()... ");
331 if(encoder->get_loose_mid_side_stereo() != false) {
332 printf("FAILED, expected false, got true\n");
337 printf("testing get_channels()... ");
338 if(encoder->get_channels() != streaminfo_.data.stream_info.channels) {
339 printf("FAILED, expected %u, got %u\n", streaminfo_.data.stream_info.channels, encoder->get_channels());
344 printf("testing get_bits_per_sample()... ");
345 if(encoder->get_bits_per_sample() != streaminfo_.data.stream_info.bits_per_sample) {
346 printf("FAILED, expected %u, got %u\n", streaminfo_.data.stream_info.bits_per_sample, encoder->get_bits_per_sample());
351 printf("testing get_sample_rate()... ");
352 if(encoder->get_sample_rate() != streaminfo_.data.stream_info.sample_rate) {
353 printf("FAILED, expected %u, got %u\n", streaminfo_.data.stream_info.sample_rate, encoder->get_sample_rate());
358 printf("testing get_blocksize()... ");
359 if(encoder->get_blocksize() != streaminfo_.data.stream_info.min_blocksize) {
360 printf("FAILED, expected %u, got %u\n", streaminfo_.data.stream_info.min_blocksize, encoder->get_blocksize());
365 printf("testing get_max_lpc_order()... ");
366 if(encoder->get_max_lpc_order() != 0) {
367 printf("FAILED, expected %u, got %u\n", 0, encoder->get_max_lpc_order());
372 printf("testing get_qlp_coeff_precision()... ");
373 (void)encoder->get_qlp_coeff_precision();
374 /* we asked the encoder to auto select this so we accept anything */
377 printf("testing get_do_qlp_coeff_prec_search()... ");
378 if(encoder->get_do_qlp_coeff_prec_search() != false) {
379 printf("FAILED, expected false, got true\n");
384 printf("testing get_do_escape_coding()... ");
385 if(encoder->get_do_escape_coding() != false) {
386 printf("FAILED, expected false, got true\n");
391 printf("testing get_do_exhaustive_model_search()... ");
392 if(encoder->get_do_exhaustive_model_search() != false) {
393 printf("FAILED, expected false, got true\n");
398 printf("testing get_min_residual_partition_order()... ");
399 if(encoder->get_min_residual_partition_order() != 0) {
400 printf("FAILED, expected %u, got %u\n", 0, encoder->get_min_residual_partition_order());
405 printf("testing get_max_residual_partition_order()... ");
406 if(encoder->get_max_residual_partition_order() != 0) {
407 printf("FAILED, expected %u, got %u\n", 0, encoder->get_max_residual_partition_order());
412 printf("testing get_rice_parameter_search_dist()... ");
413 if(encoder->get_rice_parameter_search_dist() != 0) {
414 printf("FAILED, expected %u, got %u\n", 0, encoder->get_rice_parameter_search_dist());
419 printf("testing get_total_samples_estimate()... ");
420 if(encoder->get_total_samples_estimate() != streaminfo_.data.stream_info.total_samples) {
421 printf("FAILED, expected %llu, got %llu\n", streaminfo_.data.stream_info.total_samples, encoder->get_total_samples_estimate());
426 /* init the dummy sample buffer */
427 for(i = 0; i < sizeof(samples) / sizeof(FLAC__int32); i++)
430 printf("testing process()... ");
431 if(!encoder->process(samples_array, sizeof(samples) / sizeof(FLAC__int32)))
432 return encoder->die("returned false");
435 printf("testing process_interleaved()... ");
436 if(!encoder->process_interleaved(samples, sizeof(samples) / sizeof(FLAC__int32)))
437 return encoder->die("returned false");
440 printf("testing finish()... ");
444 printf("freeing encoder instance... ");
448 printf("\nPASSED!\n");
455 init_metadata_blocks_();
457 if(!test_stream_encoder())
460 free_metadata_blocks_();