7b7dc3459764203d5e8846b3c761ca35c21e5268
[platform/upstream/flac.git] / src / test_libFLAC++ / encoders.cc
1 /* test_libFLAC++ - Unit tester for libFLAC++
2  * Copyright (C) 2002  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 "encoders.h"
20 extern "C" {
21 #include "file_utils.h"
22 }
23 #include "FLAC/assert.h"
24 #include "FLAC++/encoder.h"
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28
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;
32
33 static void *malloc_or_die_(size_t size)
34 {
35         void *x = malloc(size);
36         if(0 == x) {
37                 fprintf(stderr, "ERROR: out of memory allocating %u bytes\n", (unsigned)size);
38                 exit(1);
39         }
40         return x;
41 }
42
43 static void init_metadata_blocks_()
44 {
45         /*
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
48
49                 remember, the metadata interface gets tested after the encoders,
50                 so we do all the metadata manipulation here without it.
51         */
52
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);
66
67     padding_.is_last = false;
68     padding_.type = ::FLAC__METADATA_TYPE_PADDING;
69     padding_.length = 1234;
70
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;
82
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);
89
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;
95
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;
109 }
110
111 static void free_metadata_blocks_()
112 {
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);
118 }
119
120 class StreamEncoder : public FLAC::Encoder::Stream {
121 public:
122         StreamEncoder(): FLAC::Encoder::Stream() { }
123         ~StreamEncoder() { }
124
125         // from FLAC::Encoder::Stream
126         ::FLAC__StreamEncoderWriteStatus write_callback(const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame);
127         void metadata_callback(const ::FLAC__StreamMetadata *metadata);
128
129         bool die(const char *msg = 0) const;
130 };
131
132 ::FLAC__StreamEncoderWriteStatus StreamEncoder::write_callback(const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame)
133 {
134         (void)buffer, (void)bytes, (void)samples, (void)current_frame;
135
136         return ::FLAC__STREAM_ENCODER_WRITE_OK;
137 }
138
139 void StreamEncoder::metadata_callback(const ::FLAC__StreamMetadata *metadata)
140 {
141         (void)metadata;
142 }
143
144 bool StreamEncoder::die(const char *msg) const
145 {
146         State state = get_state();
147
148         if(msg)
149                 printf("FAILED, %s, state = %u (%s)\n", msg, (unsigned)((::FLAC__StreamEncoderState)state), state.as_cstring());
150         else
151                 printf("FAILED, state = %u (%s)\n", (unsigned)((::FLAC__StreamEncoderState)state), state.as_cstring());
152
153         return false;
154 }
155
156 static bool test_stream_encoder()
157 {
158         StreamEncoder *encoder;
159         FLAC__int32 samples[1024];
160         FLAC__int32 *samples_array[1] = { samples };
161         unsigned i;
162
163         printf("\n+++ libFLAC++ unit test: FLAC::Encoder::Stream\n\n");
164
165         printf("allocating encoder instance... ");
166         encoder = new StreamEncoder();
167         if(0 == encoder) {
168                 printf("FAILED, new returned NULL\n");
169                 return false;
170         }
171         printf("OK\n");
172
173         printf("testing is_valid()... ");
174         if(!encoder->is_valid()) {
175                 printf("FAILED, returned false\n");
176                 return false;
177         }
178         printf("OK\n");
179
180         printf("testing set_streamable_subset()... ");
181         if(!encoder->set_streamable_subset(true))
182                 return encoder->die("returned false");
183         printf("OK\n");
184
185         printf("testing set_do_mid_side_stereo()... ");
186         if(!encoder->set_do_mid_side_stereo(false))
187                 return encoder->die("returned false");
188         printf("OK\n");
189
190         printf("testing set_loose_mid_side_stereo()... ");
191         if(!encoder->set_loose_mid_side_stereo(false))
192                 return encoder->die("returned false");
193         printf("OK\n");
194
195         printf("testing set_channels()... ");
196         if(!encoder->set_channels(streaminfo_.data.stream_info.channels))
197                 return encoder->die("returned false");
198         printf("OK\n");
199
200         printf("testing set_bits_per_sample()... ");
201         if(!encoder->set_bits_per_sample(streaminfo_.data.stream_info.bits_per_sample))
202                 return encoder->die("returned false");
203         printf("OK\n");
204
205         printf("testing set_sample_rate()... ");
206         if(!encoder->set_sample_rate(streaminfo_.data.stream_info.sample_rate))
207                 return encoder->die("returned false");
208         printf("OK\n");
209
210         printf("testing set_blocksize()... ");
211         if(!encoder->set_blocksize(streaminfo_.data.stream_info.min_blocksize))
212                 return encoder->die("returned false");
213         printf("OK\n");
214
215         printf("testing set_max_lpc_order()... ");
216         if(!encoder->set_max_lpc_order(0))
217                 return encoder->die("returned false");
218         printf("OK\n");
219
220         printf("testing set_qlp_coeff_precision()... ");
221         if(!encoder->set_qlp_coeff_precision(0))
222                 return encoder->die("returned false");
223         printf("OK\n");
224
225         printf("testing set_do_qlp_coeff_prec_search()... ");
226         if(!encoder->set_do_qlp_coeff_prec_search(false))
227                 return encoder->die("returned false");
228         printf("OK\n");
229
230         printf("testing set_do_escape_coding()... ");
231         if(!encoder->set_do_escape_coding(false))
232                 return encoder->die("returned false");
233         printf("OK\n");
234
235         printf("testing set_do_exhaustive_model_search()... ");
236         if(!encoder->set_do_exhaustive_model_search(false))
237                 return encoder->die("returned false");
238         printf("OK\n");
239
240         printf("testing set_min_residual_partition_order()... ");
241         if(!encoder->set_min_residual_partition_order(0))
242                 return encoder->die("returned false");
243         printf("OK\n");
244
245         printf("testing set_max_residual_partition_order()... ");
246         if(!encoder->set_max_residual_partition_order(0))
247                 return encoder->die("returned false");
248         printf("OK\n");
249
250         printf("testing set_rice_parameter_search_dist()... ");
251         if(!encoder->set_rice_parameter_search_dist(0))
252                 return encoder->die("returned false");
253         printf("OK\n");
254
255         printf("testing set_total_samples_estimate()... ");
256         if(!encoder->set_total_samples_estimate(streaminfo_.data.stream_info.total_samples))
257                 return encoder->die("returned false");
258         printf("OK\n");
259
260         printf("testing set_metadata()... ");
261         if(!encoder->set_metadata(metadata_sequence_, num_metadata_))
262                 return encoder->die("returned false");
263         printf("OK\n");
264
265         printf("testing init()... ");
266         if(encoder->init() != ::FLAC__STREAM_ENCODER_OK)
267                 return encoder->die();
268         printf("OK\n");
269
270         printf("testing get_state()... ");
271         FLAC::Encoder::Stream::State state = encoder->get_state();
272         printf("returned state = %u (%s)... OK\n", (unsigned)((::FLAC__StreamEncoderState)state), state.as_cstring());
273
274         printf("testing get_streamable_subset()... ");
275         if(encoder->get_streamable_subset() != true) {
276                 printf("FAILED, expected true, got false\n");
277                 return false;
278         }
279         printf("OK\n");
280
281         printf("testing get_do_mid_side_stereo()... ");
282         if(encoder->get_do_mid_side_stereo() != false) {
283                 printf("FAILED, expected false, got true\n");
284                 return false;
285         }
286         printf("OK\n");
287
288         printf("testing get_loose_mid_side_stereo()... ");
289         if(encoder->get_loose_mid_side_stereo() != false) {
290                 printf("FAILED, expected false, got true\n");
291                 return false;
292         }
293         printf("OK\n");
294
295         printf("testing get_channels()... ");
296         if(encoder->get_channels() != streaminfo_.data.stream_info.channels) {
297                 printf("FAILED, expected %u, got %u\n", streaminfo_.data.stream_info.channels, encoder->get_channels());
298                 return false;
299         }
300         printf("OK\n");
301
302         printf("testing get_bits_per_sample()... ");
303         if(encoder->get_bits_per_sample() != streaminfo_.data.stream_info.bits_per_sample) {
304                 printf("FAILED, expected %u, got %u\n", streaminfo_.data.stream_info.bits_per_sample, encoder->get_bits_per_sample());
305                 return false;
306         }
307         printf("OK\n");
308
309         printf("testing get_sample_rate()... ");
310         if(encoder->get_sample_rate() != streaminfo_.data.stream_info.sample_rate) {
311                 printf("FAILED, expected %u, got %u\n", streaminfo_.data.stream_info.sample_rate, encoder->get_sample_rate());
312                 return false;
313         }
314         printf("OK\n");
315
316         printf("testing get_blocksize()... ");
317         if(encoder->get_blocksize() != streaminfo_.data.stream_info.min_blocksize) {
318                 printf("FAILED, expected %u, got %u\n", streaminfo_.data.stream_info.min_blocksize, encoder->get_blocksize());
319                 return false;
320         }
321         printf("OK\n");
322
323         printf("testing get_max_lpc_order()... ");
324         if(encoder->get_max_lpc_order() != 0) {
325                 printf("FAILED, expected %u, got %u\n", 0, encoder->get_max_lpc_order());
326                 return false;
327         }
328         printf("OK\n");
329
330         printf("testing get_qlp_coeff_precision()... ");
331         (void)encoder->get_qlp_coeff_precision();
332         /* we asked the encoder to auto select this so we accept anything */
333         printf("OK\n");
334
335         printf("testing get_do_qlp_coeff_prec_search()... ");
336         if(encoder->get_do_qlp_coeff_prec_search() != false) {
337                 printf("FAILED, expected false, got true\n");
338                 return false;
339         }
340         printf("OK\n");
341
342         printf("testing get_do_escape_coding()... ");
343         if(encoder->get_do_escape_coding() != false) {
344                 printf("FAILED, expected false, got true\n");
345                 return false;
346         }
347         printf("OK\n");
348
349         printf("testing get_do_exhaustive_model_search()... ");
350         if(encoder->get_do_exhaustive_model_search() != false) {
351                 printf("FAILED, expected false, got true\n");
352                 return false;
353         }
354         printf("OK\n");
355
356         printf("testing get_min_residual_partition_order()... ");
357         if(encoder->get_min_residual_partition_order() != 0) {
358                 printf("FAILED, expected %u, got %u\n", 0, encoder->get_min_residual_partition_order());
359                 return false;
360         }
361         printf("OK\n");
362
363         printf("testing get_max_residual_partition_order()... ");
364         if(encoder->get_max_residual_partition_order() != 0) {
365                 printf("FAILED, expected %u, got %u\n", 0, encoder->get_max_residual_partition_order());
366                 return false;
367         }
368         printf("OK\n");
369
370         printf("testing get_rice_parameter_search_dist()... ");
371         if(encoder->get_rice_parameter_search_dist() != 0) {
372                 printf("FAILED, expected %u, got %u\n", 0, encoder->get_rice_parameter_search_dist());
373                 return false;
374         }
375         printf("OK\n");
376
377         /* init the dummy sample buffer */
378         for(i = 0; i < sizeof(samples) / sizeof(FLAC__int32); i++)
379                 samples[i] = i & 7;
380
381         printf("testing process()... ");
382         if(!encoder->process(samples_array, sizeof(samples) / sizeof(FLAC__int32)))
383                 return encoder->die("returned false");
384         printf("OK\n");
385
386         printf("testing process_interleaved()... ");
387         if(!encoder->process_interleaved(samples, sizeof(samples) / sizeof(FLAC__int32)))
388                 return encoder->die("returned false");
389         printf("OK\n");
390
391         printf("testing finish()... ");
392         encoder->finish();
393         printf("OK\n");
394
395         printf("freeing encoder instance... ");
396         delete encoder;
397         printf("OK\n");
398
399         printf("\nPASSED!\n");
400
401         return true;
402 }
403
404 bool test_encoders()
405 {
406         init_metadata_blocks_();
407
408         if(!test_stream_encoder())
409                 return false;
410
411         free_metadata_blocks_();
412
413         return true;
414 }