~ubuntu-branches/ubuntu/raring/flac/raring

« back to all changes in this revision

Viewing changes to src/libOggFLAC/file_encoder.c

  • Committer: Bazaar Package Importer
  • Author(s): Joshua Kwan
  • Date: 2007-05-29 22:56:36 UTC
  • mto: (8.1.1 lenny)
  • mto: This revision was merged to the branch mainline in revision 9.
  • Revision ID: james.westby@ubuntu.com-20070529225636-p8lkii0r0kp50pns
Tags: upstream-1.1.4
ImportĀ upstreamĀ versionĀ 1.1.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* libOggFLAC - Free Lossless Audio Codec + Ogg 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 "OggFLAC/seekable_stream_encoder.h"
37
 
#include "protected/file_encoder.h"
38
 
 
39
 
#ifdef max
40
 
#undef max
41
 
#endif
42
 
#define max(x,y) ((x)>(y)?(x):(y))
43
 
 
44
 
/***********************************************************************
45
 
 *
46
 
 * Private class method prototypes
47
 
 *
48
 
 ***********************************************************************/
49
 
 
50
 
/* unpublished debug routines */
51
 
extern FLAC__bool OggFLAC__seekable_stream_encoder_disable_constant_subframes(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value);
52
 
extern FLAC__bool OggFLAC__seekable_stream_encoder_disable_fixed_subframes(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value);
53
 
extern FLAC__bool OggFLAC__seekable_stream_encoder_disable_verbatim_subframes(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value);
54
 
 
55
 
static void set_defaults_(OggFLAC__FileEncoder *encoder);
56
 
static OggFLAC__SeekableStreamEncoderReadStatus read_callback_(const OggFLAC__SeekableStreamEncoder *encoder, FLAC__byte buffer[], unsigned *bytes, void *client_data);
57
 
static FLAC__SeekableStreamEncoderSeekStatus seek_callback_(const OggFLAC__SeekableStreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data);
58
 
static FLAC__SeekableStreamEncoderTellStatus tell_callback_(const OggFLAC__SeekableStreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data);
59
 
static FLAC__StreamEncoderWriteStatus write_callback_(const OggFLAC__SeekableStreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data);
60
 
 
61
 
/***********************************************************************
62
 
 *
63
 
 * Private class data
64
 
 *
65
 
 ***********************************************************************/
66
 
 
67
 
typedef struct OggFLAC__FileEncoderPrivate {
68
 
        OggFLAC__FileEncoderProgressCallback progress_callback;
69
 
        void *client_data;
70
 
        char *filename;
71
 
        FLAC__uint64 bytes_written;
72
 
        FLAC__uint64 samples_written;
73
 
        unsigned frames_written;
74
 
        unsigned total_frames_estimate;
75
 
        OggFLAC__SeekableStreamEncoder *seekable_stream_encoder;
76
 
        FILE *file;
77
 
} OggFLAC__FileEncoderPrivate;
78
 
 
79
 
/***********************************************************************
80
 
 *
81
 
 * Public static class data
82
 
 *
83
 
 ***********************************************************************/
84
 
 
85
 
OggFLAC_API const char * const OggFLAC__FileEncoderStateString[] = {
86
 
        "OggFLAC__FILE_ENCODER_OK",
87
 
        "OggFLAC__FILE_ENCODER_NO_FILENAME",
88
 
        "OggFLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR",
89
 
        "OggFLAC__FILE_ENCODER_FATAL_ERROR_WHILE_WRITING",
90
 
        "OggFLAC__FILE_ENCODER_ERROR_OPENING_FILE",
91
 
        "OggFLAC__FILE_ENCODER_MEMORY_ALLOCATION_ERROR",
92
 
        "OggFLAC__FILE_ENCODER_ALREADY_INITIALIZED",
93
 
        "OggFLAC__FILE_ENCODER_UNINITIALIZED"
94
 
};
95
 
 
96
 
 
97
 
/***********************************************************************
98
 
 *
99
 
 * Class constructor/destructor
100
 
 *
101
 
 ***********************************************************************/
102
 
 
103
 
OggFLAC_API OggFLAC__FileEncoder *OggFLAC__file_encoder_new()
104
 
{
105
 
        OggFLAC__FileEncoder *encoder;
106
 
 
107
 
        FLAC__ASSERT(sizeof(int) >= 4); /* we want to die right away if this is not true */
108
 
 
109
 
        encoder = (OggFLAC__FileEncoder*)calloc(1, sizeof(OggFLAC__FileEncoder));
110
 
        if(encoder == 0) {
111
 
                return 0;
112
 
        }
113
 
 
114
 
        encoder->protected_ = (OggFLAC__FileEncoderProtected*)calloc(1, sizeof(OggFLAC__FileEncoderProtected));
115
 
        if(encoder->protected_ == 0) {
116
 
                free(encoder);
117
 
                return 0;
118
 
        }
119
 
 
120
 
        encoder->private_ = (OggFLAC__FileEncoderPrivate*)calloc(1, sizeof(OggFLAC__FileEncoderPrivate));
121
 
        if(encoder->private_ == 0) {
122
 
                free(encoder->protected_);
123
 
                free(encoder);
124
 
                return 0;
125
 
        }
126
 
 
127
 
        encoder->private_->seekable_stream_encoder = OggFLAC__seekable_stream_encoder_new();
128
 
        if(0 == encoder->private_->seekable_stream_encoder) {
129
 
                free(encoder->private_);
130
 
                free(encoder->protected_);
131
 
                free(encoder);
132
 
                return 0;
133
 
        }
134
 
 
135
 
        encoder->private_->file = 0;
136
 
 
137
 
        set_defaults_(encoder);
138
 
 
139
 
        encoder->protected_->state = OggFLAC__FILE_ENCODER_UNINITIALIZED;
140
 
 
141
 
        return encoder;
142
 
}
143
 
 
144
 
OggFLAC_API void OggFLAC__file_encoder_delete(OggFLAC__FileEncoder *encoder)
145
 
{
146
 
        FLAC__ASSERT(0 != encoder);
147
 
        FLAC__ASSERT(0 != encoder->protected_);
148
 
        FLAC__ASSERT(0 != encoder->private_);
149
 
        FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
150
 
 
151
 
        (void)OggFLAC__file_encoder_finish(encoder);
152
 
 
153
 
        OggFLAC__seekable_stream_encoder_delete(encoder->private_->seekable_stream_encoder);
154
 
 
155
 
        free(encoder->private_);
156
 
        free(encoder->protected_);
157
 
        free(encoder);
158
 
}
159
 
 
160
 
/***********************************************************************
161
 
 *
162
 
 * Public class methods
163
 
 *
164
 
 ***********************************************************************/
165
 
 
166
 
OggFLAC_API OggFLAC__FileEncoderState OggFLAC__file_encoder_init(OggFLAC__FileEncoder *encoder)
167
 
{
168
 
        FLAC__ASSERT(0 != encoder);
169
 
 
170
 
        if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
171
 
                return encoder->protected_->state = OggFLAC__FILE_ENCODER_ALREADY_INITIALIZED;
172
 
 
173
 
        if(0 == encoder->private_->filename)
174
 
                return encoder->protected_->state = OggFLAC__FILE_ENCODER_NO_FILENAME;
175
 
 
176
 
        encoder->private_->file = fopen(encoder->private_->filename, "w+b");
177
 
 
178
 
        if(encoder->private_->file == 0)
179
 
                return encoder->protected_->state = OggFLAC__FILE_ENCODER_ERROR_OPENING_FILE;
180
 
 
181
 
        encoder->private_->bytes_written = 0;
182
 
        encoder->private_->samples_written = 0;
183
 
        encoder->private_->frames_written = 0;
184
 
 
185
 
        OggFLAC__seekable_stream_encoder_set_read_callback(encoder->private_->seekable_stream_encoder, read_callback_);
186
 
        OggFLAC__seekable_stream_encoder_set_seek_callback(encoder->private_->seekable_stream_encoder, seek_callback_);
187
 
        OggFLAC__seekable_stream_encoder_set_tell_callback(encoder->private_->seekable_stream_encoder, tell_callback_);
188
 
        OggFLAC__seekable_stream_encoder_set_write_callback(encoder->private_->seekable_stream_encoder, write_callback_);
189
 
        OggFLAC__seekable_stream_encoder_set_client_data(encoder->private_->seekable_stream_encoder, encoder);
190
 
 
191
 
        if(OggFLAC__seekable_stream_encoder_init(encoder->private_->seekable_stream_encoder) != OggFLAC__SEEKABLE_STREAM_ENCODER_OK)
192
 
                return encoder->protected_->state = OggFLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR;
193
 
 
194
 
        {
195
 
                unsigned blocksize = OggFLAC__file_encoder_get_blocksize(encoder);
196
 
 
197
 
                FLAC__ASSERT(blocksize != 0);
198
 
                encoder->private_->total_frames_estimate = (unsigned)((OggFLAC__file_encoder_get_total_samples_estimate(encoder) + blocksize - 1) / blocksize);
199
 
        }
200
 
 
201
 
        return encoder->protected_->state = OggFLAC__FILE_ENCODER_OK;
202
 
}
203
 
 
204
 
OggFLAC_API void OggFLAC__file_encoder_finish(OggFLAC__FileEncoder *encoder)
205
 
{
206
 
        FLAC__ASSERT(0 != encoder);
207
 
 
208
 
        if(encoder->protected_->state == OggFLAC__FILE_ENCODER_UNINITIALIZED)
209
 
                return;
210
 
 
211
 
        FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
212
 
 
213
 
        /* OggFLAC__seekable_stream_encoder_finish() might write data so we must close the file after it. */
214
 
 
215
 
        OggFLAC__seekable_stream_encoder_finish(encoder->private_->seekable_stream_encoder);
216
 
 
217
 
        if(0 != encoder->private_->file) {
218
 
                fclose(encoder->private_->file);
219
 
                encoder->private_->file = 0;
220
 
        }
221
 
 
222
 
        if(0 != encoder->private_->filename) {
223
 
                free(encoder->private_->filename);
224
 
                encoder->private_->filename = 0;
225
 
        }
226
 
 
227
 
        set_defaults_(encoder);
228
 
 
229
 
        encoder->protected_->state = OggFLAC__FILE_ENCODER_UNINITIALIZED;
230
 
}
231
 
 
232
 
OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_serial_number(OggFLAC__FileEncoder *encoder, long serial_number)
233
 
{
234
 
        FLAC__ASSERT(0 != encoder);
235
 
        FLAC__ASSERT(0 != encoder->private_);
236
 
        FLAC__ASSERT(0 != encoder->protected_);
237
 
        FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
238
 
        if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
239
 
                return false;
240
 
        return OggFLAC__seekable_stream_encoder_set_serial_number(encoder->private_->seekable_stream_encoder, serial_number);
241
 
}
242
 
 
243
 
OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_verify(OggFLAC__FileEncoder *encoder, FLAC__bool value)
244
 
{
245
 
        FLAC__ASSERT(0 != encoder);
246
 
        FLAC__ASSERT(0 != encoder->private_);
247
 
        FLAC__ASSERT(0 != encoder->protected_);
248
 
        FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
249
 
        if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
250
 
                return false;
251
 
        return OggFLAC__seekable_stream_encoder_set_verify(encoder->private_->seekable_stream_encoder, value);
252
 
}
253
 
 
254
 
OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_streamable_subset(OggFLAC__FileEncoder *encoder, FLAC__bool value)
255
 
{
256
 
        FLAC__ASSERT(0 != encoder);
257
 
        FLAC__ASSERT(0 != encoder->private_);
258
 
        FLAC__ASSERT(0 != encoder->protected_);
259
 
        FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
260
 
        if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
261
 
                return false;
262
 
        return OggFLAC__seekable_stream_encoder_set_streamable_subset(encoder->private_->seekable_stream_encoder, value);
263
 
}
264
 
 
265
 
OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_do_mid_side_stereo(OggFLAC__FileEncoder *encoder, FLAC__bool value)
266
 
{
267
 
        FLAC__ASSERT(0 != encoder);
268
 
        FLAC__ASSERT(0 != encoder->private_);
269
 
        FLAC__ASSERT(0 != encoder->protected_);
270
 
        FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
271
 
        if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
272
 
                return false;
273
 
        return OggFLAC__seekable_stream_encoder_set_do_mid_side_stereo(encoder->private_->seekable_stream_encoder, value);
274
 
}
275
 
 
276
 
OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_loose_mid_side_stereo(OggFLAC__FileEncoder *encoder, FLAC__bool value)
277
 
{
278
 
        FLAC__ASSERT(0 != encoder);
279
 
        FLAC__ASSERT(0 != encoder->private_);
280
 
        FLAC__ASSERT(0 != encoder->protected_);
281
 
        FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
282
 
        if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
283
 
                return false;
284
 
        return OggFLAC__seekable_stream_encoder_set_loose_mid_side_stereo(encoder->private_->seekable_stream_encoder, value);
285
 
}
286
 
 
287
 
OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_channels(OggFLAC__FileEncoder *encoder, unsigned value)
288
 
{
289
 
        FLAC__ASSERT(0 != encoder);
290
 
        FLAC__ASSERT(0 != encoder->private_);
291
 
        FLAC__ASSERT(0 != encoder->protected_);
292
 
        FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
293
 
        if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
294
 
                return false;
295
 
        return OggFLAC__seekable_stream_encoder_set_channels(encoder->private_->seekable_stream_encoder, value);
296
 
}
297
 
 
298
 
OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_bits_per_sample(OggFLAC__FileEncoder *encoder, unsigned value)
299
 
{
300
 
        FLAC__ASSERT(0 != encoder);
301
 
        FLAC__ASSERT(0 != encoder->private_);
302
 
        FLAC__ASSERT(0 != encoder->protected_);
303
 
        FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
304
 
        if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
305
 
                return false;
306
 
        return OggFLAC__seekable_stream_encoder_set_bits_per_sample(encoder->private_->seekable_stream_encoder, value);
307
 
}
308
 
 
309
 
OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_sample_rate(OggFLAC__FileEncoder *encoder, unsigned value)
310
 
{
311
 
        FLAC__ASSERT(0 != encoder);
312
 
        FLAC__ASSERT(0 != encoder->private_);
313
 
        FLAC__ASSERT(0 != encoder->protected_);
314
 
        FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
315
 
        if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
316
 
                return false;
317
 
        return OggFLAC__seekable_stream_encoder_set_sample_rate(encoder->private_->seekable_stream_encoder, value);
318
 
}
319
 
 
320
 
OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_blocksize(OggFLAC__FileEncoder *encoder, unsigned value)
321
 
{
322
 
        FLAC__ASSERT(0 != encoder);
323
 
        FLAC__ASSERT(0 != encoder->private_);
324
 
        FLAC__ASSERT(0 != encoder->protected_);
325
 
        FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
326
 
        if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
327
 
                return false;
328
 
        return OggFLAC__seekable_stream_encoder_set_blocksize(encoder->private_->seekable_stream_encoder, value);
329
 
}
330
 
 
331
 
OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_max_lpc_order(OggFLAC__FileEncoder *encoder, unsigned value)
332
 
{
333
 
        FLAC__ASSERT(0 != encoder);
334
 
        FLAC__ASSERT(0 != encoder->private_);
335
 
        FLAC__ASSERT(0 != encoder->protected_);
336
 
        FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
337
 
        if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
338
 
                return false;
339
 
        return OggFLAC__seekable_stream_encoder_set_max_lpc_order(encoder->private_->seekable_stream_encoder, value);
340
 
}
341
 
 
342
 
OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_qlp_coeff_precision(OggFLAC__FileEncoder *encoder, unsigned value)
343
 
{
344
 
        FLAC__ASSERT(0 != encoder);
345
 
        FLAC__ASSERT(0 != encoder->private_);
346
 
        FLAC__ASSERT(0 != encoder->protected_);
347
 
        FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
348
 
        if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
349
 
                return false;
350
 
        return OggFLAC__seekable_stream_encoder_set_qlp_coeff_precision(encoder->private_->seekable_stream_encoder, value);
351
 
}
352
 
 
353
 
OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_do_qlp_coeff_prec_search(OggFLAC__FileEncoder *encoder, FLAC__bool value)
354
 
{
355
 
        FLAC__ASSERT(0 != encoder);
356
 
        FLAC__ASSERT(0 != encoder->private_);
357
 
        FLAC__ASSERT(0 != encoder->protected_);
358
 
        FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
359
 
        if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
360
 
                return false;
361
 
        return OggFLAC__seekable_stream_encoder_set_do_qlp_coeff_prec_search(encoder->private_->seekable_stream_encoder, value);
362
 
}
363
 
 
364
 
OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_do_escape_coding(OggFLAC__FileEncoder *encoder, FLAC__bool value)
365
 
{
366
 
        FLAC__ASSERT(0 != encoder);
367
 
        FLAC__ASSERT(0 != encoder->private_);
368
 
        FLAC__ASSERT(0 != encoder->protected_);
369
 
        FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
370
 
        if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
371
 
                return false;
372
 
        return OggFLAC__seekable_stream_encoder_set_do_escape_coding(encoder->private_->seekable_stream_encoder, value);
373
 
}
374
 
 
375
 
OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_do_exhaustive_model_search(OggFLAC__FileEncoder *encoder, FLAC__bool value)
376
 
{
377
 
        FLAC__ASSERT(0 != encoder);
378
 
        FLAC__ASSERT(0 != encoder->private_);
379
 
        FLAC__ASSERT(0 != encoder->protected_);
380
 
        FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
381
 
        if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
382
 
                return false;
383
 
        return OggFLAC__seekable_stream_encoder_set_do_exhaustive_model_search(encoder->private_->seekable_stream_encoder, value);
384
 
}
385
 
 
386
 
OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_min_residual_partition_order(OggFLAC__FileEncoder *encoder, unsigned value)
387
 
{
388
 
        FLAC__ASSERT(0 != encoder);
389
 
        FLAC__ASSERT(0 != encoder->private_);
390
 
        FLAC__ASSERT(0 != encoder->protected_);
391
 
        FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
392
 
        if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
393
 
                return false;
394
 
        return OggFLAC__seekable_stream_encoder_set_min_residual_partition_order(encoder->private_->seekable_stream_encoder, value);
395
 
}
396
 
 
397
 
OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_max_residual_partition_order(OggFLAC__FileEncoder *encoder, unsigned value)
398
 
{
399
 
        FLAC__ASSERT(0 != encoder);
400
 
        FLAC__ASSERT(0 != encoder->private_);
401
 
        FLAC__ASSERT(0 != encoder->protected_);
402
 
        FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
403
 
        if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
404
 
                return false;
405
 
        return OggFLAC__seekable_stream_encoder_set_max_residual_partition_order(encoder->private_->seekable_stream_encoder, value);
406
 
}
407
 
 
408
 
OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_rice_parameter_search_dist(OggFLAC__FileEncoder *encoder, unsigned value)
409
 
{
410
 
        FLAC__ASSERT(0 != encoder);
411
 
        FLAC__ASSERT(0 != encoder->private_);
412
 
        FLAC__ASSERT(0 != encoder->protected_);
413
 
        FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
414
 
        if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
415
 
                return false;
416
 
        return OggFLAC__seekable_stream_encoder_set_rice_parameter_search_dist(encoder->private_->seekable_stream_encoder, value);
417
 
}
418
 
 
419
 
OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_total_samples_estimate(OggFLAC__FileEncoder *encoder, FLAC__uint64 value)
420
 
{
421
 
        FLAC__ASSERT(0 != encoder);
422
 
        FLAC__ASSERT(0 != encoder->private_);
423
 
        FLAC__ASSERT(0 != encoder->protected_);
424
 
        FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
425
 
        if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
426
 
                return false;
427
 
        return OggFLAC__seekable_stream_encoder_set_total_samples_estimate(encoder->private_->seekable_stream_encoder, value);
428
 
}
429
 
 
430
 
OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_metadata(OggFLAC__FileEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks)
431
 
{
432
 
        FLAC__ASSERT(0 != encoder);
433
 
        FLAC__ASSERT(0 != encoder->private_);
434
 
        FLAC__ASSERT(0 != encoder->protected_);
435
 
        FLAC__ASSERT(0 != encoder->private_->seekable_stream_encoder);
436
 
        if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
437
 
                return false;
438
 
        return OggFLAC__seekable_stream_encoder_set_metadata(encoder->private_->seekable_stream_encoder, metadata, num_blocks);
439
 
}
440
 
 
441
 
OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_filename(OggFLAC__FileEncoder *encoder, const char *value)
442
 
{
443
 
        FLAC__ASSERT(0 != encoder);
444
 
        FLAC__ASSERT(0 != encoder->private_);
445
 
        FLAC__ASSERT(0 != encoder->protected_);
446
 
        FLAC__ASSERT(0 != value);
447
 
        if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
448
 
                return false;
449
 
        if(0 != encoder->private_->filename) {
450
 
                free(encoder->private_->filename);
451
 
                encoder->private_->filename = 0;
452
 
        }
453
 
        if(0 == (encoder->private_->filename = (char*)malloc(strlen(value)+1))) {
454
 
                encoder->protected_->state = OggFLAC__FILE_ENCODER_MEMORY_ALLOCATION_ERROR;
455
 
                return false;
456
 
        }
457
 
        strcpy(encoder->private_->filename, value);
458
 
        return true;
459
 
}
460
 
 
461
 
OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_progress_callback(OggFLAC__FileEncoder *encoder, OggFLAC__FileEncoderProgressCallback value)
462
 
{
463
 
        FLAC__ASSERT(0 != encoder);
464
 
        FLAC__ASSERT(0 != encoder->private_);
465
 
        FLAC__ASSERT(0 != encoder->protected_);
466
 
        if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
467
 
                return false;
468
 
        encoder->private_->progress_callback = value;
469
 
        return true;
470
 
}
471
 
 
472
 
OggFLAC_API FLAC__bool OggFLAC__file_encoder_set_client_data(OggFLAC__FileEncoder *encoder, void *value)
473
 
{
474
 
        FLAC__ASSERT(0 != encoder);
475
 
        FLAC__ASSERT(0 != encoder->private_);
476
 
        FLAC__ASSERT(0 != encoder->protected_);
477
 
        if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
478
 
                return false;
479
 
        encoder->private_->client_data = value;
480
 
        return true;
481
 
}
482
 
 
483
 
/*
484
 
 * These three functions are not static, but not publically exposed in
485
 
 * include/OggFLAC/ either.  They are used by the test suite.
486
 
 */
487
 
OggFLAC_API FLAC__bool OggFLAC__file_encoder_disable_constant_subframes(OggFLAC__FileEncoder *encoder, FLAC__bool value)
488
 
{
489
 
        FLAC__ASSERT(0 != encoder);
490
 
        FLAC__ASSERT(0 != encoder->private_);
491
 
        FLAC__ASSERT(0 != encoder->protected_);
492
 
        if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
493
 
                return false;
494
 
        return OggFLAC__seekable_stream_encoder_disable_constant_subframes(encoder->private_->seekable_stream_encoder, value);
495
 
}
496
 
 
497
 
OggFLAC_API FLAC__bool OggFLAC__file_encoder_disable_fixed_subframes(OggFLAC__FileEncoder *encoder, FLAC__bool value)
498
 
{
499
 
        FLAC__ASSERT(0 != encoder);
500
 
        FLAC__ASSERT(0 != encoder->private_);
501
 
        FLAC__ASSERT(0 != encoder->protected_);
502
 
        if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
503
 
                return false;
504
 
        return OggFLAC__seekable_stream_encoder_disable_fixed_subframes(encoder->private_->seekable_stream_encoder, value);
505
 
}
506
 
 
507
 
OggFLAC_API FLAC__bool OggFLAC__file_encoder_disable_verbatim_subframes(OggFLAC__FileEncoder *encoder, FLAC__bool value)
508
 
{
509
 
        FLAC__ASSERT(0 != encoder);
510
 
        FLAC__ASSERT(0 != encoder->private_);
511
 
        FLAC__ASSERT(0 != encoder->protected_);
512
 
        if(encoder->protected_->state != OggFLAC__FILE_ENCODER_UNINITIALIZED)
513
 
                return false;
514
 
        return OggFLAC__seekable_stream_encoder_disable_verbatim_subframes(encoder->private_->seekable_stream_encoder, value);
515
 
}
516
 
 
517
 
OggFLAC_API OggFLAC__FileEncoderState OggFLAC__file_encoder_get_state(const OggFLAC__FileEncoder *encoder)
518
 
{
519
 
        FLAC__ASSERT(0 != encoder);
520
 
        FLAC__ASSERT(0 != encoder->protected_);
521
 
        return encoder->protected_->state;
522
 
}
523
 
 
524
 
OggFLAC_API OggFLAC__SeekableStreamEncoderState OggFLAC__file_encoder_get_seekable_stream_encoder_state(const OggFLAC__FileEncoder *encoder)
525
 
{
526
 
        FLAC__ASSERT(0 != encoder);
527
 
        FLAC__ASSERT(0 != encoder->private_);
528
 
        return OggFLAC__seekable_stream_encoder_get_state(encoder->private_->seekable_stream_encoder);
529
 
}
530
 
 
531
 
OggFLAC_API FLAC__StreamEncoderState OggFLAC__file_encoder_get_FLAC_stream_encoder_state(const OggFLAC__FileEncoder *encoder)
532
 
{
533
 
        FLAC__ASSERT(0 != encoder);
534
 
        FLAC__ASSERT(0 != encoder->private_);
535
 
        return OggFLAC__seekable_stream_encoder_get_FLAC_stream_encoder_state(encoder->private_->seekable_stream_encoder);
536
 
}
537
 
 
538
 
OggFLAC_API FLAC__StreamDecoderState OggFLAC__file_encoder_get_verify_decoder_state(const OggFLAC__FileEncoder *encoder)
539
 
{
540
 
        FLAC__ASSERT(0 != encoder);
541
 
        FLAC__ASSERT(0 != encoder->private_);
542
 
        return OggFLAC__seekable_stream_encoder_get_verify_decoder_state(encoder->private_->seekable_stream_encoder);
543
 
}
544
 
 
545
 
OggFLAC_API const char *OggFLAC__file_encoder_get_resolved_state_string(const OggFLAC__FileEncoder *encoder)
546
 
{
547
 
        if(encoder->protected_->state != OggFLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR)
548
 
                return OggFLAC__FileEncoderStateString[encoder->protected_->state];
549
 
        else
550
 
                return OggFLAC__seekable_stream_encoder_get_resolved_state_string(encoder->private_->seekable_stream_encoder);
551
 
}
552
 
 
553
 
OggFLAC_API void OggFLAC__file_encoder_get_verify_decoder_error_stats(const OggFLAC__FileEncoder *encoder, FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got)
554
 
{
555
 
        FLAC__ASSERT(0 != encoder);
556
 
        FLAC__ASSERT(0 != encoder->private_);
557
 
        OggFLAC__seekable_stream_encoder_get_verify_decoder_error_stats(encoder->private_->seekable_stream_encoder, absolute_sample, frame_number, channel, sample, expected, got);
558
 
}
559
 
 
560
 
OggFLAC_API FLAC__bool OggFLAC__file_encoder_get_verify(const OggFLAC__FileEncoder *encoder)
561
 
{
562
 
        FLAC__ASSERT(0 != encoder);
563
 
        FLAC__ASSERT(0 != encoder->private_);
564
 
        return OggFLAC__seekable_stream_encoder_get_verify(encoder->private_->seekable_stream_encoder);
565
 
}
566
 
 
567
 
OggFLAC_API FLAC__bool OggFLAC__file_encoder_get_streamable_subset(const OggFLAC__FileEncoder *encoder)
568
 
{
569
 
        FLAC__ASSERT(0 != encoder);
570
 
        FLAC__ASSERT(0 != encoder->private_);
571
 
        return OggFLAC__seekable_stream_encoder_get_streamable_subset(encoder->private_->seekable_stream_encoder);
572
 
}
573
 
 
574
 
OggFLAC_API FLAC__bool OggFLAC__file_encoder_get_do_mid_side_stereo(const OggFLAC__FileEncoder *encoder)
575
 
{
576
 
        FLAC__ASSERT(0 != encoder);
577
 
        FLAC__ASSERT(0 != encoder->private_);
578
 
        return OggFLAC__seekable_stream_encoder_get_do_mid_side_stereo(encoder->private_->seekable_stream_encoder);
579
 
}
580
 
 
581
 
OggFLAC_API FLAC__bool OggFLAC__file_encoder_get_loose_mid_side_stereo(const OggFLAC__FileEncoder *encoder)
582
 
{
583
 
        FLAC__ASSERT(0 != encoder);
584
 
        FLAC__ASSERT(0 != encoder->private_);
585
 
        return OggFLAC__seekable_stream_encoder_get_loose_mid_side_stereo(encoder->private_->seekable_stream_encoder);
586
 
}
587
 
 
588
 
OggFLAC_API unsigned OggFLAC__file_encoder_get_channels(const OggFLAC__FileEncoder *encoder)
589
 
{
590
 
        FLAC__ASSERT(0 != encoder);
591
 
        FLAC__ASSERT(0 != encoder->private_);
592
 
        return OggFLAC__seekable_stream_encoder_get_channels(encoder->private_->seekable_stream_encoder);
593
 
}
594
 
 
595
 
OggFLAC_API unsigned OggFLAC__file_encoder_get_bits_per_sample(const OggFLAC__FileEncoder *encoder)
596
 
{
597
 
        FLAC__ASSERT(0 != encoder);
598
 
        FLAC__ASSERT(0 != encoder->private_);
599
 
        return OggFLAC__seekable_stream_encoder_get_bits_per_sample(encoder->private_->seekable_stream_encoder);
600
 
}
601
 
 
602
 
OggFLAC_API unsigned OggFLAC__file_encoder_get_sample_rate(const OggFLAC__FileEncoder *encoder)
603
 
{
604
 
        FLAC__ASSERT(0 != encoder);
605
 
        FLAC__ASSERT(0 != encoder->private_);
606
 
        return OggFLAC__seekable_stream_encoder_get_sample_rate(encoder->private_->seekable_stream_encoder);
607
 
}
608
 
 
609
 
OggFLAC_API unsigned OggFLAC__file_encoder_get_blocksize(const OggFLAC__FileEncoder *encoder)
610
 
{
611
 
        FLAC__ASSERT(0 != encoder);
612
 
        FLAC__ASSERT(0 != encoder->private_);
613
 
        return OggFLAC__seekable_stream_encoder_get_blocksize(encoder->private_->seekable_stream_encoder);
614
 
}
615
 
 
616
 
OggFLAC_API unsigned OggFLAC__file_encoder_get_max_lpc_order(const OggFLAC__FileEncoder *encoder)
617
 
{
618
 
        FLAC__ASSERT(0 != encoder);
619
 
        FLAC__ASSERT(0 != encoder->private_);
620
 
        return OggFLAC__seekable_stream_encoder_get_max_lpc_order(encoder->private_->seekable_stream_encoder);
621
 
}
622
 
 
623
 
OggFLAC_API unsigned OggFLAC__file_encoder_get_qlp_coeff_precision(const OggFLAC__FileEncoder *encoder)
624
 
{
625
 
        FLAC__ASSERT(0 != encoder);
626
 
        FLAC__ASSERT(0 != encoder->private_);
627
 
        return OggFLAC__seekable_stream_encoder_get_qlp_coeff_precision(encoder->private_->seekable_stream_encoder);
628
 
}
629
 
 
630
 
OggFLAC_API FLAC__bool OggFLAC__file_encoder_get_do_qlp_coeff_prec_search(const OggFLAC__FileEncoder *encoder)
631
 
{
632
 
        FLAC__ASSERT(0 != encoder);
633
 
        FLAC__ASSERT(0 != encoder->private_);
634
 
        return OggFLAC__seekable_stream_encoder_get_do_qlp_coeff_prec_search(encoder->private_->seekable_stream_encoder);
635
 
}
636
 
 
637
 
OggFLAC_API FLAC__bool OggFLAC__file_encoder_get_do_escape_coding(const OggFLAC__FileEncoder *encoder)
638
 
{
639
 
        FLAC__ASSERT(0 != encoder);
640
 
        FLAC__ASSERT(0 != encoder->private_);
641
 
        return OggFLAC__seekable_stream_encoder_get_do_escape_coding(encoder->private_->seekable_stream_encoder);
642
 
}
643
 
 
644
 
OggFLAC_API FLAC__bool OggFLAC__file_encoder_get_do_exhaustive_model_search(const OggFLAC__FileEncoder *encoder)
645
 
{
646
 
        FLAC__ASSERT(0 != encoder);
647
 
        FLAC__ASSERT(0 != encoder->private_);
648
 
        return OggFLAC__seekable_stream_encoder_get_do_exhaustive_model_search(encoder->private_->seekable_stream_encoder);
649
 
}
650
 
 
651
 
OggFLAC_API unsigned OggFLAC__file_encoder_get_min_residual_partition_order(const OggFLAC__FileEncoder *encoder)
652
 
{
653
 
        FLAC__ASSERT(0 != encoder);
654
 
        FLAC__ASSERT(0 != encoder->private_);
655
 
        return OggFLAC__seekable_stream_encoder_get_min_residual_partition_order(encoder->private_->seekable_stream_encoder);
656
 
}
657
 
 
658
 
OggFLAC_API unsigned OggFLAC__file_encoder_get_max_residual_partition_order(const OggFLAC__FileEncoder *encoder)
659
 
{
660
 
        FLAC__ASSERT(0 != encoder);
661
 
        FLAC__ASSERT(0 != encoder->private_);
662
 
        return OggFLAC__seekable_stream_encoder_get_max_residual_partition_order(encoder->private_->seekable_stream_encoder);
663
 
}
664
 
 
665
 
OggFLAC_API unsigned OggFLAC__file_encoder_get_rice_parameter_search_dist(const OggFLAC__FileEncoder *encoder)
666
 
{
667
 
        FLAC__ASSERT(0 != encoder);
668
 
        FLAC__ASSERT(0 != encoder->private_);
669
 
        return OggFLAC__seekable_stream_encoder_get_rice_parameter_search_dist(encoder->private_->seekable_stream_encoder);
670
 
}
671
 
 
672
 
OggFLAC_API FLAC__uint64 OggFLAC__file_encoder_get_total_samples_estimate(const OggFLAC__FileEncoder *encoder)
673
 
{
674
 
        FLAC__ASSERT(0 != encoder);
675
 
        FLAC__ASSERT(0 != encoder->private_);
676
 
        return OggFLAC__seekable_stream_encoder_get_total_samples_estimate(encoder->private_->seekable_stream_encoder);
677
 
}
678
 
 
679
 
OggFLAC_API FLAC__bool OggFLAC__file_encoder_process(OggFLAC__FileEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples)
680
 
{
681
 
        FLAC__ASSERT(0 != encoder);
682
 
        FLAC__ASSERT(0 != encoder->private_);
683
 
        if(!OggFLAC__seekable_stream_encoder_process(encoder->private_->seekable_stream_encoder, buffer, samples)) {
684
 
                encoder->protected_->state = OggFLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR;
685
 
                return false;
686
 
        }
687
 
        else
688
 
                return true;
689
 
}
690
 
 
691
 
/* 'samples' is channel-wide samples, e.g. for 1 second at 44100Hz, 'samples' = 44100 regardless of the number of channels */
692
 
OggFLAC_API FLAC__bool OggFLAC__file_encoder_process_interleaved(OggFLAC__FileEncoder *encoder, const FLAC__int32 buffer[], unsigned samples)
693
 
{
694
 
        FLAC__ASSERT(0 != encoder);
695
 
        FLAC__ASSERT(0 != encoder->private_);
696
 
        if(!OggFLAC__seekable_stream_encoder_process_interleaved(encoder->private_->seekable_stream_encoder, buffer, samples)) {
697
 
                encoder->protected_->state = OggFLAC__FILE_ENCODER_SEEKABLE_STREAM_ENCODER_ERROR;
698
 
                return false;
699
 
        }
700
 
        else
701
 
                return true;
702
 
}
703
 
 
704
 
 
705
 
/***********************************************************************
706
 
 *
707
 
 * Private class methods
708
 
 *
709
 
 ***********************************************************************/
710
 
 
711
 
void set_defaults_(OggFLAC__FileEncoder *encoder)
712
 
{
713
 
        FLAC__ASSERT(0 != encoder);
714
 
        FLAC__ASSERT(0 != encoder->private_);
715
 
 
716
 
        encoder->private_->progress_callback = 0;
717
 
        encoder->private_->client_data = 0;
718
 
        encoder->private_->total_frames_estimate = 0;
719
 
        encoder->private_->filename = 0;
720
 
}
721
 
 
722
 
OggFLAC__SeekableStreamEncoderReadStatus read_callback_(const OggFLAC__SeekableStreamEncoder *encoder, FLAC__byte buffer[], unsigned *bytes, void *client_data)
723
 
{
724
 
        OggFLAC__FileEncoder *file_encoder = (OggFLAC__FileEncoder*)client_data;
725
 
 
726
 
        (void)encoder;
727
 
 
728
 
        FLAC__ASSERT(0 != file_encoder);
729
 
 
730
 
        *bytes = (unsigned)fread(buffer, 1, *bytes, file_encoder->private_->file);
731
 
        if (*bytes == 0) {
732
 
                if (feof(file_encoder->private_->file))
733
 
                        return OggFLAC__SEEKABLE_STREAM_ENCODER_READ_STATUS_END_OF_STREAM;
734
 
                else if (ferror(file_encoder->private_->file))
735
 
                        return OggFLAC__SEEKABLE_STREAM_ENCODER_READ_STATUS_ABORT;
736
 
        }
737
 
        return OggFLAC__SEEKABLE_STREAM_ENCODER_READ_STATUS_CONTINUE;
738
 
}
739
 
 
740
 
FLAC__SeekableStreamEncoderSeekStatus seek_callback_(const OggFLAC__SeekableStreamEncoder *encoder, FLAC__uint64 absolute_byte_offset, void *client_data)
741
 
{
742
 
        OggFLAC__FileEncoder *file_encoder = (OggFLAC__FileEncoder*)client_data;
743
 
 
744
 
        (void)encoder;
745
 
 
746
 
        FLAC__ASSERT(0 != file_encoder);
747
 
 
748
 
        if(fseek(file_encoder->private_->file, (long)absolute_byte_offset, SEEK_SET) < 0)
749
 
                return FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_ERROR;
750
 
        else
751
 
                return FLAC__SEEKABLE_STREAM_ENCODER_SEEK_STATUS_OK;
752
 
}
753
 
 
754
 
FLAC__SeekableStreamEncoderTellStatus tell_callback_(const OggFLAC__SeekableStreamEncoder *encoder, FLAC__uint64 *absolute_byte_offset, void *client_data)
755
 
{
756
 
        OggFLAC__FileEncoder *file_encoder = (OggFLAC__FileEncoder*)client_data;
757
 
        long offset;
758
 
 
759
 
        (void)encoder;
760
 
 
761
 
        FLAC__ASSERT(0 != file_encoder);
762
 
 
763
 
        offset = ftell(file_encoder->private_->file);
764
 
 
765
 
        if(offset < 0) {
766
 
                return FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_ERROR;
767
 
        }
768
 
        else {
769
 
                *absolute_byte_offset = (FLAC__uint64)offset;
770
 
                return FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_OK;
771
 
        }
772
 
}
773
 
 
774
 
#ifdef FLAC__VALGRIND_TESTING
775
 
static size_t local__fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
776
 
{
777
 
        size_t ret = fwrite(ptr, size, nmemb, stream);
778
 
        if(!ferror(stream))
779
 
                fflush(stream);
780
 
        return ret;
781
 
}
782
 
#else
783
 
#define local__fwrite fwrite
784
 
#endif
785
 
 
786
 
FLAC__StreamEncoderWriteStatus write_callback_(const OggFLAC__SeekableStreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
787
 
{
788
 
        OggFLAC__FileEncoder *file_encoder = (OggFLAC__FileEncoder*)client_data;
789
 
 
790
 
        (void)encoder;
791
 
 
792
 
        FLAC__ASSERT(0 != file_encoder);
793
 
 
794
 
        if(local__fwrite(buffer, sizeof(FLAC__byte), bytes, file_encoder->private_->file) == bytes) {
795
 
                file_encoder->private_->bytes_written += bytes;
796
 
                file_encoder->private_->samples_written += samples;
797
 
                /* we keep a high watermark on the number of frames written
798
 
                 * because when the encoder goes back to write metadata,
799
 
                 * 'current_frame' will drop back to 0.
800
 
                 */
801
 
                file_encoder->private_->frames_written = max(file_encoder->private_->frames_written, current_frame+1);
802
 
                /*@@@ We would like to add an '&& samples > 0' to the if
803
 
                 * clause here but currently because of the nature of our Ogg
804
 
                 * writing implementation, 'samples' is always 0 (see
805
 
                 * ogg_encoder_aspect.c).  The downside is extra progress
806
 
                 * callbacks.
807
 
                 */
808
 
                if(0 != file_encoder->private_->progress_callback)
809
 
                        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);
810
 
                return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
811
 
        }
812
 
        else
813
 
                return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
814
 
}