blob: a3d6e572fd7cbdbd2a8c31ba1d0413c982aca3af [file] [log] [blame]
Josh Coalsonebece622002-08-02 06:03:18 +00001/* libFLAC++ - Free Lossless Audio Codec library
Josh Coalson0395dac2006-04-25 06:59:33 +00002 * Copyright (C) 2002,2003,2004,2005,2006 Josh Coalson
Josh Coalsonebece622002-08-02 06:03:18 +00003 *
Josh Coalsonafd81072003-01-31 23:34:56 +00004 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
Josh Coalsonebece622002-08-02 06:03:18 +00007 *
Josh Coalsonafd81072003-01-31 23:34:56 +00008 * - Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
Josh Coalsonebece622002-08-02 06:03:18 +000010 *
Josh Coalsonafd81072003-01-31 23:34:56 +000011 * - 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.
Josh Coalsonebece622002-08-02 06:03:18 +000030 */
31
32#include "FLAC++/encoder.h"
33#include "FLAC/assert.h"
34
Josh Coalsonb7eeec12003-12-18 05:16:44 +000035#ifdef _MSC_VER
36// warning C4800: 'int' : forcing to bool 'true' or 'false' (performance warning)
37#pragma warning ( disable : 4800 )
38#endif
39
Josh Coalsonebece622002-08-02 06:03:18 +000040namespace FLAC {
41 namespace Encoder {
42
43 File::File():
44 encoder_(::FLAC__file_encoder_new())
45 { }
46
47 File::~File()
48 {
49 if(0 != encoder_) {
50 ::FLAC__file_encoder_finish(encoder_);
51 ::FLAC__file_encoder_delete(encoder_);
52 }
53 }
54
55 bool File::is_valid() const
56 {
57 return 0 != encoder_;
58 }
59
Josh Coalsond86e03b2002-08-03 21:56:15 +000060 bool File::set_verify(bool value)
61 {
62 FLAC__ASSERT(is_valid());
63 return (bool)::FLAC__file_encoder_set_verify(encoder_, value);
64 }
65
Josh Coalsonebece622002-08-02 06:03:18 +000066 bool File::set_streamable_subset(bool value)
67 {
68 FLAC__ASSERT(is_valid());
69 return (bool)::FLAC__file_encoder_set_streamable_subset(encoder_, value);
70 }
71
72 bool File::set_do_mid_side_stereo(bool value)
73 {
74 FLAC__ASSERT(is_valid());
75 return (bool)::FLAC__file_encoder_set_do_mid_side_stereo(encoder_, value);
76 }
77
78 bool File::set_loose_mid_side_stereo(bool value)
79 {
80 FLAC__ASSERT(is_valid());
81 return (bool)::FLAC__file_encoder_set_loose_mid_side_stereo(encoder_, value);
82 }
83
84 bool File::set_channels(unsigned value)
85 {
86 FLAC__ASSERT(is_valid());
87 return (bool)::FLAC__file_encoder_set_channels(encoder_, value);
88 }
89
90 bool File::set_bits_per_sample(unsigned value)
91 {
92 FLAC__ASSERT(is_valid());
93 return (bool)::FLAC__file_encoder_set_bits_per_sample(encoder_, value);
94 }
95
96 bool File::set_sample_rate(unsigned value)
97 {
98 FLAC__ASSERT(is_valid());
99 return (bool)::FLAC__file_encoder_set_sample_rate(encoder_, value);
100 }
101
102 bool File::set_blocksize(unsigned value)
103 {
104 FLAC__ASSERT(is_valid());
105 return (bool)::FLAC__file_encoder_set_blocksize(encoder_, value);
106 }
107
Josh Coalson6126c832006-05-03 00:20:47 +0000108 bool File::set_apodization(const char *specification)
Josh Coalsonc4fe2692006-05-01 05:27:13 +0000109 {
110 FLAC__ASSERT(is_valid());
111 return (bool)::FLAC__file_encoder_set_apodization(encoder_, specification);
112 }
113
Josh Coalsonebece622002-08-02 06:03:18 +0000114 bool File::set_max_lpc_order(unsigned value)
115 {
116 FLAC__ASSERT(is_valid());
117 return (bool)::FLAC__file_encoder_set_max_lpc_order(encoder_, value);
118 }
119
120 bool File::set_qlp_coeff_precision(unsigned value)
121 {
122 FLAC__ASSERT(is_valid());
123 return (bool)::FLAC__file_encoder_set_qlp_coeff_precision(encoder_, value);
124 }
125
126 bool File::set_do_qlp_coeff_prec_search(bool value)
127 {
128 FLAC__ASSERT(is_valid());
129 return (bool)::FLAC__file_encoder_set_do_qlp_coeff_prec_search(encoder_, value);
130 }
131
132 bool File::set_do_escape_coding(bool value)
133 {
134 FLAC__ASSERT(is_valid());
135 return (bool)::FLAC__file_encoder_set_do_escape_coding(encoder_, value);
136 }
137
138 bool File::set_do_exhaustive_model_search(bool value)
139 {
140 FLAC__ASSERT(is_valid());
141 return (bool)::FLAC__file_encoder_set_do_exhaustive_model_search(encoder_, value);
142 }
143
144 bool File::set_min_residual_partition_order(unsigned value)
145 {
146 FLAC__ASSERT(is_valid());
147 return (bool)::FLAC__file_encoder_set_min_residual_partition_order(encoder_, value);
148 }
149
150 bool File::set_max_residual_partition_order(unsigned value)
151 {
152 FLAC__ASSERT(is_valid());
153 return (bool)::FLAC__file_encoder_set_max_residual_partition_order(encoder_, value);
154 }
155
156 bool File::set_rice_parameter_search_dist(unsigned value)
157 {
158 FLAC__ASSERT(is_valid());
159 return (bool)::FLAC__file_encoder_set_rice_parameter_search_dist(encoder_, value);
160 }
161
162 bool File::set_total_samples_estimate(FLAC__uint64 value)
163 {
164 FLAC__ASSERT(is_valid());
165 return (bool)::FLAC__file_encoder_set_total_samples_estimate(encoder_, value);
166 }
167
168 bool File::set_metadata(::FLAC__StreamMetadata **metadata, unsigned num_blocks)
169 {
170 FLAC__ASSERT(is_valid());
171 return (bool)::FLAC__file_encoder_set_metadata(encoder_, metadata, num_blocks);
172 }
173
Josh Coalson091d84f2004-07-22 01:04:22 +0000174 bool File::set_metadata(FLAC::Metadata::Prototype **metadata, unsigned num_blocks)
175 {
176 FLAC__ASSERT(is_valid());
Josh Coalsonf4c1a8e2005-01-27 03:55:35 +0000177#if (defined _MSC_VER) || (defined __SUNPRO_CC)
Josh Coalson990f7412004-07-23 05:16:11 +0000178 // MSVC++ can't handle:
179 // ::FLAC__StreamMetadata *m[num_blocks];
180 // so we do this ugly workaround
181 ::FLAC__StreamMetadata **m = new ::FLAC__StreamMetadata*[num_blocks];
182#else
Josh Coalson091d84f2004-07-22 01:04:22 +0000183 ::FLAC__StreamMetadata *m[num_blocks];
Josh Coalson990f7412004-07-23 05:16:11 +0000184#endif
Josh Coalson091d84f2004-07-22 01:04:22 +0000185 for(unsigned i = 0; i < num_blocks; i++) {
186 // we can get away with this since we know the encoder will only correct the is_last flags
187 m[i] = const_cast< ::FLAC__StreamMetadata*>((::FLAC__StreamMetadata*)metadata[i]);
188 }
Josh Coalsonf4c1a8e2005-01-27 03:55:35 +0000189#if (defined _MSC_VER) || (defined __SUNPRO_CC)
Josh Coalson990f7412004-07-23 05:16:11 +0000190 // complete the hack
191 const bool ok = (bool)::FLAC__file_encoder_set_metadata(encoder_, m, num_blocks);
192 delete [] m;
193 return ok;
194#else
Josh Coalson091d84f2004-07-22 01:04:22 +0000195 return (bool)::FLAC__file_encoder_set_metadata(encoder_, m, num_blocks);
Josh Coalson990f7412004-07-23 05:16:11 +0000196#endif
Josh Coalson091d84f2004-07-22 01:04:22 +0000197 }
198
Josh Coalsonebece622002-08-02 06:03:18 +0000199 bool File::set_filename(const char *value)
200 {
201 FLAC__ASSERT(is_valid());
202 return (bool)::FLAC__file_encoder_set_filename(encoder_, value);
203 }
204
205 File::State File::get_state() const
206 {
207 FLAC__ASSERT(is_valid());
208 return State(::FLAC__file_encoder_get_state(encoder_));
209 }
210
211 SeekableStream::State File::get_seekable_stream_encoder_state() const
212 {
213 FLAC__ASSERT(is_valid());
214 return SeekableStream::State(::FLAC__file_encoder_get_seekable_stream_encoder_state(encoder_));
215 }
216
217 Stream::State File::get_stream_encoder_state() const
218 {
219 FLAC__ASSERT(is_valid());
220 return Stream::State(::FLAC__file_encoder_get_stream_encoder_state(encoder_));
221 }
222
Josh Coalsond86e03b2002-08-03 21:56:15 +0000223 Decoder::Stream::State File::get_verify_decoder_state() const
224 {
225 FLAC__ASSERT(is_valid());
226 return Decoder::Stream::State(::FLAC__file_encoder_get_verify_decoder_state(encoder_));
227 }
228
Josh Coalson589f8c72002-08-07 23:54:55 +0000229 void File::get_verify_decoder_error_stats(FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got)
230 {
231 FLAC__ASSERT(is_valid());
Josh Coalson5f39e9f2002-08-21 05:27:01 +0000232 ::FLAC__file_encoder_get_verify_decoder_error_stats(encoder_, absolute_sample, frame_number, channel, sample, expected, got);
Josh Coalson589f8c72002-08-07 23:54:55 +0000233 }
234
Josh Coalsond86e03b2002-08-03 21:56:15 +0000235 bool File::get_verify() const
236 {
237 FLAC__ASSERT(is_valid());
238 return (bool)::FLAC__file_encoder_get_verify(encoder_);
239 }
240
Josh Coalsonebece622002-08-02 06:03:18 +0000241 bool File::get_streamable_subset() const
242 {
243 FLAC__ASSERT(is_valid());
244 return (bool)::FLAC__file_encoder_get_streamable_subset(encoder_);
245 }
246
247 bool File::get_do_mid_side_stereo() const
248 {
249 FLAC__ASSERT(is_valid());
250 return (bool)::FLAC__file_encoder_get_do_mid_side_stereo(encoder_);
251 }
252
253 bool File::get_loose_mid_side_stereo() const
254 {
255 FLAC__ASSERT(is_valid());
256 return (bool)::FLAC__file_encoder_get_loose_mid_side_stereo(encoder_);
257 }
258
259 unsigned File::get_channels() const
260 {
261 FLAC__ASSERT(is_valid());
262 return ::FLAC__file_encoder_get_channels(encoder_);
263 }
264
265 unsigned File::get_bits_per_sample() const
266 {
267 FLAC__ASSERT(is_valid());
268 return ::FLAC__file_encoder_get_bits_per_sample(encoder_);
269 }
270
271 unsigned File::get_sample_rate() const
272 {
273 FLAC__ASSERT(is_valid());
274 return ::FLAC__file_encoder_get_sample_rate(encoder_);
275 }
276
277 unsigned File::get_blocksize() const
278 {
279 FLAC__ASSERT(is_valid());
280 return ::FLAC__file_encoder_get_blocksize(encoder_);
281 }
282
283 unsigned File::get_max_lpc_order() const
284 {
285 FLAC__ASSERT(is_valid());
286 return ::FLAC__file_encoder_get_max_lpc_order(encoder_);
287 }
288
289 unsigned File::get_qlp_coeff_precision() const
290 {
291 FLAC__ASSERT(is_valid());
292 return ::FLAC__file_encoder_get_qlp_coeff_precision(encoder_);
293 }
294
295 bool File::get_do_qlp_coeff_prec_search() const
296 {
297 FLAC__ASSERT(is_valid());
298 return (bool)::FLAC__file_encoder_get_do_qlp_coeff_prec_search(encoder_);
299 }
300
301 bool File::get_do_escape_coding() const
302 {
303 FLAC__ASSERT(is_valid());
304 return (bool)::FLAC__file_encoder_get_do_escape_coding(encoder_);
305 }
306
307 bool File::get_do_exhaustive_model_search() const
308 {
309 FLAC__ASSERT(is_valid());
310 return (bool)::FLAC__file_encoder_get_do_exhaustive_model_search(encoder_);
311 }
312
313 unsigned File::get_min_residual_partition_order() const
314 {
315 FLAC__ASSERT(is_valid());
316 return ::FLAC__file_encoder_get_min_residual_partition_order(encoder_);
317 }
318
319 unsigned File::get_max_residual_partition_order() const
320 {
321 FLAC__ASSERT(is_valid());
322 return ::FLAC__file_encoder_get_max_residual_partition_order(encoder_);
323 }
324
325 unsigned File::get_rice_parameter_search_dist() const
326 {
327 FLAC__ASSERT(is_valid());
328 return ::FLAC__file_encoder_get_rice_parameter_search_dist(encoder_);
329 }
330
Josh Coalsonb5bc2492002-08-02 07:40:38 +0000331 FLAC__uint64 File::get_total_samples_estimate() const
332 {
333 FLAC__ASSERT(is_valid());
334 return ::FLAC__file_encoder_get_total_samples_estimate(encoder_);
335 }
336
Josh Coalsonebece622002-08-02 06:03:18 +0000337 File::State File::init()
338 {
339 FLAC__ASSERT(is_valid());
Josh Coalsonb5bc2492002-08-02 07:40:38 +0000340 ::FLAC__file_encoder_set_progress_callback(encoder_, progress_callback_);
341 ::FLAC__file_encoder_set_client_data(encoder_, (void*)this);
Josh Coalsonebece622002-08-02 06:03:18 +0000342 return State(::FLAC__file_encoder_init(encoder_));
343 }
344
345 void File::finish()
346 {
347 FLAC__ASSERT(is_valid());
348 ::FLAC__file_encoder_finish(encoder_);
349 }
350
351 bool File::process(const FLAC__int32 * const buffer[], unsigned samples)
352 {
353 FLAC__ASSERT(is_valid());
354 return (bool)::FLAC__file_encoder_process(encoder_, buffer, samples);
355 }
356
357 bool File::process_interleaved(const FLAC__int32 buffer[], unsigned samples)
358 {
359 FLAC__ASSERT(is_valid());
360 return (bool)::FLAC__file_encoder_process_interleaved(encoder_, buffer, samples);
361 }
362
Josh Coalson2ea08392002-08-08 22:55:45 +0000363 void File::progress_callback(FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate)
Josh Coalsonb5bc2492002-08-02 07:40:38 +0000364 {
Josh Coalson2ea08392002-08-08 22:55:45 +0000365 (void)bytes_written, (void)samples_written, (void)frames_written, (void)total_frames_estimate;
Josh Coalsonb5bc2492002-08-02 07:40:38 +0000366 }
367
Josh Coalson2ea08392002-08-08 22:55:45 +0000368 void File::progress_callback_(const ::FLAC__FileEncoder *encoder, FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate, void *client_data)
Josh Coalsonb5bc2492002-08-02 07:40:38 +0000369 {
370 (void)encoder;
371 FLAC__ASSERT(0 != client_data);
372 File *instance = reinterpret_cast<File *>(client_data);
373 FLAC__ASSERT(0 != instance);
Josh Coalson2ea08392002-08-08 22:55:45 +0000374 instance->progress_callback(bytes_written, samples_written, frames_written, total_frames_estimate);
Josh Coalsonb5bc2492002-08-02 07:40:38 +0000375 }
376
Josh Coalsonc71bfe92005-01-25 02:27:20 +0000377 }
378}