diff options
Diffstat (limited to 'apps/codecs/libFLAC/file_encoder.c')
-rw-r--r-- | apps/codecs/libFLAC/file_encoder.c | 776 |
1 files changed, 776 insertions, 0 deletions
diff --git a/apps/codecs/libFLAC/file_encoder.c b/apps/codecs/libFLAC/file_encoder.c new file mode 100644 index 0000000000..db4c421f98 --- /dev/null +++ b/apps/codecs/libFLAC/file_encoder.c | |||
@@ -0,0 +1,776 @@ | |||
1 | /* libFLAC - Free Lossless Audio Codec library | ||
2 | * Copyright (C) 2002,2003,2004,2005 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 <stdio.h> | ||
33 | #include <stdlib.h> /* for malloc() */ | ||
34 | #include <string.h> /* for strlen(), strcpy() */ | ||
35 | #include "FLAC/assert.h" | ||
36 | #include "protected/file_encoder.h" | ||
37 | |||
38 | #ifdef max | ||
39 | #undef max | ||
40 | #endif | ||
41 | #define max(x,y) ((x)>(y)?(x):(y)) | ||
42 | |||
43 | /*********************************************************************** | ||
44 | * | ||
45 | * Private class method prototypes | ||
46 | * | ||
47 | ***********************************************************************/ | ||
48 | |||
49 | /* unpublished debug routines */ | ||
50 | extern FLAC__bool FLAC__seekable_stream_encoder_disable_constant_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value); | ||
51 | extern FLAC__bool FLAC__seekable_stream_encoder_disable_fixed_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value); | ||
52 | extern FLAC__bool FLAC__seekable_stream_encoder_disable_verbatim_subframes(FLAC__SeekableStreamEncoder *encoder, FLAC__bool value); | ||
53 | |||
54 | static void set_defaults_(FLAC__FileEncoder *encoder); | ||
55 | static FLAC__SeekableStreamEncoderSeekStatus seek_callback_(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data); | ||
56 | static FLAC__SeekableStreamEncoderTellStatus tell_callback_(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data); | ||
57 | static FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__SeekableStreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data); | ||
58 | |||
59 | /*********************************************************************** | ||
60 | * | ||
61 | * Private class data | ||
62 | * | ||
63 | ***********************************************************************/ | ||
64 | |||
65 | typedef struct FLAC__FileEncoderPrivate { | ||
66 | FLAC__FileEncoderProgressCallback progress_callback; | ||
67 | void *client_data; | ||
68 | char *filename; | ||
69 | FLAC__uint64 bytes_written; | ||
70 | FLAC__uint64 samples_written; | ||
71 | unsigned frames_written; | ||
72 | unsigned total_frames_estimate; | ||
73 | FLAC__SeekableStreamEncoder *seekable_stream_encoder; | ||
74 | FILE *file; | ||
75 | } FLAC__FileEncoderPrivate; | ||
76 | |||
77 | /*********************************************************************** | ||
78 | * | ||
79 | * Public static class data | ||
80 | * | ||
81 | ***********************************************************************/ | ||
82 | |||
83 | FLAC_API const char * const FLAC__FileEncoderStateString[] = { | ||
84 | "FLAC__FILE_ENCODER_OK", | ||
85 | "FLAC__FILE_ENCODER_NO_FILENAME", | ||
86 | "FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR", | ||
87 | "FLAC__FILE_ENCODER_FATAL_ERROR_WHILE_WRITING", | ||
88 | "FLAC__FILE_ENCODER_ERROR_OPENING_FILE", | ||
89 | "FLAC__FILE_ENCODER_MEMORY_ALLOCATION_ERROR", | ||
90 | "FLAC__FILE_ENCODER_ALREADY_INITIALIZED", | ||
91 | "FLAC__FILE_ENCODER_UNINITIALIZED" | ||
92 | }; | ||
93 | |||
94 | |||
95 | /*********************************************************************** | ||
96 | * | ||
97 | * Class constructor/destructor | ||
98 | * | ||
99 | ***********************************************************************/ | ||
100 | |||
101 | FLAC_API FLAC__FileEncoder *FLAC__file_encoder_new() | ||
102 | { | ||
103 | FLAC__FileEncoder *encoder; | ||
104 | |||
105 | FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */ | ||
106 | |||
107 | encoder = (FLAC__FileEncoder*)calloc(1, sizeof(FLAC__FileEncoder)); | ||
108 | if(encoder == 0) { | ||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | encoder->protected_ = (FLAC__FileEncoderProtected*)calloc(1, sizeof(FLAC__FileEncoderProtected)); | ||
113 | if(encoder->protected_ == 0) { | ||
114 | free(encoder); | ||
115 | return 0; | ||
116 | } | ||
117 | |||
118 | encoder->private_ = (FLAC__FileEncoderPrivate*)calloc(1, sizeof(FLAC__FileEncoderPrivate)); | ||
119 | if(encoder->private_ == 0) { | ||
120 | free(encoder->protected_); | ||
121 | free(encoder); | ||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | encoder->private_->seekable_stream_encoder = FLAC__seekable_stream_encoder_new(); | ||
126 | if(0 == encoder->private_->seekable_stream_encoder) { | ||
127 | free(encoder->private_); | ||
128 | free(encoder->protected_); | ||
129 | free(encoder); | ||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | encoder->private_->file = 0; | ||
134 | |||
135 | set_defaults_(encoder); | ||
136 | |||
137 | encoder->protected_->state = FLAC__FILE_ENCODER_UNINITIALIZED; | ||
138 | |||
139 | return encoder; | ||
140 | } | ||
141 | |||
142 | FLAC_API void FLAC__file_encoder_delete(FLAC__FileEncoder *encoder) | ||
143 | { | ||
144 | FLAC__ASSERT(0 != encoder); | ||
145 | FLAC__ASSERT(0 != encoder->protected_); | ||
146 | FLAC__ASSERT(0 != encoder->private_); | ||
147 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
148 | |||
149 | (void)FLAC__file_encoder_finish(encoder); | ||
150 | |||
151 | FLAC__seekable_stream_encoder_delete(encoder->private_->seekable_stream_encoder); | ||
152 | |||
153 | free(encoder->private_); | ||
154 | free(encoder->protected_); | ||
155 | free(encoder); | ||
156 | } | ||
157 | |||
158 | /*********************************************************************** | ||
159 | * | ||
160 | * Public class methods | ||
161 | * | ||
162 | ***********************************************************************/ | ||
163 | |||
164 | FLAC_API FLAC__FileEncoderState FLAC__file_encoder_init(FLAC__FileEncoder *encoder) | ||
165 | { | ||
166 | FLAC__ASSERT(0 != encoder); | ||
167 | |||
168 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
169 | return encoder->protected_->state = FLAC__FILE_ENCODER_ALREADY_INITIALIZED; | ||
170 | |||
171 | if(0 == encoder->private_->filename) | ||
172 | return encoder->protected_->state = FLAC__FILE_ENCODER_NO_FILENAME; | ||
173 | |||
174 | encoder->private_->file = fopen(encoder->private_->filename, "w+b"); | ||
175 | |||
176 | if(encoder->private_->file == 0) | ||
177 | return encoder->protected_->state = FLAC__FILE_ENCODER_ERROR_OPENING_FILE; | ||
178 | |||
179 | encoder->private_->bytes_written = 0; | ||
180 | encoder->private_->samples_written = 0; | ||
181 | encoder->private_->frames_written = 0; | ||
182 | |||
183 | FLAC__seekable_stream_encoder_set_seek_callback(encoder->private_->seekable_stream_encoder, seek_callback_); | ||
184 | FLAC__seekable_stream_encoder_set_tell_callback(encoder->private_->seekable_stream_encoder, tell_callback_); | ||
185 | FLAC__seekable_stream_encoder_set_write_callback(encoder->private_->seekable_stream_encoder, write_callback_); | ||
186 | FLAC__seekable_stream_encoder_set_client_data(encoder->private_->seekable_stream_encoder, encoder); | ||
187 | |||
188 | if(FLAC__seekable_stream_encoder_init(encoder->private_->seekable_stream_encoder) != FLAC__SEEKABLE_STREAM_ENCODER_OK) | ||
189 | return encoder->protected_->state = FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR; | ||
190 | |||
191 | { | ||
192 | unsigned blocksize = FLAC__file_encoder_get_blocksize(encoder); | ||
193 | |||
194 | FLAC__ASSERT(blocksize != 0); | ||
195 | encoder->private_->total_frames_estimate = (unsigned)((FLAC__file_encoder_get_total_samples_estimate(encoder) + blocksize - 1) / blocksize); | ||
196 | } | ||
197 | |||
198 | return encoder->protected_->state = FLAC__FILE_ENCODER_OK; | ||
199 | } | ||
200 | |||
201 | FLAC_API void FLAC__file_encoder_finish(FLAC__FileEncoder *encoder) | ||
202 | { | ||
203 | FLAC__ASSERT(0 != encoder); | ||
204 | |||
205 | if(encoder->protected_->state == FLAC__FILE_ENCODER_UNINITIALIZED) | ||
206 | return; | ||
207 | |||
208 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
209 | |||
210 | /* FLAC__seekable_stream_encoder_finish() might write data so we must close the file after it. */ | ||
211 | |||
212 | FLAC__seekable_stream_encoder_finish(encoder->private_->seekable_stream_encoder); | ||
213 | |||
214 | if(0 != encoder->private_->file) { | ||
215 | fclose(encoder->private_->file); | ||
216 | encoder->private_->file = 0; | ||
217 | } | ||
218 | |||
219 | if(0 != encoder->private_->filename) { | ||
220 | free(encoder->private_->filename); | ||
221 | encoder->private_->filename = 0; | ||
222 | } | ||
223 | |||
224 | set_defaults_(encoder); | ||
225 | |||
226 | encoder->protected_->state = FLAC__FILE_ENCODER_UNINITIALIZED; | ||
227 | } | ||
228 | |||
229 | FLAC_API FLAC__bool FLAC__file_encoder_set_verify(FLAC__FileEncoder *encoder, FLAC__bool value) | ||
230 | { | ||
231 | FLAC__ASSERT(0 != encoder); | ||
232 | FLAC__ASSERT(0 != encoder->private_); | ||
233 | FLAC__ASSERT(0 != encoder->protected_); | ||
234 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
235 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
236 | return false; | ||
237 | return FLAC__seekable_stream_encoder_set_verify(encoder->private_->seekable_stream_encoder, value); | ||
238 | } | ||
239 | |||
240 | FLAC_API FLAC__bool FLAC__file_encoder_set_streamable_subset(FLAC__FileEncoder *encoder, FLAC__bool value) | ||
241 | { | ||
242 | FLAC__ASSERT(0 != encoder); | ||
243 | FLAC__ASSERT(0 != encoder->private_); | ||
244 | FLAC__ASSERT(0 != encoder->protected_); | ||
245 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
246 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
247 | return false; | ||
248 | return FLAC__seekable_stream_encoder_set_streamable_subset(encoder->private_->seekable_stream_encoder, value); | ||
249 | } | ||
250 | |||
251 | FLAC_API FLAC__bool FLAC__file_encoder_set_do_mid_side_stereo(FLAC__FileEncoder *encoder, FLAC__bool value) | ||
252 | { | ||
253 | FLAC__ASSERT(0 != encoder); | ||
254 | FLAC__ASSERT(0 != encoder->private_); | ||
255 | FLAC__ASSERT(0 != encoder->protected_); | ||
256 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
257 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
258 | return false; | ||
259 | return FLAC__seekable_stream_encoder_set_do_mid_side_stereo(encoder->private_->seekable_stream_encoder, value); | ||
260 | } | ||
261 | |||
262 | FLAC_API FLAC__bool FLAC__file_encoder_set_loose_mid_side_stereo(FLAC__FileEncoder *encoder, FLAC__bool value) | ||
263 | { | ||
264 | FLAC__ASSERT(0 != encoder); | ||
265 | FLAC__ASSERT(0 != encoder->private_); | ||
266 | FLAC__ASSERT(0 != encoder->protected_); | ||
267 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
268 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
269 | return false; | ||
270 | return FLAC__seekable_stream_encoder_set_loose_mid_side_stereo(encoder->private_->seekable_stream_encoder, value); | ||
271 | } | ||
272 | |||
273 | FLAC_API FLAC__bool FLAC__file_encoder_set_channels(FLAC__FileEncoder *encoder, unsigned value) | ||
274 | { | ||
275 | FLAC__ASSERT(0 != encoder); | ||
276 | FLAC__ASSERT(0 != encoder->private_); | ||
277 | FLAC__ASSERT(0 != encoder->protected_); | ||
278 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
279 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
280 | return false; | ||
281 | return FLAC__seekable_stream_encoder_set_channels(encoder->private_->seekable_stream_encoder, value); | ||
282 | } | ||
283 | |||
284 | FLAC_API FLAC__bool FLAC__file_encoder_set_bits_per_sample(FLAC__FileEncoder *encoder, unsigned value) | ||
285 | { | ||
286 | FLAC__ASSERT(0 != encoder); | ||
287 | FLAC__ASSERT(0 != encoder->private_); | ||
288 | FLAC__ASSERT(0 != encoder->protected_); | ||
289 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
290 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
291 | return false; | ||
292 | return FLAC__seekable_stream_encoder_set_bits_per_sample(encoder->private_->seekable_stream_encoder, value); | ||
293 | } | ||
294 | |||
295 | FLAC_API FLAC__bool FLAC__file_encoder_set_sample_rate(FLAC__FileEncoder *encoder, unsigned value) | ||
296 | { | ||
297 | FLAC__ASSERT(0 != encoder); | ||
298 | FLAC__ASSERT(0 != encoder->private_); | ||
299 | FLAC__ASSERT(0 != encoder->protected_); | ||
300 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
301 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
302 | return false; | ||
303 | return FLAC__seekable_stream_encoder_set_sample_rate(encoder->private_->seekable_stream_encoder, value); | ||
304 | } | ||
305 | |||
306 | FLAC_API FLAC__bool FLAC__file_encoder_set_blocksize(FLAC__FileEncoder *encoder, unsigned value) | ||
307 | { | ||
308 | FLAC__ASSERT(0 != encoder); | ||
309 | FLAC__ASSERT(0 != encoder->private_); | ||
310 | FLAC__ASSERT(0 != encoder->protected_); | ||
311 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
312 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
313 | return false; | ||
314 | return FLAC__seekable_stream_encoder_set_blocksize(encoder->private_->seekable_stream_encoder, value); | ||
315 | } | ||
316 | |||
317 | FLAC_API FLAC__bool FLAC__file_encoder_set_max_lpc_order(FLAC__FileEncoder *encoder, unsigned value) | ||
318 | { | ||
319 | FLAC__ASSERT(0 != encoder); | ||
320 | FLAC__ASSERT(0 != encoder->private_); | ||
321 | FLAC__ASSERT(0 != encoder->protected_); | ||
322 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
323 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
324 | return false; | ||
325 | return FLAC__seekable_stream_encoder_set_max_lpc_order(encoder->private_->seekable_stream_encoder, value); | ||
326 | } | ||
327 | |||
328 | FLAC_API FLAC__bool FLAC__file_encoder_set_qlp_coeff_precision(FLAC__FileEncoder *encoder, unsigned value) | ||
329 | { | ||
330 | FLAC__ASSERT(0 != encoder); | ||
331 | FLAC__ASSERT(0 != encoder->private_); | ||
332 | FLAC__ASSERT(0 != encoder->protected_); | ||
333 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
334 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
335 | return false; | ||
336 | return FLAC__seekable_stream_encoder_set_qlp_coeff_precision(encoder->private_->seekable_stream_encoder, value); | ||
337 | } | ||
338 | |||
339 | FLAC_API FLAC__bool FLAC__file_encoder_set_do_qlp_coeff_prec_search(FLAC__FileEncoder *encoder, FLAC__bool value) | ||
340 | { | ||
341 | FLAC__ASSERT(0 != encoder); | ||
342 | FLAC__ASSERT(0 != encoder->private_); | ||
343 | FLAC__ASSERT(0 != encoder->protected_); | ||
344 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
345 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
346 | return false; | ||
347 | return FLAC__seekable_stream_encoder_set_do_qlp_coeff_prec_search(encoder->private_->seekable_stream_encoder, value); | ||
348 | } | ||
349 | |||
350 | FLAC_API FLAC__bool FLAC__file_encoder_set_do_escape_coding(FLAC__FileEncoder *encoder, FLAC__bool value) | ||
351 | { | ||
352 | FLAC__ASSERT(0 != encoder); | ||
353 | FLAC__ASSERT(0 != encoder->private_); | ||
354 | FLAC__ASSERT(0 != encoder->protected_); | ||
355 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
356 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
357 | return false; | ||
358 | return FLAC__seekable_stream_encoder_set_do_escape_coding(encoder->private_->seekable_stream_encoder, value); | ||
359 | } | ||
360 | |||
361 | FLAC_API FLAC__bool FLAC__file_encoder_set_do_exhaustive_model_search(FLAC__FileEncoder *encoder, FLAC__bool value) | ||
362 | { | ||
363 | FLAC__ASSERT(0 != encoder); | ||
364 | FLAC__ASSERT(0 != encoder->private_); | ||
365 | FLAC__ASSERT(0 != encoder->protected_); | ||
366 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
367 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
368 | return false; | ||
369 | return FLAC__seekable_stream_encoder_set_do_exhaustive_model_search(encoder->private_->seekable_stream_encoder, value); | ||
370 | } | ||
371 | |||
372 | FLAC_API FLAC__bool FLAC__file_encoder_set_min_residual_partition_order(FLAC__FileEncoder *encoder, unsigned value) | ||
373 | { | ||
374 | FLAC__ASSERT(0 != encoder); | ||
375 | FLAC__ASSERT(0 != encoder->private_); | ||
376 | FLAC__ASSERT(0 != encoder->protected_); | ||
377 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
378 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
379 | return false; | ||
380 | return FLAC__seekable_stream_encoder_set_min_residual_partition_order(encoder->private_->seekable_stream_encoder, value); | ||
381 | } | ||
382 | |||
383 | FLAC_API FLAC__bool FLAC__file_encoder_set_max_residual_partition_order(FLAC__FileEncoder *encoder, unsigned value) | ||
384 | { | ||
385 | FLAC__ASSERT(0 != encoder); | ||
386 | FLAC__ASSERT(0 != encoder->private_); | ||
387 | FLAC__ASSERT(0 != encoder->protected_); | ||
388 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
389 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
390 | return false; | ||
391 | return FLAC__seekable_stream_encoder_set_max_residual_partition_order(encoder->private_->seekable_stream_encoder, value); | ||
392 | } | ||
393 | |||
394 | FLAC_API FLAC__bool FLAC__file_encoder_set_rice_parameter_search_dist(FLAC__FileEncoder *encoder, unsigned value) | ||
395 | { | ||
396 | FLAC__ASSERT(0 != encoder); | ||
397 | FLAC__ASSERT(0 != encoder->private_); | ||
398 | FLAC__ASSERT(0 != encoder->protected_); | ||
399 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
400 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
401 | return false; | ||
402 | return FLAC__seekable_stream_encoder_set_rice_parameter_search_dist(encoder->private_->seekable_stream_encoder, value); | ||
403 | } | ||
404 | |||
405 | FLAC_API FLAC__bool FLAC__file_encoder_set_total_samples_estimate(FLAC__FileEncoder *encoder, FLAC__uint64 value) | ||
406 | { | ||
407 | FLAC__ASSERT(0 != encoder); | ||
408 | FLAC__ASSERT(0 != encoder->private_); | ||
409 | FLAC__ASSERT(0 != encoder->protected_); | ||
410 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
411 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
412 | return false; | ||
413 | return FLAC__seekable_stream_encoder_set_total_samples_estimate(encoder->private_->seekable_stream_encoder, value); | ||
414 | } | ||
415 | |||
416 | FLAC_API FLAC__bool FLAC__file_encoder_set_metadata(FLAC__FileEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks) | ||
417 | { | ||
418 | FLAC__ASSERT(0 != encoder); | ||
419 | FLAC__ASSERT(0 != encoder->private_); | ||
420 | FLAC__ASSERT(0 != encoder->protected_); | ||
421 | FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder); | ||
422 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
423 | return false; | ||
424 | return FLAC__seekable_stream_encoder_set_metadata(encoder->private_->seekable_stream_encoder, metadata, num_blocks); | ||
425 | } | ||
426 | |||
427 | FLAC_API FLAC__bool FLAC__file_encoder_set_filename(FLAC__FileEncoder *encoder, const char *value) | ||
428 | { | ||
429 | FLAC__ASSERT(0 != encoder); | ||
430 | FLAC__ASSERT(0 != encoder->private_); | ||
431 | FLAC__ASSERT(0 != encoder->protected_); | ||
432 | FLAC__ASSERT(0 != value); | ||
433 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
434 | return false; | ||
435 | if(0 != encoder->private_->filename) { | ||
436 | free(encoder->private_->filename); | ||
437 | encoder->private_->filename = 0; | ||
438 | } | ||
439 | if(0 == (encoder->private_->filename = (char*)malloc(strlen(value)+1))) { | ||
440 | encoder->protected_->state = FLAC__FILE_ENCODER_MEMORY_ALLOCATION_ERROR; | ||
441 | return false; | ||
442 | } | ||
443 | strcpy(encoder->private_->filename, value); | ||
444 | return true; | ||
445 | } | ||
446 | |||
447 | FLAC_API FLAC__bool FLAC__file_encoder_set_progress_callback(FLAC__FileEncoder *encoder, FLAC__FileEncoderProgressCallback value) | ||
448 | { | ||
449 | FLAC__ASSERT(0 != encoder); | ||
450 | FLAC__ASSERT(0 != encoder->private_); | ||
451 | FLAC__ASSERT(0 != encoder->protected_); | ||
452 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
453 | return false; | ||
454 | encoder->private_->progress_callback = value; | ||
455 | return true; | ||
456 | } | ||
457 | |||
458 | FLAC_API FLAC__bool FLAC__file_encoder_set_client_data(FLAC__FileEncoder *encoder, void *value) | ||
459 | { | ||
460 | FLAC__ASSERT(0 != encoder); | ||
461 | FLAC__ASSERT(0 != encoder->private_); | ||
462 | FLAC__ASSERT(0 != encoder->protected_); | ||
463 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
464 | return false; | ||
465 | encoder->private_->client_data = value; | ||
466 | return true; | ||
467 | } | ||
468 | |||
469 | /* | ||
470 | * These three functions are not static, but not publically exposed in | ||
471 | * include/FLAC/ either. They are used by the test suite. | ||
472 | */ | ||
473 | FLAC_API FLAC__bool FLAC__file_encoder_disable_constant_subframes(FLAC__FileEncoder *encoder, FLAC__bool value) | ||
474 | { | ||
475 | FLAC__ASSERT(0 != encoder); | ||
476 | FLAC__ASSERT(0 != encoder->private_); | ||
477 | FLAC__ASSERT(0 != encoder->protected_); | ||
478 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
479 | return false; | ||
480 | return FLAC__seekable_stream_encoder_disable_constant_subframes(encoder->private_->seekable_stream_encoder, value); | ||
481 | } | ||
482 | |||
483 | FLAC_API FLAC__bool FLAC__file_encoder_disable_fixed_subframes(FLAC__FileEncoder *encoder, FLAC__bool value) | ||
484 | { | ||
485 | FLAC__ASSERT(0 != encoder); | ||
486 | FLAC__ASSERT(0 != encoder->private_); | ||
487 | FLAC__ASSERT(0 != encoder->protected_); | ||
488 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
489 | return false; | ||
490 | return FLAC__seekable_stream_encoder_disable_fixed_subframes(encoder->private_->seekable_stream_encoder, value); | ||
491 | } | ||
492 | |||
493 | FLAC_API FLAC__bool FLAC__file_encoder_disable_verbatim_subframes(FLAC__FileEncoder *encoder, FLAC__bool value) | ||
494 | { | ||
495 | FLAC__ASSERT(0 != encoder); | ||
496 | FLAC__ASSERT(0 != encoder->private_); | ||
497 | FLAC__ASSERT(0 != encoder->protected_); | ||
498 | if(encoder->protected_->state != FLAC__FILE_ENCODER_UNINITIALIZED) | ||
499 | return false; | ||
500 | return FLAC__seekable_stream_encoder_disable_verbatim_subframes(encoder->private_->seekable_stream_encoder, value); | ||
501 | } | ||
502 | |||
503 | FLAC_API FLAC__FileEncoderState FLAC__file_encoder_get_state(const FLAC__FileEncoder *encoder) | ||
504 | { | ||
505 | FLAC__ASSERT(0 != encoder); | ||
506 | FLAC__ASSERT(0 != encoder->protected_); | ||
507 | return encoder->protected_->state; | ||
508 | } | ||
509 | |||
510 | FLAC_API FLAC__SeekableStreamEncoderState FLAC__file_encoder_get_seekable_stream_encoder_state(const FLAC__FileEncoder *encoder) | ||
511 | { | ||
512 | FLAC__ASSERT(0 != encoder); | ||
513 | FLAC__ASSERT(0 != encoder->private_); | ||
514 | return FLAC__seekable_stream_encoder_get_state(encoder->private_->seekable_stream_encoder); | ||
515 | } | ||
516 | |||
517 | FLAC_API FLAC__StreamEncoderState FLAC__file_encoder_get_stream_encoder_state(const FLAC__FileEncoder *encoder) | ||
518 | { | ||
519 | FLAC__ASSERT(0 != encoder); | ||
520 | FLAC__ASSERT(0 != encoder->private_); | ||
521 | return FLAC__seekable_stream_encoder_get_stream_encoder_state(encoder->private_->seekable_stream_encoder); | ||
522 | } | ||
523 | |||
524 | FLAC_API FLAC__StreamDecoderState FLAC__file_encoder_get_verify_decoder_state(const FLAC__FileEncoder *encoder) | ||
525 | { | ||
526 | FLAC__ASSERT(0 != encoder); | ||
527 | FLAC__ASSERT(0 != encoder->private_); | ||
528 | return FLAC__seekable_stream_encoder_get_verify_decoder_state(encoder->private_->seekable_stream_encoder); | ||
529 | } | ||
530 | |||
531 | FLAC_API const char *FLAC__file_encoder_get_resolved_state_string(const FLAC__FileEncoder *encoder) | ||
532 | { | ||
533 | if(encoder->protected_->state != FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR) | ||
534 | return FLAC__FileEncoderStateString[encoder->protected_->state]; | ||
535 | else | ||
536 | return FLAC__seekable_stream_encoder_get_resolved_state_string(encoder->private_->seekable_stream_encoder); | ||
537 | } | ||
538 | |||
539 | FLAC_API void FLAC__file_encoder_get_verify_decoder_error_stats(const FLAC__FileEncoder *encoder, FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got) | ||
540 | { | ||
541 | FLAC__ASSERT(0 != encoder); | ||
542 | FLAC__ASSERT(0 != encoder->private_); | ||
543 | FLAC__seekable_stream_encoder_get_verify_decoder_error_stats(encoder->private_->seekable_stream_encoder, absolute_sample, frame_number, channel, sample, expected, got); | ||
544 | } | ||
545 | |||
546 | FLAC_API FLAC__bool FLAC__file_encoder_get_verify(const FLAC__FileEncoder *encoder) | ||
547 | { | ||
548 | FLAC__ASSERT(0 != encoder); | ||
549 | FLAC__ASSERT(0 != encoder->private_); | ||
550 | return FLAC__seekable_stream_encoder_get_verify(encoder->private_->seekable_stream_encoder); | ||
551 | } | ||
552 | |||
553 | FLAC_API FLAC__bool FLAC__file_encoder_get_streamable_subset(const FLAC__FileEncoder *encoder) | ||
554 | { | ||
555 | FLAC__ASSERT(0 != encoder); | ||
556 | FLAC__ASSERT(0 != encoder->private_); | ||
557 | return FLAC__seekable_stream_encoder_get_streamable_subset(encoder->private_->seekable_stream_encoder); | ||
558 | } | ||
559 | |||
560 | FLAC_API FLAC__bool FLAC__file_encoder_get_do_mid_side_stereo(const FLAC__FileEncoder *encoder) | ||
561 | { | ||
562 | FLAC__ASSERT(0 != encoder); | ||
563 | FLAC__ASSERT(0 != encoder->private_); | ||
564 | return FLAC__seekable_stream_encoder_get_do_mid_side_stereo(encoder->private_->seekable_stream_encoder); | ||
565 | } | ||
566 | |||
567 | FLAC_API FLAC__bool FLAC__file_encoder_get_loose_mid_side_stereo(const FLAC__FileEncoder *encoder) | ||
568 | { | ||
569 | FLAC__ASSERT(0 != encoder); | ||
570 | FLAC__ASSERT(0 != encoder->private_); | ||
571 | return FLAC__seekable_stream_encoder_get_loose_mid_side_stereo(encoder->private_->seekable_stream_encoder); | ||
572 | } | ||
573 | |||
574 | FLAC_API unsigned FLAC__file_encoder_get_channels(const FLAC__FileEncoder *encoder) | ||
575 | { | ||
576 | FLAC__ASSERT(0 != encoder); | ||
577 | FLAC__ASSERT(0 != encoder->private_); | ||
578 | return FLAC__seekable_stream_encoder_get_channels(encoder->private_->seekable_stream_encoder); | ||
579 | } | ||
580 | |||
581 | FLAC_API unsigned FLAC__file_encoder_get_bits_per_sample(const FLAC__FileEncoder *encoder) | ||
582 | { | ||
583 | FLAC__ASSERT(0 != encoder); | ||
584 | FLAC__ASSERT(0 != encoder->private_); | ||
585 | return FLAC__seekable_stream_encoder_get_bits_per_sample(encoder->private_->seekable_stream_encoder); | ||
586 | } | ||
587 | |||
588 | FLAC_API unsigned FLAC__file_encoder_get_sample_rate(const FLAC__FileEncoder *encoder) | ||
589 | { | ||
590 | FLAC__ASSERT(0 != encoder); | ||
591 | FLAC__ASSERT(0 != encoder->private_); | ||
592 | return FLAC__seekable_stream_encoder_get_sample_rate(encoder->private_->seekable_stream_encoder); | ||
593 | } | ||
594 | |||
595 | FLAC_API unsigned FLAC__file_encoder_get_blocksize(const FLAC__FileEncoder *encoder) | ||
596 | { | ||
597 | FLAC__ASSERT(0 != encoder); | ||
598 | FLAC__ASSERT(0 != encoder->private_); | ||
599 | return FLAC__seekable_stream_encoder_get_blocksize(encoder->private_->seekable_stream_encoder); | ||
600 | } | ||
601 | |||
602 | FLAC_API unsigned FLAC__file_encoder_get_max_lpc_order(const FLAC__FileEncoder *encoder) | ||
603 | { | ||
604 | FLAC__ASSERT(0 != encoder); | ||
605 | FLAC__ASSERT(0 != encoder->private_); | ||
606 | return FLAC__seekable_stream_encoder_get_max_lpc_order(encoder->private_->seekable_stream_encoder); | ||
607 | } | ||
608 | |||
609 | FLAC_API unsigned FLAC__file_encoder_get_qlp_coeff_precision(const FLAC__FileEncoder *encoder) | ||
610 | { | ||
611 | FLAC__ASSERT(0 != encoder); | ||
612 | FLAC__ASSERT(0 != encoder->private_); | ||
613 | return FLAC__seekable_stream_encoder_get_qlp_coeff_precision(encoder->private_->seekable_stream_encoder); | ||
614 | } | ||
615 | |||
616 | FLAC_API FLAC__bool FLAC__file_encoder_get_do_qlp_coeff_prec_search(const FLAC__FileEncoder *encoder) | ||
617 | { | ||
618 | FLAC__ASSERT(0 != encoder); | ||
619 | FLAC__ASSERT(0 != encoder->private_); | ||
620 | return FLAC__seekable_stream_encoder_get_do_qlp_coeff_prec_search(encoder->private_->seekable_stream_encoder); | ||
621 | } | ||
622 | |||
623 | FLAC_API FLAC__bool FLAC__file_encoder_get_do_escape_coding(const FLAC__FileEncoder *encoder) | ||
624 | { | ||
625 | FLAC__ASSERT(0 != encoder); | ||
626 | FLAC__ASSERT(0 != encoder->private_); | ||
627 | return FLAC__seekable_stream_encoder_get_do_escape_coding(encoder->private_->seekable_stream_encoder); | ||
628 | } | ||
629 | |||
630 | FLAC_API FLAC__bool FLAC__file_encoder_get_do_exhaustive_model_search(const FLAC__FileEncoder *encoder) | ||
631 | { | ||
632 | FLAC__ASSERT(0 != encoder); | ||
633 | FLAC__ASSERT(0 != encoder->private_); | ||
634 | return FLAC__seekable_stream_encoder_get_do_exhaustive_model_search(encoder->private_->seekable_stream_encoder); | ||
635 | } | ||
636 | |||
637 | FLAC_API unsigned FLAC__file_encoder_get_min_residual_partition_order(const FLAC__FileEncoder *encoder) | ||
638 | { | ||
639 | FLAC__ASSERT(0 != encoder); | ||
640 | FLAC__ASSERT(0 != encoder->private_); | ||
641 | return FLAC__seekable_stream_encoder_get_min_residual_partition_order(encoder->private_->seekable_stream_encoder); | ||
642 | } | ||
643 | |||
644 | FLAC_API unsigned FLAC__file_encoder_get_max_residual_partition_order(const FLAC__FileEncoder *encoder) | ||
645 | { | ||
646 | FLAC__ASSERT(0 != encoder); | ||
647 | FLAC__ASSERT(0 != encoder->private_); | ||
648 | return FLAC__seekable_stream_encoder_get_max_residual_partition_order(encoder->private_->seekable_stream_encoder); | ||
649 | } | ||
650 | |||
651 | FLAC_API unsigned FLAC__file_encoder_get_rice_parameter_search_dist(const FLAC__FileEncoder *encoder) | ||
652 | { | ||
653 | FLAC__ASSERT(0 != encoder); | ||
654 | FLAC__ASSERT(0 != encoder->private_); | ||
655 | return FLAC__seekable_stream_encoder_get_rice_parameter_search_dist(encoder->private_->seekable_stream_encoder); | ||
656 | } | ||
657 | |||
658 | FLAC_API FLAC__uint64 FLAC__file_encoder_get_total_samples_estimate(const FLAC__FileEncoder *encoder) | ||
659 | { | ||
660 | FLAC__ASSERT(0 != encoder); | ||
661 | FLAC__ASSERT(0 != encoder->private_); | ||
662 | return FLAC__seekable_stream_encoder_get_total_samples_estimate(encoder->private_->seekable_stream_encoder); | ||
663 | } | ||
664 | |||
665 | FLAC_API FLAC__bool FLAC__file_encoder_process(FLAC__FileEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples) | ||
666 | { | ||
667 | FLAC__ASSERT(0 != encoder); | ||
668 | FLAC__ASSERT(0 != encoder->private_); | ||
669 | if(!FLAC__seekable_stream_encoder_process(encoder->private_->seekable_stream_encoder, buffer, samples)) { | ||
670 | encoder->protected_->state = FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR; | ||
671 | return false; | ||
672 | } | ||
673 | else | ||
674 | return true; | ||
675 | } | ||
676 | |||
677 | /* 'samples' is channel-wide samples, e.g. for 1 second at 44100Hz, 'samples' = 44100 regardless of the number of channels */ | ||
678 | FLAC_API FLAC__bool FLAC__file_encoder_process_interleaved(FLAC__FileEncoder *encoder, const FLAC__int32 buffer[], unsigned samples) | ||
679 | { | ||
680 | FLAC__ASSERT(0 != encoder); | ||
681 | FLAC__ASSERT(0 != encoder->private_); | ||
682 | if(!FLAC__seekable_stream_encoder_process_interleaved(encoder->private_->seekable_stream_encoder, buffer, samples)) { | ||
683 | encoder->protected_->state = FLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR; | ||
684 | return false; | ||
685 | } | ||
686 | else | ||
687 | return true; | ||
688 | } | ||
689 | |||
690 | |||
691 | /*********************************************************************** | ||
692 | * | ||
693 | * Private class methods | ||
694 | * | ||
695 | ***********************************************************************/ | ||
696 | |||
697 | void set_defaults_(FLAC__FileEncoder *encoder) | ||
698 | { | ||
699 | FLAC__ASSERT(0 != encoder); | ||
700 | FLAC__ASSERT(0 != encoder->private_); | ||
701 | |||
702 | encoder->private_->progress_callback = 0; | ||
703 | encoder->private_->client_data = 0; | ||
704 | encoder->private_->total_frames_estimate = 0; | ||
705 | encoder->private_->filename = 0; | ||
706 | } | ||
707 | |||
708 | FLAC__SeekableStreamEncoderSeekStatus seek_callback_(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data) | ||
709 | { | ||
710 | FLAC__FileEncoder *file_encoder = (FLAC__FileEncoder*)client_data; | ||
711 | |||
712 | (void)encoder; | ||
713 | |||
714 | FLAC__ASSERT(0 != file_encoder); | ||
715 | |||
716 | if(fseek(file_encoder->private_->file, (long)absolute_byte_offset, SEEK_SET) < 0) | ||
717 | return FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_ERROR; | ||
718 | else | ||
719 | return FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK; | ||
720 | } | ||
721 | |||
722 | FLAC__SeekableStreamEncoderTellStatus tell_callback_(const FLAC__SeekableStreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data) | ||
723 | { | ||
724 | FLAC__FileEncoder *file_encoder = (FLAC__FileEncoder*)client_data; | ||
725 | long offset; | ||
726 | |||
727 | (void)encoder; | ||
728 | |||
729 | FLAC__ASSERT(0 != file_encoder); | ||
730 | |||
731 | offset = ftell(file_encoder->private_->file); | ||
732 | |||
733 | if(offset < 0) { | ||
734 | return FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_ERROR; | ||
735 | } | ||
736 | else { | ||
737 | *absolute_byte_offset = (FLAC__uint64)offset; | ||
738 | return FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_OK; | ||
739 | } | ||
740 | } | ||
741 | |||
742 | #ifdef FLAC__VALGRIND_TESTING | ||
743 | static size_t local__fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) | ||
744 | { | ||
745 | size_t ret = fwrite(ptr, size, nmemb, stream); | ||
746 | if(!ferror(stream)) | ||
747 | fflush(stream); | ||
748 | return ret; | ||
749 | } | ||
750 | #else | ||
751 | #define local__fwrite fwrite | ||
752 | #endif | ||
753 | |||
754 | FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__SeekableStreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data) | ||
755 | { | ||
756 | FLAC__FileEncoder *file_encoder = (FLAC__FileEncoder*)client_data; | ||
757 | |||
758 | (void)encoder, (void)samples, (void)current_frame; | ||
759 | |||
760 | FLAC__ASSERT(0 != file_encoder); | ||
761 | |||
762 | if(local__fwrite(buffer, sizeof(FLAC__byte), bytes, file_encoder->private_->file) == bytes) { | ||
763 | file_encoder->private_->bytes_written += bytes; | ||
764 | file_encoder->private_->samples_written += samples; | ||
765 | /* we keep a high watermark on the number of frames written because | ||
766 | * when the encoder goes back to write metadata, 'current_frame' | ||
767 | * will drop back to 0. | ||
768 | */ | ||
769 | file_encoder->private_->frames_written = max(file_encoder->private_->frames_written, current_frame+1); | ||
770 | if(0 != file_encoder->private_->progress_callback && samples > 0) | ||
771 | file_encoder->private_->progress_callback(file_encoder, file_encoder->private_->bytes_written, file_encoder->private_->samples_written, file_encoder->private_->frames_written, file_encoder->private_->total_frames_estimate, file_encoder->private_->client_data); | ||
772 | return FLAC__STREAM_ENCODER_WRITE_STATUS_OK; | ||
773 | } | ||
774 | else | ||
775 | return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR; | ||
776 | } | ||