4eb20591dd4c0fbacc95048e4ecacaca63c03ce7
[platform/upstream/flac.git] / src / libFLAC++ / stream_encoder.cpp
1 /* libFLAC++ - Free Lossless Audio Codec library
2  * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009  Josh Coalson
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * - Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *
11  * - Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  *
15  * - Neither the name of the Xiph.org Foundation nor the names of its
16  * contributors may be used to endorse or promote products derived from
17  * this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31
32 #include "FLAC++/encoder.h"
33 #include "FLAC++/metadata.h"
34 #include "FLAC/assert.h"
35
36 #ifdef _MSC_VER
37 // warning C4800: 'int' : forcing to bool 'true' or 'false' (performance warning)
38 #pragma warning ( disable : 4800 )
39 #endif
40
41 namespace FLAC {
42         namespace Encoder {
43
44                 // ------------------------------------------------------------
45                 //
46                 // Stream
47                 //
48                 // ------------------------------------------------------------
49
50                 Stream::Stream():
51                 encoder_(::FLAC__stream_encoder_new())
52                 { }
53
54                 Stream::~Stream()
55                 {
56                         if(0 != encoder_) {
57                                 (void)::FLAC__stream_encoder_finish(encoder_);
58                                 ::FLAC__stream_encoder_delete(encoder_);
59                         }
60                 }
61
62                 bool Stream::is_valid() const
63                 {
64                         return 0 != encoder_;
65                 }
66
67                 bool Stream::set_ogg_serial_number(long value)
68                 {
69                         FLAC__ASSERT(is_valid());
70                         return (bool)::FLAC__stream_encoder_set_ogg_serial_number(encoder_, value);
71                 }
72
73                 bool Stream::set_verify(bool value)
74                 {
75                         FLAC__ASSERT(is_valid());
76                         return (bool)::FLAC__stream_encoder_set_verify(encoder_, value);
77                 }
78
79                 bool Stream::set_streamable_subset(bool value)
80                 {
81                         FLAC__ASSERT(is_valid());
82                         return (bool)::FLAC__stream_encoder_set_streamable_subset(encoder_, value);
83                 }
84
85                 bool Stream::set_channels(unsigned value)
86                 {
87                         FLAC__ASSERT(is_valid());
88                         return (bool)::FLAC__stream_encoder_set_channels(encoder_, value);
89                 }
90
91                 bool Stream::set_bits_per_sample(unsigned value)
92                 {
93                         FLAC__ASSERT(is_valid());
94                         return (bool)::FLAC__stream_encoder_set_bits_per_sample(encoder_, value);
95                 }
96
97                 bool Stream::set_sample_rate(unsigned value)
98                 {
99                         FLAC__ASSERT(is_valid());
100                         return (bool)::FLAC__stream_encoder_set_sample_rate(encoder_, value);
101                 }
102
103                 bool Stream::set_compression_level(unsigned value)
104                 {
105                         FLAC__ASSERT(is_valid());
106                         return (bool)::FLAC__stream_encoder_set_compression_level(encoder_, value);
107                 }
108
109                 bool Stream::set_blocksize(unsigned value)
110                 {
111                         FLAC__ASSERT(is_valid());
112                         return (bool)::FLAC__stream_encoder_set_blocksize(encoder_, value);
113                 }
114
115                 bool Stream::set_do_mid_side_stereo(bool value)
116                 {
117                         FLAC__ASSERT(is_valid());
118                         return (bool)::FLAC__stream_encoder_set_do_mid_side_stereo(encoder_, value);
119                 }
120
121                 bool Stream::set_loose_mid_side_stereo(bool value)
122                 {
123                         FLAC__ASSERT(is_valid());
124                         return (bool)::FLAC__stream_encoder_set_loose_mid_side_stereo(encoder_, value);
125                 }
126
127                 bool Stream::set_apodization(const char *specification)
128                 {
129                         FLAC__ASSERT(is_valid());
130                         return (bool)::FLAC__stream_encoder_set_apodization(encoder_, specification);
131                 }
132
133                 bool Stream::set_max_lpc_order(unsigned value)
134                 {
135                         FLAC__ASSERT(is_valid());
136                         return (bool)::FLAC__stream_encoder_set_max_lpc_order(encoder_, value);
137                 }
138
139                 bool Stream::set_qlp_coeff_precision(unsigned value)
140                 {
141                         FLAC__ASSERT(is_valid());
142                         return (bool)::FLAC__stream_encoder_set_qlp_coeff_precision(encoder_, value);
143                 }
144
145                 bool Stream::set_do_qlp_coeff_prec_search(bool value)
146                 {
147                         FLAC__ASSERT(is_valid());
148                         return (bool)::FLAC__stream_encoder_set_do_qlp_coeff_prec_search(encoder_, value);
149                 }
150
151                 bool Stream::set_do_escape_coding(bool value)
152                 {
153                         FLAC__ASSERT(is_valid());
154                         return (bool)::FLAC__stream_encoder_set_do_escape_coding(encoder_, value);
155                 }
156
157                 bool Stream::set_do_exhaustive_model_search(bool value)
158                 {
159                         FLAC__ASSERT(is_valid());
160                         return (bool)::FLAC__stream_encoder_set_do_exhaustive_model_search(encoder_, value);
161                 }
162
163                 bool Stream::set_min_residual_partition_order(unsigned value)
164                 {
165                         FLAC__ASSERT(is_valid());
166                         return (bool)::FLAC__stream_encoder_set_min_residual_partition_order(encoder_, value);
167                 }
168
169                 bool Stream::set_max_residual_partition_order(unsigned value)
170                 {
171                         FLAC__ASSERT(is_valid());
172                         return (bool)::FLAC__stream_encoder_set_max_residual_partition_order(encoder_, value);
173                 }
174
175                 bool Stream::set_rice_parameter_search_dist(unsigned value)
176                 {
177                         FLAC__ASSERT(is_valid());
178                         return (bool)::FLAC__stream_encoder_set_rice_parameter_search_dist(encoder_, value);
179                 }
180
181                 bool Stream::set_total_samples_estimate(FLAC__uint64 value)
182                 {
183                         FLAC__ASSERT(is_valid());
184                         return (bool)::FLAC__stream_encoder_set_total_samples_estimate(encoder_, value);
185                 }
186
187                 bool Stream::set_metadata(::FLAC__StreamMetadata **metadata, unsigned num_blocks)
188                 {
189                         FLAC__ASSERT(is_valid());
190                         return (bool)::FLAC__stream_encoder_set_metadata(encoder_, metadata, num_blocks);
191                 }
192
193                 bool Stream::set_metadata(FLAC::Metadata::Prototype **metadata, unsigned num_blocks)
194                 {
195                         FLAC__ASSERT(is_valid());
196 #ifndef HAVE_CXX_VARARRAYS
197                         // some compilers (MSVC++, Borland C, SunPro, some GCCs w/ -pedantic) can't handle:
198                         // ::FLAC__StreamMetadata *m[num_blocks];
199                         // so we do this ugly workaround
200                         ::FLAC__StreamMetadata **m = new ::FLAC__StreamMetadata*[num_blocks];
201 #else
202                         ::FLAC__StreamMetadata *m[num_blocks];
203 #endif
204                         for(unsigned i = 0; i < num_blocks; i++) {
205                                 // we can get away with the const_cast since we know the encoder will only correct the is_last flags
206                                 m[i] = const_cast< ::FLAC__StreamMetadata*>(static_cast<const ::FLAC__StreamMetadata*>(*metadata[i]));
207                         }
208 #ifndef HAVE_CXX_VARARRAYS
209                         // complete the hack
210                         const bool ok = (bool)::FLAC__stream_encoder_set_metadata(encoder_, m, num_blocks);
211                         delete [] m;
212                         return ok;
213 #else
214                         return (bool)::FLAC__stream_encoder_set_metadata(encoder_, m, num_blocks);
215 #endif
216                 }
217
218                 Stream::State Stream::get_state() const
219                 {
220                         FLAC__ASSERT(is_valid());
221                         return State(::FLAC__stream_encoder_get_state(encoder_));
222                 }
223
224                 Decoder::Stream::State Stream::get_verify_decoder_state() const
225                 {
226                         FLAC__ASSERT(is_valid());
227                         return Decoder::Stream::State(::FLAC__stream_encoder_get_verify_decoder_state(encoder_));
228                 }
229
230                 void Stream::get_verify_decoder_error_stats(FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got)
231                 {
232                         FLAC__ASSERT(is_valid());
233                         ::FLAC__stream_encoder_get_verify_decoder_error_stats(encoder_, absolute_sample, frame_number, channel, sample, expected, got);
234                 }
235
236                 bool Stream::get_verify() const
237                 {
238                         FLAC__ASSERT(is_valid());
239                         return (bool)::FLAC__stream_encoder_get_verify(encoder_);
240                 }
241
242                 bool Stream::get_streamable_subset() const
243                 {
244                         FLAC__ASSERT(is_valid());
245                         return (bool)::FLAC__stream_encoder_get_streamable_subset(encoder_);
246                 }
247
248                 bool Stream::get_do_mid_side_stereo() const
249                 {
250                         FLAC__ASSERT(is_valid());
251                         return (bool)::FLAC__stream_encoder_get_do_mid_side_stereo(encoder_);
252                 }
253
254                 bool Stream::get_loose_mid_side_stereo() const
255                 {
256                         FLAC__ASSERT(is_valid());
257                         return (bool)::FLAC__stream_encoder_get_loose_mid_side_stereo(encoder_);
258                 }
259
260                 unsigned Stream::get_channels() const
261                 {
262                         FLAC__ASSERT(is_valid());
263                         return ::FLAC__stream_encoder_get_channels(encoder_);
264                 }
265
266                 unsigned Stream::get_bits_per_sample() const
267                 {
268                         FLAC__ASSERT(is_valid());
269                         return ::FLAC__stream_encoder_get_bits_per_sample(encoder_);
270                 }
271
272                 unsigned Stream::get_sample_rate() const
273                 {
274                         FLAC__ASSERT(is_valid());
275                         return ::FLAC__stream_encoder_get_sample_rate(encoder_);
276                 }
277
278                 unsigned Stream::get_blocksize() const
279                 {
280                         FLAC__ASSERT(is_valid());
281                         return ::FLAC__stream_encoder_get_blocksize(encoder_);
282                 }
283
284                 unsigned Stream::get_max_lpc_order() const
285                 {
286                         FLAC__ASSERT(is_valid());
287                         return ::FLAC__stream_encoder_get_max_lpc_order(encoder_);
288                 }
289
290                 unsigned Stream::get_qlp_coeff_precision() const
291                 {
292                         FLAC__ASSERT(is_valid());
293                         return ::FLAC__stream_encoder_get_qlp_coeff_precision(encoder_);
294                 }
295
296                 bool Stream::get_do_qlp_coeff_prec_search() const
297                 {
298                         FLAC__ASSERT(is_valid());
299                         return (bool)::FLAC__stream_encoder_get_do_qlp_coeff_prec_search(encoder_);
300                 }
301
302                 bool Stream::get_do_escape_coding() const
303                 {
304                         FLAC__ASSERT(is_valid());
305                         return (bool)::FLAC__stream_encoder_get_do_escape_coding(encoder_);
306                 }
307
308                 bool Stream::get_do_exhaustive_model_search() const
309                 {
310                         FLAC__ASSERT(is_valid());
311                         return (bool)::FLAC__stream_encoder_get_do_exhaustive_model_search(encoder_);
312                 }
313
314                 unsigned Stream::get_min_residual_partition_order() const
315                 {
316                         FLAC__ASSERT(is_valid());
317                         return ::FLAC__stream_encoder_get_min_residual_partition_order(encoder_);
318                 }
319
320                 unsigned Stream::get_max_residual_partition_order() const
321                 {
322                         FLAC__ASSERT(is_valid());
323                         return ::FLAC__stream_encoder_get_max_residual_partition_order(encoder_);
324                 }
325
326                 unsigned Stream::get_rice_parameter_search_dist() const
327                 {
328                         FLAC__ASSERT(is_valid());
329                         return ::FLAC__stream_encoder_get_rice_parameter_search_dist(encoder_);
330                 }
331
332                 FLAC__uint64 Stream::get_total_samples_estimate() const
333                 {
334                         FLAC__ASSERT(is_valid());
335                         return ::FLAC__stream_encoder_get_total_samples_estimate(encoder_);
336                 }
337
338                 ::FLAC__StreamEncoderInitStatus Stream::init()
339                 {
340                         FLAC__ASSERT(is_valid());
341                         return ::FLAC__stream_encoder_init_stream(encoder_, write_callback_, seek_callback_, tell_callback_, metadata_callback_, /*client_data=*/(void*)this);
342                 }
343
344                 ::FLAC__StreamEncoderInitStatus Stream::init_ogg()
345                 {
346                         FLAC__ASSERT(is_valid());
347                         return ::FLAC__stream_encoder_init_ogg_stream(encoder_, read_callback_, write_callback_, seek_callback_, tell_callback_, metadata_callback_, /*client_data=*/(void*)this);
348                 }
349
350                 bool Stream::finish()
351                 {
352                         FLAC__ASSERT(is_valid());
353                         return (bool)::FLAC__stream_encoder_finish(encoder_);
354                 }
355
356                 bool Stream::process(const FLAC__int32 * const buffer[], unsigned samples)
357                 {
358                         FLAC__ASSERT(is_valid());
359                         return (bool)::FLAC__stream_encoder_process(encoder_, buffer, samples);
360                 }
361
362                 bool Stream::process_interleaved(const FLAC__int32 buffer[], unsigned samples)
363                 {
364                         FLAC__ASSERT(is_valid());
365                         return (bool)::FLAC__stream_encoder_process_interleaved(encoder_, buffer, samples);
366                 }
367
368                 ::FLAC__StreamEncoderReadStatus Stream::read_callback(FLAC__byte buffer[], size_t *bytes)
369                 {
370                         (void)buffer, (void)bytes;
371                         return ::FLAC__STREAM_ENCODER_READ_STATUS_UNSUPPORTED;
372                 }
373
374                 ::FLAC__StreamEncoderSeekStatus Stream::seek_callback(FLAC__uint64 absolute_byte_offset)
375                 {
376                         (void)absolute_byte_offset;
377                         return ::FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED;
378                 }
379
380                 ::FLAC__StreamEncoderTellStatus Stream::tell_callback(FLAC__uint64 *absolute_byte_offset)
381                 {
382                         (void)absolute_byte_offset;
383                         return ::FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED;
384                 }
385
386                 void Stream::metadata_callback(const ::FLAC__StreamMetadata *metadata)
387                 {
388                         (void)metadata;
389                 }
390
391                 ::FLAC__StreamEncoderReadStatus Stream::read_callback_(const ::FLAC__StreamEncoder *encoder, FLAC__byte buffer[], size_t *bytes, void *client_data)
392                 {
393                         (void)encoder;
394                         FLAC__ASSERT(0 != client_data);
395                         Stream *instance = reinterpret_cast<Stream *>(client_data);
396                         FLAC__ASSERT(0 != instance);
397                         return instance->read_callback(buffer, bytes);
398                 }
399
400                 ::FLAC__StreamEncoderWriteStatus Stream::write_callback_(const ::FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame, void *client_data)
401                 {
402                         (void)encoder;
403                         FLAC__ASSERT(0 != client_data);
404                         Stream *instance = reinterpret_cast<Stream *>(client_data);
405                         FLAC__ASSERT(0 != instance);
406                         return instance->write_callback(buffer, bytes, samples, current_frame);
407                 }
408
409                 ::FLAC__StreamEncoderSeekStatus Stream::seek_callback_(const ::FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data)
410                 {
411                         (void)encoder;
412                         FLAC__ASSERT(0 != client_data);
413                         Stream *instance = reinterpret_cast<Stream *>(client_data);
414                         FLAC__ASSERT(0 != instance);
415                         return instance->seek_callback(absolute_byte_offset);
416                 }
417
418                 ::FLAC__StreamEncoderTellStatus Stream::tell_callback_(const ::FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
419                 {
420                         (void)encoder;
421                         FLAC__ASSERT(0 != client_data);
422                         Stream *instance = reinterpret_cast<Stream *>(client_data);
423                         FLAC__ASSERT(0 != instance);
424                         return instance->tell_callback(absolute_byte_offset);
425                 }
426
427                 void Stream::metadata_callback_(const ::FLAC__StreamEncoder *encoder, const ::FLAC__StreamMetadata *metadata, void *client_data)
428                 {
429                         (void)encoder;
430                         FLAC__ASSERT(0 != client_data);
431                         Stream *instance = reinterpret_cast<Stream *>(client_data);
432                         FLAC__ASSERT(0 != instance);
433                         instance->metadata_callback(metadata);
434                 }
435
436                 // ------------------------------------------------------------
437                 //
438                 // File
439                 //
440                 // ------------------------------------------------------------
441
442                 File::File():
443                         Stream()
444                 { }
445
446                 File::~File()
447                 {
448                 }
449
450                 ::FLAC__StreamEncoderInitStatus File::init(FILE *file)
451                 {
452                         FLAC__ASSERT(is_valid());
453                         return ::FLAC__stream_encoder_init_FILE(encoder_, file, progress_callback_, /*client_data=*/(void*)this);
454                 }
455
456                 ::FLAC__StreamEncoderInitStatus File::init(const char *filename)
457                 {
458                         FLAC__ASSERT(is_valid());
459                         return ::FLAC__stream_encoder_init_file(encoder_, filename, progress_callback_, /*client_data=*/(void*)this);
460                 }
461
462                 ::FLAC__StreamEncoderInitStatus File::init(const std::string &filename)
463                 {
464                         return init(filename.c_str());
465                 }
466
467                 ::FLAC__StreamEncoderInitStatus File::init_ogg(FILE *file)
468                 {
469                         FLAC__ASSERT(is_valid());
470                         return ::FLAC__stream_encoder_init_ogg_FILE(encoder_, file, progress_callback_, /*client_data=*/(void*)this);
471                 }
472
473                 ::FLAC__StreamEncoderInitStatus File::init_ogg(const char *filename)
474                 {
475                         FLAC__ASSERT(is_valid());
476                         return ::FLAC__stream_encoder_init_ogg_file(encoder_, filename, progress_callback_, /*client_data=*/(void*)this);
477                 }
478
479                 ::FLAC__StreamEncoderInitStatus File::init_ogg(const std::string &filename)
480                 {
481                         return init_ogg(filename.c_str());
482                 }
483
484                 // This is a dummy to satisfy the pure virtual from Stream; the
485                 // read callback will never be called since we are initializing
486                 // with FLAC__stream_decoder_init_FILE() or
487                 // FLAC__stream_decoder_init_file() and those supply the read
488                 // callback internally.
489                 ::FLAC__StreamEncoderWriteStatus File::write_callback(const FLAC__byte buffer[], size_t bytes, unsigned samples, unsigned current_frame)
490                 {
491                         (void)buffer, (void)bytes, (void)samples, (void)current_frame;
492                         FLAC__ASSERT(false);
493                         return ::FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; // double protection
494                 }
495
496                 void File::progress_callback(FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate)
497                 {
498                         (void)bytes_written, (void)samples_written, (void)frames_written, (void)total_frames_estimate;
499                 }
500
501                 void File::progress_callback_(const ::FLAC__StreamEncoder *encoder, FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate, void *client_data)
502                 {
503                         (void)encoder;
504                         FLAC__ASSERT(0 != client_data);
505                         File *instance = reinterpret_cast<File *>(client_data);
506                         FLAC__ASSERT(0 != instance);
507                         instance->progress_callback(bytes_written, samples_written, frames_written, total_frames_estimate);
508                 }
509
510         }
511 }