fix bug in file closing logic in _finish()
[flac.git] / src / libFLAC++ / stream_encoder.cpp
1 /* libFLAC++ - Free Lossless Audio Codec library
2  * Copyright (C) 2002,2003,2004,2005,2006  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                 Stream::Stream():
45                 encoder_(::FLAC__stream_encoder_new())
46                 { }
47
48                 Stream::Stream(::FLAC__StreamEncoder *encoder):
49                 encoder_(encoder)
50                 { }
51
52                 Stream::~Stream()
53                 {
54                         // WATCHOUT: must check for NULL not only because
55                         // ::FLAC__stream_encoder_new() might have failed in
56                         // the constructor, but also because
57                         // OggFLAC::Encoder::Stream deletes the encoder_ before
58                         // we get to it here to make the C inheritance magic
59                         // work.
60                         if(0 != encoder_) {
61                                 ::FLAC__stream_encoder_finish(encoder_);
62                                 ::FLAC__stream_encoder_delete(encoder_);
63                         }
64                 }
65
66                 bool Stream::is_valid() const
67                 {
68                         return 0 != encoder_;
69                 }
70
71                 bool Stream::set_verify(bool value)
72                 {
73                         FLAC__ASSERT(is_valid());
74                         return (bool)::FLAC__stream_encoder_set_verify(encoder_, value);
75                 }
76
77                 bool Stream::set_streamable_subset(bool value)
78                 {
79                         FLAC__ASSERT(is_valid());
80                         return (bool)::FLAC__stream_encoder_set_streamable_subset(encoder_, value);
81                 }
82
83                 bool Stream::set_do_mid_side_stereo(bool value)
84                 {
85                         FLAC__ASSERT(is_valid());
86                         return (bool)::FLAC__stream_encoder_set_do_mid_side_stereo(encoder_, value);
87                 }
88
89                 bool Stream::set_loose_mid_side_stereo(bool value)
90                 {
91                         FLAC__ASSERT(is_valid());
92                         return (bool)::FLAC__stream_encoder_set_loose_mid_side_stereo(encoder_, value);
93                 }
94
95                 bool Stream::set_channels(unsigned value)
96                 {
97                         FLAC__ASSERT(is_valid());
98                         return (bool)::FLAC__stream_encoder_set_channels(encoder_, value);
99                 }
100
101                 bool Stream::set_bits_per_sample(unsigned value)
102                 {
103                         FLAC__ASSERT(is_valid());
104                         return (bool)::FLAC__stream_encoder_set_bits_per_sample(encoder_, value);
105                 }
106
107                 bool Stream::set_sample_rate(unsigned value)
108                 {
109                         FLAC__ASSERT(is_valid());
110                         return (bool)::FLAC__stream_encoder_set_sample_rate(encoder_, value);
111                 }
112
113                 bool Stream::set_blocksize(unsigned value)
114                 {
115                         FLAC__ASSERT(is_valid());
116                         return (bool)::FLAC__stream_encoder_set_blocksize(encoder_, value);
117                 }
118
119                 bool Stream::set_apodization(const char *specification)
120                 {
121                         FLAC__ASSERT(is_valid());
122                         return (bool)::FLAC__stream_encoder_set_apodization(encoder_, specification);
123                 }
124
125                 bool Stream::set_max_lpc_order(unsigned value)
126                 {
127                         FLAC__ASSERT(is_valid());
128                         return (bool)::FLAC__stream_encoder_set_max_lpc_order(encoder_, value);
129                 }
130
131                 bool Stream::set_qlp_coeff_precision(unsigned value)
132                 {
133                         FLAC__ASSERT(is_valid());
134                         return (bool)::FLAC__stream_encoder_set_qlp_coeff_precision(encoder_, value);
135                 }
136
137                 bool Stream::set_do_qlp_coeff_prec_search(bool value)
138                 {
139                         FLAC__ASSERT(is_valid());
140                         return (bool)::FLAC__stream_encoder_set_do_qlp_coeff_prec_search(encoder_, value);
141                 }
142
143                 bool Stream::set_do_escape_coding(bool value)
144                 {
145                         FLAC__ASSERT(is_valid());
146                         return (bool)::FLAC__stream_encoder_set_do_escape_coding(encoder_, value);
147                 }
148
149                 bool Stream::set_do_exhaustive_model_search(bool value)
150                 {
151                         FLAC__ASSERT(is_valid());
152                         return (bool)::FLAC__stream_encoder_set_do_exhaustive_model_search(encoder_, value);
153                 }
154
155                 bool Stream::set_min_residual_partition_order(unsigned value)
156                 {
157                         FLAC__ASSERT(is_valid());
158                         return (bool)::FLAC__stream_encoder_set_min_residual_partition_order(encoder_, value);
159                 }
160
161                 bool Stream::set_max_residual_partition_order(unsigned value)
162                 {
163                         FLAC__ASSERT(is_valid());
164                         return (bool)::FLAC__stream_encoder_set_max_residual_partition_order(encoder_, value);
165                 }
166
167                 bool Stream::set_rice_parameter_search_dist(unsigned value)
168                 {
169                         FLAC__ASSERT(is_valid());
170                         return (bool)::FLAC__stream_encoder_set_rice_parameter_search_dist(encoder_, value);
171                 }
172
173                 bool Stream::set_total_samples_estimate(FLAC__uint64 value)
174                 {
175                         FLAC__ASSERT(is_valid());
176                         return (bool)::FLAC__stream_encoder_set_total_samples_estimate(encoder_, value);
177                 }
178
179                 bool Stream::set_metadata(::FLAC__StreamMetadata **metadata, unsigned num_blocks)
180                 {
181                         FLAC__ASSERT(is_valid());
182                         return (bool)::FLAC__stream_encoder_set_metadata(encoder_, metadata, num_blocks);
183                 }
184
185                 bool Stream::set_metadata(FLAC::Metadata::Prototype **metadata, unsigned num_blocks)
186                 {
187                         FLAC__ASSERT(is_valid());
188 #if (defined _MSC_VER) || (defined __SUNPRO_CC)
189                         // MSVC++ can't handle:
190                         // ::FLAC__StreamMetadata *m[num_blocks];
191                         // so we do this ugly workaround
192                         ::FLAC__StreamMetadata **m = new ::FLAC__StreamMetadata*[num_blocks];
193 #else
194                         ::FLAC__StreamMetadata *m[num_blocks];
195 #endif
196                         for(unsigned i = 0; i < num_blocks; i++) {
197                                 // we can get away with the const_cast since we know the encoder will only correct the is_last flags
198                                 m[i] = const_cast< ::FLAC__StreamMetadata*>((const ::FLAC__StreamMetadata*)metadata[i]);
199                         }
200 #if (defined _MSC_VER) || (defined __SUNPRO_CC)
201                         // complete the hack
202                         const bool ok = (bool)::FLAC__stream_encoder_set_metadata(encoder_, m, num_blocks);
203                         delete [] m;
204                         return ok;
205 #else
206                         return (bool)::FLAC__stream_encoder_set_metadata(encoder_, m, num_blocks);
207 #endif
208                 }
209
210                 Stream::State Stream::get_state() const
211                 {
212                         FLAC__ASSERT(is_valid());
213                         return State(::FLAC__stream_encoder_get_state(encoder_));
214                 }
215
216                 Decoder::Stream::State Stream::get_verify_decoder_state() const
217                 {
218                         FLAC__ASSERT(is_valid());
219                         return Decoder::Stream::State(::FLAC__stream_encoder_get_verify_decoder_state(encoder_));
220                 }
221
222                 void Stream::get_verify_decoder_error_stats(FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got)
223                 {
224                         FLAC__ASSERT(is_valid());
225                         ::FLAC__stream_encoder_get_verify_decoder_error_stats(encoder_, absolute_sample, frame_number, channel, sample, expected, got);
226                 }
227
228                 bool Stream::get_verify() const
229                 {
230                         FLAC__ASSERT(is_valid());
231                         return (bool)::FLAC__stream_encoder_get_verify(encoder_);
232                 }
233
234                 bool Stream::get_streamable_subset() const
235                 {
236                         FLAC__ASSERT(is_valid());
237                         return (bool)::FLAC__stream_encoder_get_streamable_subset(encoder_);
238                 }
239
240                 bool Stream::get_do_mid_side_stereo() const
241                 {
242                         FLAC__ASSERT(is_valid());
243                         return (bool)::FLAC__stream_encoder_get_do_mid_side_stereo(encoder_);
244                 }
245
246                 bool Stream::get_loose_mid_side_stereo() const
247                 {
248                         FLAC__ASSERT(is_valid());
249                         return (bool)::FLAC__stream_encoder_get_loose_mid_side_stereo(encoder_);
250                 }
251
252                 unsigned Stream::get_channels() const
253                 {
254                         FLAC__ASSERT(is_valid());
255                         return ::FLAC__stream_encoder_get_channels(encoder_);
256                 }
257
258                 unsigned Stream::get_bits_per_sample() const
259                 {
260                         FLAC__ASSERT(is_valid());
261                         return ::FLAC__stream_encoder_get_bits_per_sample(encoder_);
262                 }
263
264                 unsigned Stream::get_sample_rate() const
265                 {
266                         FLAC__ASSERT(is_valid());
267                         return ::FLAC__stream_encoder_get_sample_rate(encoder_);
268                 }
269
270                 unsigned Stream::get_blocksize() const
271                 {
272                         FLAC__ASSERT(is_valid());
273                         return ::FLAC__stream_encoder_get_blocksize(encoder_);
274                 }
275
276                 unsigned Stream::get_max_lpc_order() const
277                 {
278                         FLAC__ASSERT(is_valid());
279                         return ::FLAC__stream_encoder_get_max_lpc_order(encoder_);
280                 }
281
282                 unsigned Stream::get_qlp_coeff_precision() const
283                 {
284                         FLAC__ASSERT(is_valid());
285                         return ::FLAC__stream_encoder_get_qlp_coeff_precision(encoder_);
286                 }
287
288                 bool Stream::get_do_qlp_coeff_prec_search() const
289                 {
290                         FLAC__ASSERT(is_valid());
291                         return (bool)::FLAC__stream_encoder_get_do_qlp_coeff_prec_search(encoder_);
292                 }
293
294                 bool Stream::get_do_escape_coding() const
295                 {
296                         FLAC__ASSERT(is_valid());
297                         return (bool)::FLAC__stream_encoder_get_do_escape_coding(encoder_);
298                 }
299
300                 bool Stream::get_do_exhaustive_model_search() const
301                 {
302                         FLAC__ASSERT(is_valid());
303                         return (bool)::FLAC__stream_encoder_get_do_exhaustive_model_search(encoder_);
304                 }
305
306                 unsigned Stream::get_min_residual_partition_order() const
307                 {
308                         FLAC__ASSERT(is_valid());
309                         return ::FLAC__stream_encoder_get_min_residual_partition_order(encoder_);
310                 }
311
312                 unsigned Stream::get_max_residual_partition_order() const
313                 {
314                         FLAC__ASSERT(is_valid());
315                         return ::FLAC__stream_encoder_get_max_residual_partition_order(encoder_);
316                 }
317
318                 unsigned Stream::get_rice_parameter_search_dist() const
319                 {
320                         FLAC__ASSERT(is_valid());
321                         return ::FLAC__stream_encoder_get_rice_parameter_search_dist(encoder_);
322                 }
323
324                 FLAC__uint64 Stream::get_total_samples_estimate() const
325                 {
326                         FLAC__ASSERT(is_valid());
327                         return ::FLAC__stream_encoder_get_total_samples_estimate(encoder_);
328                 }
329
330                 ::FLAC__StreamEncoderInitStatus Stream::init()
331                 {
332                         FLAC__ASSERT(is_valid());
333                         return ::FLAC__stream_encoder_init_stream(encoder_, write_callback_, seek_callback_, tell_callback_, metadata_callback_, /*client_data=*/(void*)this);
334                 }
335
336                 void Stream::finish()
337                 {
338                         FLAC__ASSERT(is_valid());
339                         ::FLAC__stream_encoder_finish(encoder_);
340                 }
341
342                 bool Stream::process(const FLAC__int32 * const buffer[], unsigned samples)
343                 {
344                         FLAC__ASSERT(is_valid());
345                         return (bool)::FLAC__stream_encoder_process(encoder_, buffer, samples);
346                 }
347
348                 bool Stream::process_interleaved(const FLAC__int32 buffer[], unsigned samples)
349                 {
350                         FLAC__ASSERT(is_valid());
351                         return (bool)::FLAC__stream_encoder_process_interleaved(encoder_, buffer, samples);
352                 }
353
354                 ::FLAC__StreamEncoderSeekStatus Stream::seek_callback(FLAC__uint64 absolute_byte_offset)
355                 {
356                         (void)absolute_byte_offset;
357                         return ::FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED;
358                 }
359
360                 ::FLAC__StreamEncoderTellStatus Stream::tell_callback(FLAC__uint64 *absolute_byte_offset)
361                 {
362                         (void)absolute_byte_offset;
363                         return ::FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED;
364                 }
365
366                 void Stream::metadata_callback(const ::FLAC__StreamMetadata *metadata)
367                 {
368                         (void)metadata;
369                 }
370
371                 ::FLAC__StreamEncoderWriteStatus Stream::write_callback_(const ::FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
372                 {
373                         (void)encoder;
374                         FLAC__ASSERT(0 != client_data);
375                         Stream *instance = reinterpret_cast<Stream *>(client_data);
376                         FLAC__ASSERT(0 != instance);
377                         return instance->write_callback(buffer, bytes, samples, current_frame);
378                 }
379
380                 ::FLAC__StreamEncoderSeekStatus Stream::seek_callback_(const ::FLAC__StreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data)
381                 {
382                         (void)encoder;
383                         FLAC__ASSERT(0 != client_data);
384                         Stream *instance = reinterpret_cast<Stream *>(client_data);
385                         FLAC__ASSERT(0 != instance);
386                         return instance->seek_callback(absolute_byte_offset);
387                 }
388
389                 ::FLAC__StreamEncoderTellStatus Stream::tell_callback_(const ::FLAC__StreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
390                 {
391                         (void)encoder;
392                         FLAC__ASSERT(0 != client_data);
393                         Stream *instance = reinterpret_cast<Stream *>(client_data);
394                         FLAC__ASSERT(0 != instance);
395                         return instance->tell_callback(absolute_byte_offset);
396                 }
397
398                 void Stream::metadata_callback_(const ::FLAC__StreamEncoder *encoder, const ::FLAC__StreamMetadata *metadata, void *client_data)
399                 {
400                         (void)encoder;
401                         FLAC__ASSERT(0 != client_data);
402                         Stream *instance = reinterpret_cast<Stream *>(client_data);
403                         FLAC__ASSERT(0 != instance);
404                         instance->metadata_callback(metadata);
405                 }
406
407         }
408 }