~ubuntu-branches/ubuntu/natty/flac/natty

« back to all changes in this revision

Viewing changes to src/libFLAC/file_encoder.c

  • Committer: Bazaar Package Importer
  • Author(s): Joshua Kwan
  • Date: 2007-05-29 22:56:36 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070529225636-ljeff8xxip09qaap
Tags: 1.1.4-1
* New upstream release. closes: #405167, #411311
  - libOggFLAC and libOggFLAC++ have been merged into libFLAC, so
    remove their corresponding packages.
  - Because of the API changes required to effect the above, there has
    been yet another soname bump. libflac7 -> libflac8 and
    libflac++5 -> libflac++6. Emails have been dispatched to the
    maintainers of dependent packages.
* Some notes on patches that were removed:
  - 02_stdin_stdout, 06_manpage_mention_utf8_convert: merged upstream
  - 08_manpage_warnings: Upstream has changed the manpage so it defintely
    can't fit in in 80 cols, so just forget about it. We'll live.
  - 05_eof_warnings_are_errors: Upstream decided to add a -w option to
    flac to treat all warnings as errors. I am going to defer to that
    for now, but if people think it's stupid let me know and I'll port
    the patch forward.
  - 04_stack_smasher: was a backport from 1.1.3, so it's obsolete.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
}