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