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

« back to all changes in this revision

Viewing changes to src/libOggFLAC/seekable_stream_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
 
/* 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 calloc() */
34
 
#include <string.h> /* for memcpy() */
35
 
#include "FLAC/assert.h"
36
 
#include "OggFLAC/seekable_stream_encoder.h"
37
 
#include "protected/seekable_stream_encoder.h"
38
 
#include "private/ogg_helper.h"
39
 
 
40
 
#ifdef max
41
 
#undef max
42
 
#endif
43
 
#define max(a,b) ((a)>(b)?(a):(b))
44
 
 
45
 
/***********************************************************************
46
 
 *
47
 
 * Private class method prototypes
48
 
 *
49
 
 ***********************************************************************/
50
 
 
51
 
/* unpublished debug routines */
52
 
extern FLAC__bool FLAC__stream_encoder_disable_constant_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
53
 
extern FLAC__bool FLAC__stream_encoder_disable_fixed_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
54
 
extern FLAC__bool FLAC__stream_encoder_disable_verbatim_subframes(FLAC__StreamEncoder *encoder, FLAC__bool value);
55
 
 
56
 
static void set_defaults_(OggFLAC__SeekableStreamEncoder *encoder);
57
 
static FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data);
58
 
static void metadata_callback_(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data);
59
 
 
60
 
 
61
 
/***********************************************************************
62
 
 *
63
 
 * Private class data
64
 
 *
65
 
 ***********************************************************************/
66
 
 
67
 
typedef struct OggFLAC__SeekableStreamEncoderPrivate {
68
 
        OggFLAC__SeekableStreamEncoderReadCallback read_callback;
69
 
        OggFLAC__SeekableStreamEncoderSeekCallback seek_callback;
70
 
        OggFLAC__SeekableStreamEncoderTellCallback tell_callback;
71
 
        OggFLAC__SeekableStreamEncoderWriteCallback write_callback;
72
 
        void *client_data;
73
 
        FLAC__StreamEncoder *FLAC_stream_encoder;
74
 
        FLAC__StreamMetadata_SeekTable *seek_table;
75
 
        /* internal vars (all the above are class settings) */
76
 
        unsigned first_seekpoint_to_check;
77
 
        FLAC__uint64 samples_written;
78
 
} OggFLAC__SeekableStreamEncoderPrivate;
79
 
 
80
 
 
81
 
/***********************************************************************
82
 
 *
83
 
 * Public static class data
84
 
 *
85
 
 ***********************************************************************/
86
 
 
87
 
OggFLAC_API const char * const OggFLAC__SeekableStreamEncoderStateString[] = {
88
 
        "OggFLAC__SEEKABLE_STREAM_ENCODER_OK",
89
 
        "OggFLAC__SEEKABLE_STREAM_ENCODER_OGG_ERROR",
90
 
        "OggFLAC__SEEKABLE_STREAM_ENCODER_FLAC_STREAM_ENCODER_ERROR",
91
 
        "OggFLAC__SEEKABLE_STREAM_ENCODER_MEMORY_ALLOCATION_ERROR",
92
 
        "OggFLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR",
93
 
        "OggFLAC__SEEKABLE_STREAM_ENCODER_READ_ERROR",
94
 
        "OggFLAC__SEEKABLE_STREAM_ENCODER_READ_ERROR",
95
 
        "OggFLAC__SEEKABLE_STREAM_ENCODER_SEEK_ERROR",
96
 
        "OggFLAC__SEEKABLE_STREAM_ENCODER_TELL_ERROR",
97
 
        "OggFLAC__SEEKABLE_STREAM_ENCODER_ALREADY_INITIALIZED",
98
 
        "OggFLAC__SEEKABLE_STREAM_ENCODER_INVALID_CALLBACK",
99
 
        "OggFLAC__SEEKABLE_STREAM_ENCODER_INVALID_SEEKTABLE",
100
 
        "OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED"
101
 
};
102
 
 
103
 
OggFLAC_API const char * const OggFLAC__SeekableStreamEncoderReadStatusString[] = {
104
 
        "OggFLAC__SEEKABLE_STREAM_ENCODER_READ_STATUS_CONTINUE",
105
 
        "OggFLAC__SEEKABLE_STREAM_ENCODER_READ_STATUS_END_OF_STREAM",
106
 
        "OggFLAC__SEEKABLE_STREAM_ENCODER_READ_STATUS_ABORT"
107
 
};
108
 
 
109
 
 
110
 
/***********************************************************************
111
 
 *
112
 
 * Class constructor/destructor
113
 
 *
114
 
 */
115
 
OggFLAC_API OggFLAC__SeekableStreamEncoder *OggFLAC__seekable_stream_encoder_new()
116
 
{
117
 
        OggFLAC__SeekableStreamEncoder *encoder;
118
 
 
119
 
        encoder = (OggFLAC__SeekableStreamEncoder*)calloc(1, sizeof(OggFLAC__SeekableStreamEncoder));
120
 
        if(encoder == 0) {
121
 
                return 0;
122
 
        }
123
 
 
124
 
        encoder->protected_ = (OggFLAC__SeekableStreamEncoderProtected*)calloc(1, sizeof(OggFLAC__SeekableStreamEncoderProtected));
125
 
        if(encoder->protected_ == 0) {
126
 
                free(encoder);
127
 
                return 0;
128
 
        }
129
 
 
130
 
        encoder->private_ = (OggFLAC__SeekableStreamEncoderPrivate*)calloc(1, sizeof(OggFLAC__SeekableStreamEncoderPrivate));
131
 
        if(encoder->private_ == 0) {
132
 
                free(encoder->protected_);
133
 
                free(encoder);
134
 
                return 0;
135
 
        }
136
 
 
137
 
        encoder->private_->FLAC_stream_encoder = FLAC__stream_encoder_new();
138
 
        if(0 == encoder->private_->FLAC_stream_encoder) {
139
 
                free(encoder->private_);
140
 
                free(encoder->protected_);
141
 
                free(encoder);
142
 
                return 0;
143
 
        }
144
 
 
145
 
        set_defaults_(encoder);
146
 
 
147
 
        encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED;
148
 
 
149
 
        return encoder;
150
 
}
151
 
 
152
 
OggFLAC_API void OggFLAC__seekable_stream_encoder_delete(OggFLAC__SeekableStreamEncoder *encoder)
153
 
{
154
 
        FLAC__ASSERT(0 != encoder);
155
 
        FLAC__ASSERT(0 != encoder->protected_);
156
 
        FLAC__ASSERT(0 != encoder->private_);
157
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
158
 
 
159
 
        (void)OggFLAC__seekable_stream_encoder_finish(encoder);
160
 
 
161
 
        FLAC__stream_encoder_delete(encoder->private_->FLAC_stream_encoder);
162
 
 
163
 
        free(encoder->private_);
164
 
        free(encoder->protected_);
165
 
        free(encoder);
166
 
}
167
 
 
168
 
 
169
 
/***********************************************************************
170
 
 *
171
 
 * Public class methods
172
 
 *
173
 
 ***********************************************************************/
174
 
 
175
 
OggFLAC_API OggFLAC__SeekableStreamEncoderState OggFLAC__seekable_stream_encoder_init(OggFLAC__SeekableStreamEncoder *encoder)
176
 
{
177
 
        FLAC__ASSERT(0 != encoder);
178
 
 
179
 
        if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
180
 
                return encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_ALREADY_INITIALIZED;
181
 
 
182
 
        if(0 == encoder->private_->seek_callback || 0 == encoder->private_->tell_callback || 0 == encoder->private_->write_callback)
183
 
                return encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_INVALID_CALLBACK;
184
 
 
185
 
        if(!OggFLAC__ogg_encoder_aspect_init(&encoder->protected_->ogg_encoder_aspect))
186
 
                        return encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_OGG_ERROR;
187
 
 
188
 
        if(0 != encoder->private_->seek_table && !FLAC__format_seektable_is_legal(encoder->private_->seek_table))
189
 
                return encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_INVALID_SEEKTABLE;
190
 
 
191
 
        /*
192
 
         * These must be done before we init the stream encoder because that
193
 
         * calls the write_callback, which uses these values.
194
 
         */
195
 
        encoder->private_->first_seekpoint_to_check = 0;
196
 
        encoder->private_->samples_written = 0;
197
 
        encoder->protected_->streaminfo_offset = 0;
198
 
        encoder->protected_->seektable_offset = 0;
199
 
        encoder->protected_->audio_offset = 0;
200
 
 
201
 
        FLAC__stream_encoder_set_write_callback(encoder->private_->FLAC_stream_encoder, write_callback_);
202
 
        FLAC__stream_encoder_set_metadata_callback(encoder->private_->FLAC_stream_encoder, metadata_callback_);
203
 
        FLAC__stream_encoder_set_client_data(encoder->private_->FLAC_stream_encoder, encoder);
204
 
 
205
 
        if(FLAC__stream_encoder_init(encoder->private_->FLAC_stream_encoder) != FLAC__STREAM_ENCODER_OK)
206
 
                return encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_FLAC_STREAM_ENCODER_ERROR;
207
 
 
208
 
        /*
209
 
         * Initializing the stream encoder writes all the metadata, so we
210
 
         * save the stream offset now.
211
 
         */
212
 
        if(encoder->private_->tell_callback(encoder, &encoder->protected_->audio_offset, encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_OK)
213
 
                return encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_TELL_ERROR;
214
 
 
215
 
        return encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_OK;
216
 
}
217
 
 
218
 
OggFLAC_API void OggFLAC__seekable_stream_encoder_finish(OggFLAC__SeekableStreamEncoder *encoder)
219
 
{
220
 
        FLAC__ASSERT(0 != encoder);
221
 
        FLAC__ASSERT(0 != encoder->private_);
222
 
        FLAC__ASSERT(0 != encoder->protected_);
223
 
 
224
 
        if(encoder->protected_->state == OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
225
 
                return;
226
 
 
227
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
228
 
 
229
 
        FLAC__stream_encoder_finish(encoder->private_->FLAC_stream_encoder);
230
 
 
231
 
        OggFLAC__ogg_encoder_aspect_finish(&encoder->protected_->ogg_encoder_aspect);
232
 
 
233
 
        set_defaults_(encoder);
234
 
 
235
 
        encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED;
236
 
}
237
 
 
238
 
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_serial_number(OggFLAC__SeekableStreamEncoder *encoder, long value)
239
 
{
240
 
        FLAC__ASSERT(0 != encoder);
241
 
        FLAC__ASSERT(0 != encoder->private_);
242
 
        FLAC__ASSERT(0 != encoder->protected_);
243
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
244
 
        if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
245
 
                return false;
246
 
        OggFLAC__ogg_encoder_aspect_set_serial_number(&encoder->protected_->ogg_encoder_aspect, value);
247
 
        return true;
248
 
}
249
 
 
250
 
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_verify(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
251
 
{
252
 
        FLAC__ASSERT(0 != encoder);
253
 
        FLAC__ASSERT(0 != encoder->private_);
254
 
        FLAC__ASSERT(0 != encoder->protected_);
255
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
256
 
        if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
257
 
                return false;
258
 
        return FLAC__stream_encoder_set_verify(encoder->private_->FLAC_stream_encoder, value);
259
 
}
260
 
 
261
 
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_streamable_subset(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
262
 
{
263
 
        FLAC__ASSERT(0 != encoder);
264
 
        FLAC__ASSERT(0 != encoder->private_);
265
 
        FLAC__ASSERT(0 != encoder->protected_);
266
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
267
 
        if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
268
 
                return false;
269
 
        return FLAC__stream_encoder_set_streamable_subset(encoder->private_->FLAC_stream_encoder, value);
270
 
}
271
 
 
272
 
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_do_mid_side_stereo(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
273
 
{
274
 
        FLAC__ASSERT(0 != encoder);
275
 
        FLAC__ASSERT(0 != encoder->private_);
276
 
        FLAC__ASSERT(0 != encoder->protected_);
277
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
278
 
        if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
279
 
                return false;
280
 
        return FLAC__stream_encoder_set_do_mid_side_stereo(encoder->private_->FLAC_stream_encoder, value);
281
 
}
282
 
 
283
 
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_loose_mid_side_stereo(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
284
 
{
285
 
        FLAC__ASSERT(0 != encoder);
286
 
        FLAC__ASSERT(0 != encoder->private_);
287
 
        FLAC__ASSERT(0 != encoder->protected_);
288
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
289
 
        if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
290
 
                return false;
291
 
        return FLAC__stream_encoder_set_loose_mid_side_stereo(encoder->private_->FLAC_stream_encoder, value);
292
 
}
293
 
 
294
 
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_channels(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
295
 
{
296
 
        FLAC__ASSERT(0 != encoder);
297
 
        FLAC__ASSERT(0 != encoder->private_);
298
 
        FLAC__ASSERT(0 != encoder->protected_);
299
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
300
 
        if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
301
 
                return false;
302
 
        return FLAC__stream_encoder_set_channels(encoder->private_->FLAC_stream_encoder, value);
303
 
}
304
 
 
305
 
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_bits_per_sample(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
306
 
{
307
 
        FLAC__ASSERT(0 != encoder);
308
 
        FLAC__ASSERT(0 != encoder->private_);
309
 
        FLAC__ASSERT(0 != encoder->protected_);
310
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
311
 
        if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
312
 
                return false;
313
 
        return FLAC__stream_encoder_set_bits_per_sample(encoder->private_->FLAC_stream_encoder, value);
314
 
}
315
 
 
316
 
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_sample_rate(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
317
 
{
318
 
        FLAC__ASSERT(0 != encoder);
319
 
        FLAC__ASSERT(0 != encoder->private_);
320
 
        FLAC__ASSERT(0 != encoder->protected_);
321
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
322
 
        if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
323
 
                return false;
324
 
        return FLAC__stream_encoder_set_sample_rate(encoder->private_->FLAC_stream_encoder, value);
325
 
}
326
 
 
327
 
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_blocksize(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
328
 
{
329
 
        FLAC__ASSERT(0 != encoder);
330
 
        FLAC__ASSERT(0 != encoder->private_);
331
 
        FLAC__ASSERT(0 != encoder->protected_);
332
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
333
 
        if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
334
 
                return false;
335
 
        return FLAC__stream_encoder_set_blocksize(encoder->private_->FLAC_stream_encoder, value);
336
 
}
337
 
 
338
 
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_max_lpc_order(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
339
 
{
340
 
        FLAC__ASSERT(0 != encoder);
341
 
        FLAC__ASSERT(0 != encoder->private_);
342
 
        FLAC__ASSERT(0 != encoder->protected_);
343
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
344
 
        if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
345
 
                return false;
346
 
        return FLAC__stream_encoder_set_max_lpc_order(encoder->private_->FLAC_stream_encoder, value);
347
 
}
348
 
 
349
 
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_qlp_coeff_precision(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
350
 
{
351
 
        FLAC__ASSERT(0 != encoder);
352
 
        FLAC__ASSERT(0 != encoder->private_);
353
 
        FLAC__ASSERT(0 != encoder->protected_);
354
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
355
 
        if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
356
 
                return false;
357
 
        return FLAC__stream_encoder_set_qlp_coeff_precision(encoder->private_->FLAC_stream_encoder, value);
358
 
}
359
 
 
360
 
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_do_qlp_coeff_prec_search(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
361
 
{
362
 
        FLAC__ASSERT(0 != encoder);
363
 
        FLAC__ASSERT(0 != encoder->private_);
364
 
        FLAC__ASSERT(0 != encoder->protected_);
365
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
366
 
        if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
367
 
                return false;
368
 
        return FLAC__stream_encoder_set_do_qlp_coeff_prec_search(encoder->private_->FLAC_stream_encoder, value);
369
 
}
370
 
 
371
 
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_do_escape_coding(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
372
 
{
373
 
        FLAC__ASSERT(0 != encoder);
374
 
        FLAC__ASSERT(0 != encoder->private_);
375
 
        FLAC__ASSERT(0 != encoder->protected_);
376
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
377
 
        if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
378
 
                return false;
379
 
        return FLAC__stream_encoder_set_do_escape_coding(encoder->private_->FLAC_stream_encoder, value);
380
 
}
381
 
 
382
 
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_do_exhaustive_model_search(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
383
 
{
384
 
        FLAC__ASSERT(0 != encoder);
385
 
        FLAC__ASSERT(0 != encoder->private_);
386
 
        FLAC__ASSERT(0 != encoder->protected_);
387
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
388
 
        if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
389
 
                return false;
390
 
        return FLAC__stream_encoder_set_do_exhaustive_model_search(encoder->private_->FLAC_stream_encoder, value);
391
 
}
392
 
 
393
 
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_min_residual_partition_order(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
394
 
{
395
 
        FLAC__ASSERT(0 != encoder);
396
 
        FLAC__ASSERT(0 != encoder->private_);
397
 
        FLAC__ASSERT(0 != encoder->protected_);
398
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
399
 
        if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
400
 
                return false;
401
 
        return FLAC__stream_encoder_set_min_residual_partition_order(encoder->private_->FLAC_stream_encoder, value);
402
 
}
403
 
 
404
 
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_max_residual_partition_order(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
405
 
{
406
 
        FLAC__ASSERT(0 != encoder);
407
 
        FLAC__ASSERT(0 != encoder->private_);
408
 
        FLAC__ASSERT(0 != encoder->protected_);
409
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
410
 
        if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
411
 
                return false;
412
 
        return FLAC__stream_encoder_set_max_residual_partition_order(encoder->private_->FLAC_stream_encoder, value);
413
 
}
414
 
 
415
 
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_rice_parameter_search_dist(OggFLAC__SeekableStreamEncoder *encoder, unsigned value)
416
 
{
417
 
        FLAC__ASSERT(0 != encoder);
418
 
        FLAC__ASSERT(0 != encoder->private_);
419
 
        FLAC__ASSERT(0 != encoder->protected_);
420
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
421
 
        if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
422
 
                return false;
423
 
        return FLAC__stream_encoder_set_rice_parameter_search_dist(encoder->private_->FLAC_stream_encoder, value);
424
 
}
425
 
 
426
 
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_total_samples_estimate(OggFLAC__SeekableStreamEncoder *encoder, FLAC__uint64 value)
427
 
{
428
 
        FLAC__ASSERT(0 != encoder);
429
 
        FLAC__ASSERT(0 != encoder->private_);
430
 
        FLAC__ASSERT(0 != encoder->protected_);
431
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
432
 
        if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
433
 
                return false;
434
 
        return FLAC__stream_encoder_set_total_samples_estimate(encoder->private_->FLAC_stream_encoder, value);
435
 
}
436
 
 
437
 
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_metadata(OggFLAC__SeekableStreamEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks)
438
 
{
439
 
        FLAC__ASSERT(0 != encoder);
440
 
        FLAC__ASSERT(0 != encoder->private_);
441
 
        FLAC__ASSERT(0 != encoder->protected_);
442
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
443
 
        if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
444
 
                return false;
445
 
        /* reorder metadata if necessary to ensure that any VORBIS_COMMENT is the first, according to the mapping spec */
446
 
        if(0 != metadata && num_blocks > 1) {
447
 
                unsigned i;
448
 
                for(i = 1; i < num_blocks; i++) {
449
 
                        if(0 != metadata[i] && metadata[i]->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) {
450
 
                                FLAC__StreamMetadata *vc = metadata[i];
451
 
                                for( ; i > 0; i--)
452
 
                                        metadata[i] = metadata[i-1];
453
 
                                metadata[0] = vc;
454
 
                                break;
455
 
                        }
456
 
                }
457
 
        }
458
 
        if(0 != metadata && num_blocks > 0) {
459
 
                unsigned i;
460
 
                for(i = 0; i < num_blocks; i++) {
461
 
                        /* keep track of any SEEKTABLE block */
462
 
                        if(0 != metadata[i] && metadata[i]->type == FLAC__METADATA_TYPE_SEEKTABLE) {
463
 
                                encoder->private_->seek_table = &metadata[i]->data.seek_table;
464
 
                                break; /* take only the first one */
465
 
                        }
466
 
                }
467
 
        }
468
 
        if(!OggFLAC__ogg_encoder_aspect_set_num_metadata(&encoder->protected_->ogg_encoder_aspect, num_blocks))
469
 
                return false;
470
 
        return FLAC__stream_encoder_set_metadata(encoder->private_->FLAC_stream_encoder, metadata, num_blocks);
471
 
}
472
 
 
473
 
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_read_callback(OggFLAC__SeekableStreamEncoder *encoder, OggFLAC__SeekableStreamEncoderReadCallback value)
474
 
{
475
 
        FLAC__ASSERT(0 != encoder);
476
 
        FLAC__ASSERT(0 != encoder->private_);
477
 
        FLAC__ASSERT(0 != encoder->protected_);
478
 
        FLAC__ASSERT(0 != value);
479
 
        if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
480
 
                return false;
481
 
        encoder->private_->read_callback = value;
482
 
        return true;
483
 
}
484
 
 
485
 
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_seek_callback(OggFLAC__SeekableStreamEncoder *encoder, OggFLAC__SeekableStreamEncoderSeekCallback value)
486
 
{
487
 
        FLAC__ASSERT(0 != encoder);
488
 
        FLAC__ASSERT(0 != encoder->private_);
489
 
        FLAC__ASSERT(0 != encoder->protected_);
490
 
        FLAC__ASSERT(0 != value);
491
 
        if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
492
 
                return false;
493
 
        encoder->private_->seek_callback = value;
494
 
        return true;
495
 
}
496
 
 
497
 
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_tell_callback(OggFLAC__SeekableStreamEncoder *encoder, OggFLAC__SeekableStreamEncoderTellCallback value)
498
 
{
499
 
        FLAC__ASSERT(0 != encoder);
500
 
        FLAC__ASSERT(0 != encoder->private_);
501
 
        FLAC__ASSERT(0 != encoder->protected_);
502
 
        FLAC__ASSERT(0 != value);
503
 
        if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
504
 
                return false;
505
 
        encoder->private_->tell_callback = value;
506
 
        return true;
507
 
}
508
 
 
509
 
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_write_callback(OggFLAC__SeekableStreamEncoder *encoder, OggFLAC__SeekableStreamEncoderWriteCallback value)
510
 
{
511
 
        FLAC__ASSERT(0 != encoder);
512
 
        FLAC__ASSERT(0 != encoder->private_);
513
 
        FLAC__ASSERT(0 != encoder->protected_);
514
 
        FLAC__ASSERT(0 != value);
515
 
        if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
516
 
                return false;
517
 
        encoder->private_->write_callback = value;
518
 
        return true;
519
 
}
520
 
 
521
 
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_set_client_data(OggFLAC__SeekableStreamEncoder *encoder, void *value)
522
 
{
523
 
        FLAC__ASSERT(0 != encoder);
524
 
        FLAC__ASSERT(0 != encoder->private_);
525
 
        FLAC__ASSERT(0 != encoder->protected_);
526
 
        if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
527
 
                return false;
528
 
        encoder->private_->client_data = value;
529
 
        return true;
530
 
}
531
 
 
532
 
/*
533
 
 * These three functions are not static, but not publically exposed in
534
 
 * include/FLAC/ either.  They are used by the test suite.
535
 
 */
536
 
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_disable_constant_subframes(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
537
 
{
538
 
        FLAC__ASSERT(0 != encoder);
539
 
        FLAC__ASSERT(0 != encoder->private_);
540
 
        FLAC__ASSERT(0 != encoder->protected_);
541
 
        if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
542
 
                return false;
543
 
        return FLAC__stream_encoder_disable_constant_subframes(encoder->private_->FLAC_stream_encoder, value);
544
 
}
545
 
 
546
 
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_disable_fixed_subframes(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
547
 
{
548
 
        FLAC__ASSERT(0 != encoder);
549
 
        FLAC__ASSERT(0 != encoder->private_);
550
 
        FLAC__ASSERT(0 != encoder->protected_);
551
 
        if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
552
 
                return false;
553
 
        return FLAC__stream_encoder_disable_fixed_subframes(encoder->private_->FLAC_stream_encoder, value);
554
 
}
555
 
 
556
 
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_disable_verbatim_subframes(OggFLAC__SeekableStreamEncoder *encoder, FLAC__bool value)
557
 
{
558
 
        FLAC__ASSERT(0 != encoder);
559
 
        FLAC__ASSERT(0 != encoder->private_);
560
 
        FLAC__ASSERT(0 != encoder->protected_);
561
 
        if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
562
 
                return false;
563
 
        return FLAC__stream_encoder_disable_verbatim_subframes(encoder->private_->FLAC_stream_encoder, value);
564
 
}
565
 
 
566
 
OggFLAC_API OggFLAC__SeekableStreamEncoderState OggFLAC__seekable_stream_encoder_get_state(const OggFLAC__SeekableStreamEncoder *encoder)
567
 
{
568
 
        FLAC__ASSERT(0 != encoder);
569
 
        FLAC__ASSERT(0 != encoder->private_);
570
 
        FLAC__ASSERT(0 != encoder->protected_);
571
 
        return encoder->protected_->state;
572
 
}
573
 
 
574
 
OggFLAC_API FLAC__StreamEncoderState OggFLAC__seekable_stream_encoder_get_FLAC_stream_encoder_state(const OggFLAC__SeekableStreamEncoder *encoder)
575
 
{
576
 
        FLAC__ASSERT(0 != encoder);
577
 
        FLAC__ASSERT(0 != encoder->private_);
578
 
        FLAC__ASSERT(0 != encoder->protected_);
579
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
580
 
        return FLAC__stream_encoder_get_state(encoder->private_->FLAC_stream_encoder);
581
 
}
582
 
 
583
 
OggFLAC_API FLAC__StreamDecoderState OggFLAC__seekable_stream_encoder_get_verify_decoder_state(const OggFLAC__SeekableStreamEncoder *encoder)
584
 
{
585
 
        FLAC__ASSERT(0 != encoder);
586
 
        FLAC__ASSERT(0 != encoder->private_);
587
 
        FLAC__ASSERT(0 != encoder->protected_);
588
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
589
 
        return FLAC__stream_encoder_get_verify_decoder_state(encoder->private_->FLAC_stream_encoder);
590
 
}
591
 
 
592
 
OggFLAC_API const char *OggFLAC__seekable_stream_encoder_get_resolved_state_string(const OggFLAC__SeekableStreamEncoder *encoder)
593
 
{
594
 
        FLAC__ASSERT(0 != encoder);
595
 
        FLAC__ASSERT(0 != encoder->private_);
596
 
        FLAC__ASSERT(0 != encoder->protected_);
597
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
598
 
        if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_FLAC_STREAM_ENCODER_ERROR)
599
 
                return OggFLAC__SeekableStreamEncoderStateString[encoder->protected_->state];
600
 
        else
601
 
                return FLAC__stream_encoder_get_resolved_state_string(encoder->private_->FLAC_stream_encoder);
602
 
}
603
 
 
604
 
OggFLAC_API void OggFLAC__seekable_stream_encoder_get_verify_decoder_error_stats(const OggFLAC__SeekableStreamEncoder *encoder, FLAC__uint64 *absolute_sample, unsigned *frame_number, unsigned *channel, unsigned *sample, FLAC__int32 *expected, FLAC__int32 *got)
605
 
{
606
 
        FLAC__ASSERT(0 != encoder);
607
 
        FLAC__ASSERT(0 != encoder->private_);
608
 
        FLAC__ASSERT(0 != encoder->protected_);
609
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
610
 
        FLAC__stream_encoder_get_verify_decoder_error_stats(encoder->private_->FLAC_stream_encoder, absolute_sample, frame_number, channel, sample, expected, got);
611
 
}
612
 
 
613
 
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_get_verify(const OggFLAC__SeekableStreamEncoder *encoder)
614
 
{
615
 
        FLAC__ASSERT(0 != encoder);
616
 
        FLAC__ASSERT(0 != encoder->private_);
617
 
        FLAC__ASSERT(0 != encoder->protected_);
618
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
619
 
        return FLAC__stream_encoder_get_verify(encoder->private_->FLAC_stream_encoder);
620
 
}
621
 
 
622
 
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_get_streamable_subset(const OggFLAC__SeekableStreamEncoder *encoder)
623
 
{
624
 
        FLAC__ASSERT(0 != encoder);
625
 
        FLAC__ASSERT(0 != encoder->private_);
626
 
        FLAC__ASSERT(0 != encoder->protected_);
627
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
628
 
        return FLAC__stream_encoder_get_streamable_subset(encoder->private_->FLAC_stream_encoder);
629
 
}
630
 
 
631
 
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_get_do_mid_side_stereo(const OggFLAC__SeekableStreamEncoder *encoder)
632
 
{
633
 
        FLAC__ASSERT(0 != encoder);
634
 
        FLAC__ASSERT(0 != encoder->private_);
635
 
        FLAC__ASSERT(0 != encoder->protected_);
636
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
637
 
        return FLAC__stream_encoder_get_do_mid_side_stereo(encoder->private_->FLAC_stream_encoder);
638
 
}
639
 
 
640
 
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_get_loose_mid_side_stereo(const OggFLAC__SeekableStreamEncoder *encoder)
641
 
{
642
 
        FLAC__ASSERT(0 != encoder);
643
 
        FLAC__ASSERT(0 != encoder->private_);
644
 
        FLAC__ASSERT(0 != encoder->protected_);
645
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
646
 
        return FLAC__stream_encoder_get_loose_mid_side_stereo(encoder->private_->FLAC_stream_encoder);
647
 
}
648
 
 
649
 
OggFLAC_API unsigned OggFLAC__seekable_stream_encoder_get_channels(const OggFLAC__SeekableStreamEncoder *encoder)
650
 
{
651
 
        FLAC__ASSERT(0 != encoder);
652
 
        FLAC__ASSERT(0 != encoder->private_);
653
 
        FLAC__ASSERT(0 != encoder->protected_);
654
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
655
 
        return FLAC__stream_encoder_get_channels(encoder->private_->FLAC_stream_encoder);
656
 
}
657
 
 
658
 
OggFLAC_API unsigned OggFLAC__seekable_stream_encoder_get_bits_per_sample(const OggFLAC__SeekableStreamEncoder *encoder)
659
 
{
660
 
        FLAC__ASSERT(0 != encoder);
661
 
        FLAC__ASSERT(0 != encoder->private_);
662
 
        FLAC__ASSERT(0 != encoder->protected_);
663
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
664
 
        return FLAC__stream_encoder_get_bits_per_sample(encoder->private_->FLAC_stream_encoder);
665
 
}
666
 
 
667
 
OggFLAC_API unsigned OggFLAC__seekable_stream_encoder_get_sample_rate(const OggFLAC__SeekableStreamEncoder *encoder)
668
 
{
669
 
        FLAC__ASSERT(0 != encoder);
670
 
        FLAC__ASSERT(0 != encoder->private_);
671
 
        FLAC__ASSERT(0 != encoder->protected_);
672
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
673
 
        return FLAC__stream_encoder_get_sample_rate(encoder->private_->FLAC_stream_encoder);
674
 
}
675
 
 
676
 
OggFLAC_API unsigned OggFLAC__seekable_stream_encoder_get_blocksize(const OggFLAC__SeekableStreamEncoder *encoder)
677
 
{
678
 
        FLAC__ASSERT(0 != encoder);
679
 
        FLAC__ASSERT(0 != encoder->private_);
680
 
        FLAC__ASSERT(0 != encoder->protected_);
681
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
682
 
        return FLAC__stream_encoder_get_blocksize(encoder->private_->FLAC_stream_encoder);
683
 
}
684
 
 
685
 
OggFLAC_API unsigned OggFLAC__seekable_stream_encoder_get_max_lpc_order(const OggFLAC__SeekableStreamEncoder *encoder)
686
 
{
687
 
        FLAC__ASSERT(0 != encoder);
688
 
        FLAC__ASSERT(0 != encoder->private_);
689
 
        FLAC__ASSERT(0 != encoder->protected_);
690
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
691
 
        return FLAC__stream_encoder_get_max_lpc_order(encoder->private_->FLAC_stream_encoder);
692
 
}
693
 
 
694
 
OggFLAC_API unsigned OggFLAC__seekable_stream_encoder_get_qlp_coeff_precision(const OggFLAC__SeekableStreamEncoder *encoder)
695
 
{
696
 
        FLAC__ASSERT(0 != encoder);
697
 
        FLAC__ASSERT(0 != encoder->private_);
698
 
        FLAC__ASSERT(0 != encoder->protected_);
699
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
700
 
        return FLAC__stream_encoder_get_qlp_coeff_precision(encoder->private_->FLAC_stream_encoder);
701
 
}
702
 
 
703
 
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_get_do_qlp_coeff_prec_search(const OggFLAC__SeekableStreamEncoder *encoder)
704
 
{
705
 
        FLAC__ASSERT(0 != encoder);
706
 
        FLAC__ASSERT(0 != encoder->private_);
707
 
        FLAC__ASSERT(0 != encoder->protected_);
708
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
709
 
        return FLAC__stream_encoder_get_do_qlp_coeff_prec_search(encoder->private_->FLAC_stream_encoder);
710
 
}
711
 
 
712
 
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_get_do_escape_coding(const OggFLAC__SeekableStreamEncoder *encoder)
713
 
{
714
 
        FLAC__ASSERT(0 != encoder);
715
 
        FLAC__ASSERT(0 != encoder->private_);
716
 
        FLAC__ASSERT(0 != encoder->protected_);
717
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
718
 
        return FLAC__stream_encoder_get_do_escape_coding(encoder->private_->FLAC_stream_encoder);
719
 
}
720
 
 
721
 
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_get_do_exhaustive_model_search(const OggFLAC__SeekableStreamEncoder *encoder)
722
 
{
723
 
        FLAC__ASSERT(0 != encoder);
724
 
        FLAC__ASSERT(0 != encoder->private_);
725
 
        FLAC__ASSERT(0 != encoder->protected_);
726
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
727
 
        return FLAC__stream_encoder_get_do_exhaustive_model_search(encoder->private_->FLAC_stream_encoder);
728
 
}
729
 
 
730
 
OggFLAC_API unsigned OggFLAC__seekable_stream_encoder_get_min_residual_partition_order(const OggFLAC__SeekableStreamEncoder *encoder)
731
 
{
732
 
        FLAC__ASSERT(0 != encoder);
733
 
        FLAC__ASSERT(0 != encoder->private_);
734
 
        FLAC__ASSERT(0 != encoder->protected_);
735
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
736
 
        return FLAC__stream_encoder_get_min_residual_partition_order(encoder->private_->FLAC_stream_encoder);
737
 
}
738
 
 
739
 
OggFLAC_API unsigned OggFLAC__seekable_stream_encoder_get_max_residual_partition_order(const OggFLAC__SeekableStreamEncoder *encoder)
740
 
{
741
 
        FLAC__ASSERT(0 != encoder);
742
 
        FLAC__ASSERT(0 != encoder->private_);
743
 
        FLAC__ASSERT(0 != encoder->protected_);
744
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
745
 
        return FLAC__stream_encoder_get_max_residual_partition_order(encoder->private_->FLAC_stream_encoder);
746
 
}
747
 
 
748
 
OggFLAC_API unsigned OggFLAC__seekable_stream_encoder_get_rice_parameter_search_dist(const OggFLAC__SeekableStreamEncoder *encoder)
749
 
{
750
 
        FLAC__ASSERT(0 != encoder);
751
 
        FLAC__ASSERT(0 != encoder->private_);
752
 
        FLAC__ASSERT(0 != encoder->protected_);
753
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
754
 
        return FLAC__stream_encoder_get_rice_parameter_search_dist(encoder->private_->FLAC_stream_encoder);
755
 
}
756
 
 
757
 
OggFLAC_API FLAC__uint64 OggFLAC__seekable_stream_encoder_get_total_samples_estimate(const OggFLAC__SeekableStreamEncoder *encoder)
758
 
{
759
 
        FLAC__ASSERT(0 != encoder);
760
 
        FLAC__ASSERT(0 != encoder->private_);
761
 
        FLAC__ASSERT(0 != encoder->protected_);
762
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
763
 
        return FLAC__stream_encoder_get_total_samples_estimate(encoder->private_->FLAC_stream_encoder);
764
 
}
765
 
 
766
 
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_process(OggFLAC__SeekableStreamEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples)
767
 
{
768
 
        FLAC__ASSERT(0 != encoder);
769
 
        FLAC__ASSERT(0 != encoder->private_);
770
 
        FLAC__ASSERT(0 != encoder->protected_);
771
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
772
 
        if(!FLAC__stream_encoder_process(encoder->private_->FLAC_stream_encoder, buffer, samples)) {
773
 
                encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_FLAC_STREAM_ENCODER_ERROR;
774
 
                return false;
775
 
        }
776
 
        else
777
 
                return true;
778
 
}
779
 
 
780
 
OggFLAC_API FLAC__bool OggFLAC__seekable_stream_encoder_process_interleaved(OggFLAC__SeekableStreamEncoder *encoder, const FLAC__int32 buffer[], unsigned samples)
781
 
{
782
 
        FLAC__ASSERT(0 != encoder);
783
 
        FLAC__ASSERT(0 != encoder->private_);
784
 
        FLAC__ASSERT(0 != encoder->protected_);
785
 
        FLAC__ASSERT(0 != encoder->private_->FLAC_stream_encoder);
786
 
        if(!FLAC__stream_encoder_process_interleaved(encoder->private_->FLAC_stream_encoder, buffer, samples)) {
787
 
                encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_FLAC_STREAM_ENCODER_ERROR;
788
 
                return false;
789
 
        }
790
 
        else
791
 
                return true;
792
 
}
793
 
 
794
 
/***********************************************************************
795
 
 *
796
 
 * Private class methods
797
 
 *
798
 
 ***********************************************************************/
799
 
 
800
 
void set_defaults_(OggFLAC__SeekableStreamEncoder *encoder)
801
 
{
802
 
        FLAC__ASSERT(0 != encoder);
803
 
        FLAC__ASSERT(0 != encoder->private_);
804
 
        FLAC__ASSERT(0 != encoder->protected_);
805
 
 
806
 
        encoder->private_->seek_callback = 0;
807
 
        encoder->private_->tell_callback = 0;
808
 
        encoder->private_->write_callback = 0;
809
 
        encoder->private_->client_data = 0;
810
 
 
811
 
        encoder->private_->seek_table = 0;
812
 
 
813
 
        OggFLAC__ogg_encoder_aspect_set_defaults(&encoder->protected_->ogg_encoder_aspect);
814
 
}
815
 
 
816
 
FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *unused, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
817
 
{
818
 
        OggFLAC__SeekableStreamEncoder *encoder = (OggFLAC__SeekableStreamEncoder*)client_data;
819
 
        FLAC__StreamEncoderWriteStatus status;
820
 
        FLAC__uint64 output_position;
821
 
 
822
 
        (void)unused; /* silence compiler warning about unused parameter */
823
 
        FLAC__ASSERT(encoder->private_->FLAC_stream_encoder == unused);
824
 
 
825
 
        if(encoder->private_->tell_callback(encoder, &output_position, encoder->private_->client_data) != FLAC__SEEKABLE_STREAM_ENCODER_TELL_STATUS_OK)
826
 
                return encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_TELL_ERROR;
827
 
 
828
 
        /*
829
 
         * Watch for the STREAMINFO block and first SEEKTABLE block to go by and store their offsets.
830
 
         */
831
 
        if(samples == 0) {
832
 
                FLAC__MetadataType type = (buffer[0] & 0x7f);
833
 
                if(type == FLAC__METADATA_TYPE_STREAMINFO)
834
 
                        encoder->protected_->streaminfo_offset = output_position;
835
 
                else if(type == FLAC__METADATA_TYPE_SEEKTABLE && encoder->protected_->seektable_offset == 0)
836
 
                        encoder->protected_->seektable_offset = output_position;
837
 
        }
838
 
 
839
 
        /*
840
 
         * Mark the current seek point if hit (if audio_offset == 0 that
841
 
         * means we're still writing metadata and haven't hit the first
842
 
         * frame yet)
843
 
         */
844
 
        if(0 != encoder->private_->seek_table && encoder->protected_->audio_offset > 0 && encoder->private_->seek_table->num_points > 0) {
845
 
                const unsigned blocksize = FLAC__stream_encoder_get_blocksize(encoder->private_->FLAC_stream_encoder);
846
 
                const FLAC__uint64 frame_first_sample = encoder->private_->samples_written;
847
 
                const FLAC__uint64 frame_last_sample = frame_first_sample + (FLAC__uint64)blocksize - 1;
848
 
                FLAC__uint64 test_sample;
849
 
                unsigned i;
850
 
                for(i = encoder->private_->first_seekpoint_to_check; i < encoder->private_->seek_table->num_points; i++) {
851
 
                        test_sample = encoder->private_->seek_table->points[i].sample_number;
852
 
                        if(test_sample > frame_last_sample) {
853
 
                                break;
854
 
                        }
855
 
                        else if(test_sample >= frame_first_sample) {
856
 
                                encoder->private_->seek_table->points[i].sample_number = frame_first_sample;
857
 
                                encoder->private_->seek_table->points[i].stream_offset = output_position - encoder->protected_->audio_offset;
858
 
                                encoder->private_->seek_table->points[i].frame_samples = blocksize;
859
 
                                encoder->private_->first_seekpoint_to_check++;
860
 
                                /* DO NOT: "break;" and here's why:
861
 
                                 * The seektable template may contain more than one target
862
 
                                 * sample for any given frame; we will keep looping, generating
863
 
                                 * duplicate seekpoints for them, and we'll clean it up later,
864
 
                                 * just before writing the seektable back to the metadata.
865
 
                                 */
866
 
                        }
867
 
                        else {
868
 
                                encoder->private_->first_seekpoint_to_check++;
869
 
                        }
870
 
                }
871
 
        }
872
 
 
873
 
        status = OggFLAC__ogg_encoder_aspect_write_callback_wrapper(&encoder->protected_->ogg_encoder_aspect, FLAC__stream_encoder_get_total_samples_estimate(encoder->private_->FLAC_stream_encoder), buffer, bytes, samples, current_frame, (OggFLAC__OggEncoderAspectWriteCallbackProxy)encoder->private_->write_callback, encoder, encoder->private_->client_data);
874
 
 
875
 
        if(status == FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
876
 
                encoder->private_->samples_written += samples;
877
 
        }
878
 
        else
879
 
                encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
880
 
 
881
 
        return status;
882
 
}
883
 
 
884
 
void metadata_callback_(const FLAC__StreamEncoder *unused, const FLAC__StreamMetadata *metadata, void *client_data)
885
 
{
886
 
        OggFLAC__SeekableStreamEncoder *encoder = (OggFLAC__SeekableStreamEncoder*)client_data;
887
 
        FLAC__byte b[max(6, FLAC__STREAM_METADATA_SEEKPOINT_LENGTH)];
888
 
        const FLAC__uint64 samples = metadata->data.stream_info.total_samples;
889
 
        const unsigned min_framesize = metadata->data.stream_info.min_framesize;
890
 
        const unsigned max_framesize = metadata->data.stream_info.max_framesize;
891
 
        ogg_page page;
892
 
 
893
 
        FLAC__ASSERT(metadata->type == FLAC__METADATA_TYPE_STREAMINFO);
894
 
 
895
 
        /* We get called by the stream encoder when the encoding process
896
 
         * has finished so that we can update the STREAMINFO and SEEKTABLE
897
 
         * blocks.
898
 
         */
899
 
 
900
 
        (void)unused; /* silence compiler warning about unused parameter */
901
 
        FLAC__ASSERT(encoder->private_->FLAC_stream_encoder == unused);
902
 
 
903
 
        /*@@@ reopen callback here?  The docs currently require user to open files in update mode from the start */
904
 
 
905
 
        /* All this is based on intimate knowledge of the stream header
906
 
         * layout, but a change to the header format that would break this
907
 
         * would also break all streams encoded in the previous format.
908
 
         */
909
 
 
910
 
        /*
911
 
         * Write STREAMINFO stats
912
 
         */
913
 
        simple_ogg_page__init(&page);
914
 
        if(!simple_ogg_page__get_at(encoder, encoder->protected_->streaminfo_offset, &page, encoder->private_->seek_callback, encoder->private_->read_callback, encoder->private_->client_data)) {
915
 
                simple_ogg_page__clear(&page);
916
 
                return; /* state already set */
917
 
        }
918
 
        /*
919
 
         * MD5 signature
920
 
         */
921
 
        {
922
 
                const unsigned md5_offset =
923
 
                        FLAC__STREAM_METADATA_HEADER_LENGTH +
924
 
                        (
925
 
                                FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
926
 
                                FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN +
927
 
                                FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN +
928
 
                                FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN +
929
 
                                FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN +
930
 
                                FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN +
931
 
                                FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN +
932
 
                                FLAC__STREAM_METADATA_STREAMINFO_TOTAL_SAMPLES_LEN
933
 
                        ) / 8;
934
 
 
935
 
                if(md5_offset + 16 > (unsigned)page.body_len) {
936
 
                        encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_OGG_ERROR;
937
 
                        simple_ogg_page__clear(&page);
938
 
                        return;
939
 
                }
940
 
                memcpy(page.body + md5_offset, metadata->data.stream_info.md5sum, 16);
941
 
        }
942
 
        /*
943
 
         * total samples
944
 
         */
945
 
        {
946
 
                const unsigned total_samples_byte_offset =
947
 
                        FLAC__STREAM_METADATA_HEADER_LENGTH +
948
 
                        (
949
 
                                FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
950
 
                                FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN +
951
 
                                FLAC__STREAM_METADATA_STREAMINFO_MIN_FRAME_SIZE_LEN +
952
 
                                FLAC__STREAM_METADATA_STREAMINFO_MAX_FRAME_SIZE_LEN +
953
 
                                FLAC__STREAM_METADATA_STREAMINFO_SAMPLE_RATE_LEN +
954
 
                                FLAC__STREAM_METADATA_STREAMINFO_CHANNELS_LEN +
955
 
                                FLAC__STREAM_METADATA_STREAMINFO_BITS_PER_SAMPLE_LEN
956
 
                                - 4
957
 
                        ) / 8;
958
 
 
959
 
                if(total_samples_byte_offset + 5 > (unsigned)page.body_len) {
960
 
                        encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_OGG_ERROR;
961
 
                        simple_ogg_page__clear(&page);
962
 
                        return;
963
 
                }
964
 
                b[0] = (FLAC__byte)page.body[total_samples_byte_offset] & 0xF0;
965
 
                b[0] |= (FLAC__byte)((samples >> 32) & 0x0F);
966
 
                b[1] = (FLAC__byte)((samples >> 24) & 0xFF);
967
 
                b[2] = (FLAC__byte)((samples >> 16) & 0xFF);
968
 
                b[3] = (FLAC__byte)((samples >> 8) & 0xFF);
969
 
                b[4] = (FLAC__byte)(samples & 0xFF);
970
 
                memcpy(page.body + total_samples_byte_offset, b, 5);
971
 
        }
972
 
        /*
973
 
         * min/max framesize
974
 
         */
975
 
        {
976
 
                const unsigned min_framesize_offset =
977
 
                        FLAC__STREAM_METADATA_HEADER_LENGTH +
978
 
                        (
979
 
                                FLAC__STREAM_METADATA_STREAMINFO_MIN_BLOCK_SIZE_LEN +
980
 
                                FLAC__STREAM_METADATA_STREAMINFO_MAX_BLOCK_SIZE_LEN
981
 
                        ) / 8;
982
 
 
983
 
                if(min_framesize_offset + 6 > (unsigned)page.body_len) {
984
 
                        encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_OGG_ERROR;
985
 
                        simple_ogg_page__clear(&page);
986
 
                        return;
987
 
                }
988
 
                b[0] = (FLAC__byte)((min_framesize >> 16) & 0xFF);
989
 
                b[1] = (FLAC__byte)((min_framesize >> 8) & 0xFF);
990
 
                b[2] = (FLAC__byte)(min_framesize & 0xFF);
991
 
                b[3] = (FLAC__byte)((max_framesize >> 16) & 0xFF);
992
 
                b[4] = (FLAC__byte)((max_framesize >> 8) & 0xFF);
993
 
                b[5] = (FLAC__byte)(max_framesize & 0xFF);
994
 
                memcpy(page.body + min_framesize_offset, b, 6);
995
 
        }
996
 
        if(!simple_ogg_page__set_at(encoder, encoder->protected_->streaminfo_offset, &page, encoder->private_->seek_callback, encoder->private_->write_callback, encoder->private_->client_data)) {
997
 
                simple_ogg_page__clear(&page);
998
 
                return; /* state already set */
999
 
        }
1000
 
        simple_ogg_page__clear(&page);
1001
 
 
1002
 
        /*
1003
 
         * Write seektable
1004
 
         */
1005
 
        if(0 != encoder->private_->seek_table && encoder->private_->seek_table->num_points > 0 && encoder->protected_->seektable_offset > 0) {
1006
 
                unsigned i;
1007
 
                FLAC__byte *p;
1008
 
 
1009
 
                FLAC__format_seektable_sort(encoder->private_->seek_table);
1010
 
 
1011
 
                FLAC__ASSERT(FLAC__format_seektable_is_legal(encoder->private_->seek_table));
1012
 
 
1013
 
                simple_ogg_page__init(&page);
1014
 
                if(!simple_ogg_page__get_at(encoder, encoder->protected_->seektable_offset, &page, encoder->private_->seek_callback, encoder->private_->read_callback, encoder->private_->client_data)) {
1015
 
                        simple_ogg_page__clear(&page);
1016
 
                        return; /* state already set */
1017
 
                }
1018
 
 
1019
 
                if(FLAC__STREAM_METADATA_HEADER_LENGTH + (18*encoder->private_->seek_table->num_points) > (unsigned)page.body_len) {
1020
 
                        encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_OGG_ERROR;
1021
 
                        simple_ogg_page__clear(&page);
1022
 
                        return;
1023
 
                }
1024
 
 
1025
 
                for(i = 0, p = page.body + FLAC__STREAM_METADATA_HEADER_LENGTH; i < encoder->private_->seek_table->num_points; i++, p += 18) {
1026
 
                        FLAC__uint64 xx;
1027
 
                        unsigned x;
1028
 
                        xx = encoder->private_->seek_table->points[i].sample_number;
1029
 
                        b[7] = (FLAC__byte)xx; xx >>= 8;
1030
 
                        b[6] = (FLAC__byte)xx; xx >>= 8;
1031
 
                        b[5] = (FLAC__byte)xx; xx >>= 8;
1032
 
                        b[4] = (FLAC__byte)xx; xx >>= 8;
1033
 
                        b[3] = (FLAC__byte)xx; xx >>= 8;
1034
 
                        b[2] = (FLAC__byte)xx; xx >>= 8;
1035
 
                        b[1] = (FLAC__byte)xx; xx >>= 8;
1036
 
                        b[0] = (FLAC__byte)xx; xx >>= 8;
1037
 
                        xx = encoder->private_->seek_table->points[i].stream_offset;
1038
 
                        b[15] = (FLAC__byte)xx; xx >>= 8;
1039
 
                        b[14] = (FLAC__byte)xx; xx >>= 8;
1040
 
                        b[13] = (FLAC__byte)xx; xx >>= 8;
1041
 
                        b[12] = (FLAC__byte)xx; xx >>= 8;
1042
 
                        b[11] = (FLAC__byte)xx; xx >>= 8;
1043
 
                        b[10] = (FLAC__byte)xx; xx >>= 8;
1044
 
                        b[9] = (FLAC__byte)xx; xx >>= 8;
1045
 
                        b[8] = (FLAC__byte)xx; xx >>= 8;
1046
 
                        x = encoder->private_->seek_table->points[i].frame_samples;
1047
 
                        b[17] = (FLAC__byte)x; x >>= 8;
1048
 
                        b[16] = (FLAC__byte)x; x >>= 8;
1049
 
                        if(encoder->private_->write_callback(encoder, b, 18, 0, 0, encoder->private_->client_data) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK) {
1050
 
                                encoder->protected_->state = OggFLAC__SEEKABLE_STREAM_ENCODER_WRITE_ERROR;
1051
 
                                simple_ogg_page__clear(&page);
1052
 
                                return;
1053
 
                        }
1054
 
                        memcpy(p, b, 18);
1055
 
                }
1056
 
 
1057
 
                if(!simple_ogg_page__set_at(encoder, encoder->protected_->seektable_offset, &page, encoder->private_->seek_callback, encoder->private_->write_callback, encoder->private_->client_data)) {
1058
 
                        simple_ogg_page__clear(&page);
1059
 
                        return; /* state already set */
1060
 
                }
1061
 
                simple_ogg_page__clear(&page);
1062
 
        }
1063
 
}