initial import, still more work to be done...
[platform/upstream/flac.git] / src / libOggFLAC / stream_encoder.c
1 /* libOggFLAC - Free Lossless Audio Codec + Ogg library
2  * Copyright (C) 2002  Josh Coalson
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA  02111-1307, USA.
18  */
19
20 #include <stdio.h>
21 #include <stdlib.h> /* for malloc() */
22 #include <string.h> /* for memcpy() */
23 #include "ogg/ogg.h"
24 #include "FLAC/assert.h"
25 #include "OggFLAC/stream_decoder.h"
26 #include "protected/stream_encoder.h"
27
28 /***********************************************************************
29  *
30  * Private class method prototypes
31  *
32  ***********************************************************************/
33
34 static void set_defaults_(FLAC__StreamEncoder *encoder);
35 static FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data);
36 static void metadata_callback_(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data);
37
38
39 /***********************************************************************
40  *
41  * Private class data
42  *
43  ***********************************************************************/
44
45 typedef struct FLAC__StreamEncoderPrivate {
46         OggFLAC__StreamEncoderWriteCallback write_callback;
47         void *client_data;
48         FLAC__StreamEncoder *stream_encoder;
49         /* internal vars (all the above are class settings) */
50         FLAC__bool is_first_packet;
51         FLAC__uint64 samples_written;
52         struct {
53                 ogg_stream_state stream_state;
54                 ogg_page page;
55         } ogg;
56 } FLAC__StreamEncoderPrivate;
57
58
59 /***********************************************************************
60  *
61  * Public static class data
62  *
63  ***********************************************************************/
64
65 const char * const OggFLAC__StreamEncoderStateString[] = {
66         "OggFLAC__STREAM_ENCODER_OK",
67         "OggFLAC__STREAM_ENCODER_FLAC_STREAM_ENCODER_ERROR",
68         "OggFLAC__STREAM_ENCODER_INVALID_CALLBACK",
69         "OggFLAC__STREAM_ENCODER_MEMORY_ALLOCATION_ERROR",
70         "OggFLAC__STREAM_ENCODER_ALREADY_INITIALIZED",
71         "OggFLAC__STREAM_ENCODER_UNINITIALIZED"
72 };
73
74
75 /***********************************************************************
76  *
77  * Class constructor/destructor
78  *
79  */
80 OggFLAC__StreamEncoder *OggFLAC__stream_encoder_new()
81 {
82         OggFLAC__StreamEncoder *encoder;
83
84         encoder = (OggFLAC__StreamEncoder*)malloc(sizeof(OggFLAC__StreamEncoder));
85         if(encoder == 0) {
86                 return 0;
87         }
88         memset(encoder, 0, sizeof(OggFLAC__StreamEncoder));
89
90         encoder->protected_ = (OggFLAC__StreamEncoderProtected*)malloc(sizeof(OggFLAC__StreamEncoderProtected));
91         if(encoder->protected_ == 0) {
92                 free(encoder);
93                 return 0;
94         }
95         memset(encoder->protected_, 0, sizeof(OggFLAC__StreamEncoderProtected));
96
97         encoder->private_ = (OggFLAC__StreamEncoderPrivate*)malloc(sizeof(OggFLAC__StreamEncoderPrivate));
98         if(encoder->private_ == 0) {
99                 free(encoder->protected_);
100                 free(encoder);
101                 return 0;
102         }
103         memset(encoder->private_, 0, sizeof(OggFLAC__StreamEncoderPrivate));
104
105         encoder->private_->stream_encoder = FLAC__stream_encoder_new();
106         if(0 == encoder->private_->stream_encoder) {
107                 free(encoder->private_);
108                 free(encoder->protected_);
109                 free(encoder);
110                 return 0;
111         }
112
113         set_defaults_(encoder);
114
115         encoder->protected_->state = OggFLAC__STREAM_ENCODER_UNINITIALIZED;
116
117         return encoder;
118 }
119
120 void OggFLAC__stream_encoder_delete(OggFLAC__StreamEncoder *encoder)
121 {
122         FLAC__ASSERT(0 != encoder);
123         FLAC__ASSERT(0 != encoder->protected_);
124         FLAC__ASSERT(0 != encoder->private_);
125         FLAC__ASSERT(0 != encoder->private_->stream_encoder);
126
127         (void)OggFLAC__stream_encoder_finish(encoder);
128  
129         FLAC__stream_encoder_delete(encoder->private_->stream_encoder);
130
131         free(encoder->private_);
132         free(encoder->protected_);
133         free(encoder);
134 }
135
136
137 /***********************************************************************
138  *
139  * Public class methods
140  *
141  ***********************************************************************/
142
143 OggFLAC__StreamEncoderState OggFLAC__stream_encoder_init(FLAC__StreamEncoder *encoder)
144 {
145         FLAC__ASSERT(0 != encoder);
146
147         if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
148                 return encoder->protected_->state = OggFLAC__STREAM_ENCODER_ALREADY_INITIALIZED;
149
150         if(0 == encoder->private_->write_callback)
151                 return encoder->protected_->state = OggFLAC__STREAM_ENCODER_INVALID_CALLBACK;
152
153         FLAC__stream_encoder_set_write_callback(encoder->private_->stream_encoder, write_callback_);
154         FLAC__stream_encoder_set_metadata_callback(encoder->private_->stream_encoder, metadata_callback_);
155         FLAC__stream_encoder_set_client_data(encoder->private_->stream_encoder, encoder);
156
157         if(FLAC__stream_encoder_init(encoder->private_->stream_encoder) != FLAC__STREAM_ENCODER_OK)
158                 return encoder->protected_->state = OggFLAC__STREAM_ENCODER_FLAC_STREAM_ENCODER_ERROR;
159
160         encoder->private_->is_first_packet = true;
161         encoder->private_->samples_written = 0;
162
163         return encoder->protected_->state = OggFLAC__STREAM_ENCODER_OK;
164 }
165
166 void OggFLAC__stream_encoder_finish(OggFLAC__StreamEncoder *encoder)
167 {
168         FLAC__ASSERT(0 != encoder);
169         FLAC__ASSERT(0 != encoder->private_);
170         FLAC__ASSERT(0 != encoder->protected_);
171
172         if(encoder->protected_->state == OggFLAC__STREAM_ENCODER_UNINITIALIZED)
173                 return;
174
175         FLAC__ASSERT(0 != encoder->private_->stream_encoder);
176
177         FLAC__stream_encoder_finish(encoder->private_->stream_encoder);
178
179         set_defaults_(encoder);
180
181         encoder->protected_->state = OggFLAC__STREAM_ENCODER_UNINITIALIZED;
182 }
183
184 FLAC__bool FLAC__stream_encoder_set_verify(FLAC__StreamEncoder *encoder, FLAC__bool value)
185 {
186         FLAC__ASSERT(0 != encoder);
187         FLAC__ASSERT(0 != encoder->private_);
188         FLAC__ASSERT(0 != encoder->protected_);
189         FLAC__ASSERT(0 != encoder->private_->stream_encoder);
190         if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
191                 return false;
192         return FLAC__stream_encoder_set_verify(encoder->private_->stream_encoder, value);
193 }
194
195 FLAC__bool OggFLAC__stream_encoder_set_streamable_subset(OggFLAC__StreamEncoder *encoder, FLAC__bool value)
196 {
197         FLAC__ASSERT(0 != encoder);
198         FLAC__ASSERT(0 != encoder->private_);
199         FLAC__ASSERT(0 != encoder->protected_);
200         FLAC__ASSERT(0 != encoder->private_->stream_encoder);
201         if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
202                 return false;
203         return FLAC__stream_encoder_set_streamable_subset(encoder->private_->stream_encoder, value);
204 }
205
206 FLAC__bool OggFLAC__stream_encoder_set_do_mid_side_stereo(OggFLAC__StreamEncoder *encoder, FLAC__bool value)
207 {
208         FLAC__ASSERT(0 != encoder);
209         FLAC__ASSERT(0 != encoder->private_);
210         FLAC__ASSERT(0 != encoder->protected_);
211         FLAC__ASSERT(0 != encoder->private_->stream_encoder);
212         if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
213                 return false;
214         return FLAC__stream_encoder_set_do_mid_side_stereo(encoder->private_->stream_encoder, value);
215 }
216
217 FLAC__bool OggFLAC__stream_encoder_set_loose_mid_side_stereo(OggFLAC__StreamEncoder *encoder, FLAC__bool value)
218 {
219         FLAC__ASSERT(0 != encoder);
220         FLAC__ASSERT(0 != encoder->private_);
221         FLAC__ASSERT(0 != encoder->protected_);
222         FLAC__ASSERT(0 != encoder->private_->stream_encoder);
223         if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
224                 return false;
225         return FLAC__stream_encoder_set_loose_mid_side_stereo(encoder->private_->stream_encoder, value);
226 }
227
228 FLAC__bool OggFLAC__stream_encoder_set_channels(OggFLAC__StreamEncoder *encoder, unsigned value)
229 {
230         FLAC__ASSERT(0 != encoder);
231         FLAC__ASSERT(0 != encoder->private_);
232         FLAC__ASSERT(0 != encoder->protected_);
233         FLAC__ASSERT(0 != encoder->private_->stream_encoder);
234         if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
235                 return false;
236         return FLAC__stream_encoder_set_channels(encoder->private_->stream_encoder, value);
237 }
238
239 FLAC__bool OggFLAC__stream_encoder_set_bits_per_sample(OggFLAC__StreamEncoder *encoder, unsigned value)
240 {
241         FLAC__ASSERT(0 != encoder);
242         FLAC__ASSERT(0 != encoder->private_);
243         FLAC__ASSERT(0 != encoder->protected_);
244         FLAC__ASSERT(0 != encoder->private_->stream_encoder);
245         if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
246                 return false;
247         return FLAC__stream_encoder_set_bits_per_sample(encoder->private_->stream_encoder, value);
248 }
249
250 FLAC__bool OggFLAC__stream_encoder_set_sample_rate(OggFLAC__StreamEncoder *encoder, unsigned 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_->stream_encoder);
256         if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
257                 return false;
258         return FLAC__stream_encoder_set_sample_rate(encoder->private_->stream_encoder, value);
259 }
260
261 FLAC__bool OggFLAC__stream_encoder_set_blocksize(OggFLAC__StreamEncoder *encoder, unsigned 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_->stream_encoder);
267         if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
268                 return false;
269         return FLAC__stream_encoder_set_blocksize(encoder->private_->stream_encoder, value);
270 }
271
272 FLAC__bool OggFLAC__stream_encoder_set_max_lpc_order(OggFLAC__StreamEncoder *encoder, unsigned 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_->stream_encoder);
278         if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
279                 return false;
280         return FLAC__stream_encoder_set_max_lpc_order(encoder->private_->stream_encoder, value);
281 }
282
283 FLAC__bool OggFLAC__stream_encoder_set_qlp_coeff_precision(OggFLAC__StreamEncoder *encoder, unsigned 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_->stream_encoder);
289         if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
290                 return false;
291         return FLAC__stream_encoder_set_qlp_coeff_precision(encoder->private_->stream_encoder, value);
292 }
293
294 FLAC__bool OggFLAC__stream_encoder_set_do_qlp_coeff_prec_search(OggFLAC__StreamEncoder *encoder, FLAC__bool 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_->stream_encoder);
300         if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
301                 return false;
302         return FLAC__stream_encoder_set_do_qlp_coeff_prec_search(encoder->private_->stream_encoder, value);
303 }
304
305 FLAC__bool OggFLAC__stream_encoder_set_do_escape_coding(OggFLAC__StreamEncoder *encoder, FLAC__bool 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_->stream_encoder);
311         if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
312                 return false;
313         return FLAC__stream_encoder_set_do_escape_coding(encoder->private_->stream_encoder, value);
314 }
315
316 FLAC__bool OggFLAC__stream_encoder_set_do_exhaustive_model_search(OggFLAC__StreamEncoder *encoder, FLAC__bool 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_->stream_encoder);
322         if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
323                 return false;
324         return FLAC__stream_encoder_set_do_exhaustive_model_search(encoder->private_->stream_encoder, value);
325 }
326
327 FLAC__bool OggFLAC__stream_encoder_set_min_residual_partition_order(OggFLAC__StreamEncoder *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_->stream_encoder);
333         if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
334                 return false;
335         return FLAC__stream_encoder_set_min_residual_partition_order(encoder->private_->stream_encoder, value);
336 }
337
338 FLAC__bool OggFLAC__stream_encoder_set_max_residual_partition_order(OggFLAC__StreamEncoder *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_->stream_encoder);
344         if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
345                 return false;
346         return FLAC__stream_encoder_set_max_residual_partition_order(encoder->private_->stream_encoder, value);
347 }
348
349 FLAC__bool OggFLAC__stream_encoder_set_rice_parameter_search_dist(OggFLAC__StreamEncoder *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_->stream_encoder);
355         if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
356                 return false;
357         return FLAC__stream_encoder_set_rice_parameter_search_dist(encoder->private_->stream_encoder, value);
358 }
359
360 FLAC__bool OggFLAC__stream_encoder_set_total_samples_estimate(OggFLAC__StreamEncoder *encoder, FLAC__uint64 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_->stream_encoder);
366         if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
367                 return false;
368         return FLAC__stream_encoder_set_total_samples_estimate(encoder->private_->stream_encoder, value);
369 }
370
371 FLAC__bool OggFLAC__stream_encoder_set_metadata(OggFLAC__StreamEncoder *encoder, FLAC__StreamMetadata **metadata, unsigned num_blocks)
372 {
373         FLAC__ASSERT(0 != encoder);
374         FLAC__ASSERT(0 != encoder->private_);
375         FLAC__ASSERT(0 != encoder->protected_);
376         FLAC__ASSERT(0 != encoder->private_->stream_encoder);
377         if(encoder->protected_->state != OggFLAC__SEEKABLE_STREAM_ENCODER_UNINITIALIZED)
378                 return false;
379         return FLAC__stream_encoder_set_metadata(encoder->private_->stream_encoder, value);
380 }
381
382 FLAC__bool OggFLAC__stream_encoder_set_write_callback(OggFLAC__StreamEncoder *encoder, OggFLAC__StreamEncoderWriteCallback value)
383 {
384         FLAC__ASSERT(0 != encoder);
385         FLAC__ASSERT(0 != encoder->private_);
386         FLAC__ASSERT(0 != encoder->protected_);
387         FLAC__ASSERT(0 != value);
388         if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
389                 return false;
390         encoder->private_->write_callback = value;
391         return true;
392 }
393
394 FLAC__bool OggFLAC__stream_encoder_set_client_data(OggFLAC__StreamEncoder *encoder, void *value)
395 {
396         FLAC__ASSERT(0 != encoder);
397         FLAC__ASSERT(0 != encoder->private_);
398         FLAC__ASSERT(0 != encoder->protected_);
399         if(encoder->protected_->state != OggFLAC__STREAM_ENCODER_UNINITIALIZED)
400                 return false;
401         encoder->private_->client_data = value;
402         return true;
403 }
404
405 OggFLAC__StreamEncoderState OggFLAC__stream_encoder_get_state(const OggFLAC__StreamEncoder *encoder)
406 {
407         FLAC__ASSERT(0 != encoder);
408         FLAC__ASSERT(0 != encoder->private_);
409         FLAC__ASSERT(0 != encoder->protected_);
410         return encoder->protected_->state;
411 }
412
413 FLAC__StreamEncoderState OggFLAC__stream_encoder_get_FLAC_stream_encoder_state(const OggFLAC__StreamEncoder *encoder)
414 {
415         FLAC__ASSERT(0 != encoder);
416         FLAC__ASSERT(0 != encoder->private_);
417         FLAC__ASSERT(0 != encoder->protected_);
418         return FLAC__stream_encoder_get_state(encoder->private_->encoder);
419 }
420
421 FLAC__StreamDecoderState OggFLAC__stream_encoder_get_verify_decoder_state(const OggFLAC__StreamEncoder *encoder);
422 {
423         FLAC__ASSERT(0 != encoder);
424         FLAC__ASSERT(0 != encoder->private_);
425         FLAC__ASSERT(0 != encoder->protected_);
426         return FLAC__stream_encoder_get_verify_decoder_state(encoder->private_->encoder);
427 }
428
429 FLAC__bool OggFLAC__stream_encoder_get_verify(const OggFLAC__StreamEncoder *encoder)
430 {
431         FLAC__ASSERT(0 != encoder);
432         FLAC__ASSERT(0 != encoder->private_);
433         FLAC__ASSERT(0 != encoder->protected_);
434         return FLAC__stream_encoder_get_verify(encoder->private_->encoder);
435 }
436
437 FLAC__bool OggFLAC__stream_encoder_get_streamable_subset(const OggFLAC__StreamEncoder *encoder)
438 {
439         FLAC__ASSERT(0 != encoder);
440         FLAC__ASSERT(0 != encoder->private_);
441         FLAC__ASSERT(0 != encoder->protected_);
442         return FLAC__stream_encoder_get_streamable_subset(encoder->private_->encoder);
443 }
444
445 FLAC__bool OggFLAC__stream_encoder_get_do_mid_side_stereo(const OggFLAC__StreamEncoder *encoder)
446 {
447         FLAC__ASSERT(0 != encoder);
448         FLAC__ASSERT(0 != encoder->private_);
449         FLAC__ASSERT(0 != encoder->protected_);
450         return FLAC__stream_encoder_get_do_mid_side_stereo(encoder->private_->encoder);
451 }
452
453 FLAC__bool OggFLAC__stream_encoder_get_loose_mid_side_stereo(const OggFLAC__StreamEncoder *encoder)
454 {
455         FLAC__ASSERT(0 != encoder);
456         FLAC__ASSERT(0 != encoder->private_);
457         FLAC__ASSERT(0 != encoder->protected_);
458         return FLAC__stream_encoder_get_loose_mid_side_stereo(encoder->private_->encoder);
459 }
460
461 unsigned OggFLAC__stream_encoder_get_channels(const OggFLAC__StreamEncoder *encoder)
462 {
463         FLAC__ASSERT(0 != encoder);
464         FLAC__ASSERT(0 != encoder->private_);
465         FLAC__ASSERT(0 != encoder->protected_);
466         return FLAC__stream_encoder_get_channels(encoder->private_->encoder);
467 }
468
469 unsigned OggFLAC__stream_encoder_get_bits_per_sample(const OggFLAC__StreamEncoder *encoder)
470 {
471         FLAC__ASSERT(0 != encoder);
472         FLAC__ASSERT(0 != encoder->private_);
473         FLAC__ASSERT(0 != encoder->protected_);
474         return FLAC__stream_encoder_get_bits_per_sample(encoder->private_->encoder);
475 }
476
477 unsigned OggFLAC__stream_encoder_get_sample_rate(const OggFLAC__StreamEncoder *encoder)
478 {
479         FLAC__ASSERT(0 != encoder);
480         FLAC__ASSERT(0 != encoder->private_);
481         FLAC__ASSERT(0 != encoder->protected_);
482         return FLAC__stream_encoder_get_sample_rate(encoder->private_->encoder);
483 }
484
485 unsigned OggFLAC__stream_encoder_get_blocksize(const OggFLAC__StreamEncoder *encoder)
486 {
487         FLAC__ASSERT(0 != encoder);
488         FLAC__ASSERT(0 != encoder->private_);
489         FLAC__ASSERT(0 != encoder->protected_);
490         return FLAC__stream_encoder_get_blocksize(encoder->private_->encoder);
491 }
492
493 unsigned OggFLAC__stream_encoder_get_max_lpc_order(const OggFLAC__StreamEncoder *encoder)
494 {
495         FLAC__ASSERT(0 != encoder);
496         FLAC__ASSERT(0 != encoder->private_);
497         FLAC__ASSERT(0 != encoder->protected_);
498         return FLAC__stream_encoder_get_max_lpc_order(encoder->private_->encoder);
499 }
500
501 unsigned OggFLAC__stream_encoder_get_qlp_coeff_precision(const OggFLAC__StreamEncoder *encoder)
502 {
503         FLAC__ASSERT(0 != encoder);
504         FLAC__ASSERT(0 != encoder->private_);
505         FLAC__ASSERT(0 != encoder->protected_);
506         return FLAC__stream_encoder_get_qlp_coeff_precision(encoder->private_->encoder);
507 }
508
509 FLAC__bool OggFLAC__stream_encoder_get_do_qlp_coeff_prec_search(const OggFLAC__StreamEncoder *encoder)
510 {
511         FLAC__ASSERT(0 != encoder);
512         FLAC__ASSERT(0 != encoder->private_);
513         FLAC__ASSERT(0 != encoder->protected_);
514         return FLAC__stream_encoder_get_do_qlp_coeff_prec_search(encoder->private_->encoder);
515 }
516
517 FLAC__bool OggFLAC__stream_encoder_get_do_escape_coding(const OggFLAC__StreamEncoder *encoder)
518 {
519         FLAC__ASSERT(0 != encoder);
520         FLAC__ASSERT(0 != encoder->private_);
521         FLAC__ASSERT(0 != encoder->protected_);
522         return FLAC__stream_encoder_get_do_escape_coding(encoder->private_->encoder);
523 }
524
525 FLAC__bool OggFLAC__stream_encoder_get_do_exhaustive_model_search(const OggFLAC__StreamEncoder *encoder)
526 {
527         FLAC__ASSERT(0 != encoder);
528         FLAC__ASSERT(0 != encoder->private_);
529         FLAC__ASSERT(0 != encoder->protected_);
530         return FLAC__stream_encoder_get_do_exhaustive_model_search(encoder->private_->encoder);
531 }
532
533 unsigned OggFLAC__stream_encoder_get_min_residual_partition_order(const OggFLAC__StreamEncoder *encoder)
534 {
535         FLAC__ASSERT(0 != encoder);
536         FLAC__ASSERT(0 != encoder->private_);
537         FLAC__ASSERT(0 != encoder->protected_);
538         return FLAC__stream_encoder_get_min_residual_partition_order(encoder->private_->encoder);
539 }
540
541 unsigned OggFLAC__stream_encoder_get_max_residual_partition_order(const OggFLAC__StreamEncoder *encoder)
542 {
543         FLAC__ASSERT(0 != encoder);
544         FLAC__ASSERT(0 != encoder->private_);
545         FLAC__ASSERT(0 != encoder->protected_);
546         return FLAC__stream_encoder_get_max_residual_partition_order(encoder->private_->encoder);
547 }
548
549 unsigned OggFLAC__stream_encoder_get_rice_parameter_search_dist(const OggFLAC__StreamEncoder *encoder)
550 {
551         FLAC__ASSERT(0 != encoder);
552         FLAC__ASSERT(0 != encoder->private_);
553         FLAC__ASSERT(0 != encoder->protected_);
554         return FLAC__stream_encoder_get_rice_parameter_search_dist(encoder->private_->encoder);
555 }
556
557 FLAC__uint64 OggFLAC__stream_encoder_get_total_samples_estimate(const OggFLAC__StreamEncoder *encoder)
558 {
559         FLAC__ASSERT(0 != encoder);
560         FLAC__ASSERT(0 != encoder->private_);
561         FLAC__ASSERT(0 != encoder->protected_);
562         return FLAC__stream_encoder_get_total_samples_estimate(encoder->private_->encoder);
563 }
564
565 FLAC__bool FLAC__stream_encoder_process(FLAC__StreamEncoder *encoder, const FLAC__int32 * const buffer[], unsigned samples)
566 {
567         FLAC__ASSERT(0 != encoder);
568         FLAC__ASSERT(0 != encoder->private_);
569         FLAC__ASSERT(0 != encoder->protected_);
570         return FLAC__stream_encoder_process(encoder->private_->encoder, buffer, samples);
571 }
572
573 FLAC__bool FLAC__stream_encoder_process_interleaved(FLAC__StreamEncoder *encoder, const FLAC__int32 buffer[], unsigned samples)
574 {
575         FLAC__ASSERT(0 != encoder);
576         FLAC__ASSERT(0 != encoder->private_);
577         FLAC__ASSERT(0 != encoder->protected_);
578         return FLAC__stream_encoder_process_interleaved(encoder->private_->encoder, buffer, samples);
579 }
580
581 /***********************************************************************
582  *
583  * Private class methods
584  *
585  ***********************************************************************/
586
587 void set_defaults_(FLAC__StreamEncoder *encoder)
588 {
589         FLAC__ASSERT(0 != encoder);
590
591         encoder->private_->write_callback = 0;
592         encoder->private_->client_data = 0;
593 }
594
595 FLAC__StreamEncoderWriteStatus write_callback_(const FLAC__StreamEncoder *encoder, const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame, void *client_data)
596 {
597         ogg_packet packet;
598
599         encoder->private_->samples_written += samples;
600
601         memset(&packet, 0, sizeof(packet));
602         packet.packet = (unsigned char *)buffer;
603         packet.granulepos = encoder->private_->samples_written - 1;
604         /*@@@ WATCHOUT:
605          * This depends on the behavior of FLAC__StreamEncoder that 'samples'
606          * will be 0 for metadata writes.
607          */
608         packet.packetno = (samples == 0? -1 : (int)current_frame);
609         packet.bytes = bytes;
610
611         if(encoder->private_->is_first_packet) {
612                 packet.b_o_s = 1;
613                 encoder->private_->is_first_packet = false;
614         }
615
616         if(encoder->private_->total_samples_to_encode > 0 && encoder->private_->total_samples_to_encode == encoder->private_->samples_written)
617                 packet.e_o_s = 1;
618
619         ogg_stream_packetin(&encoder->private_->ogg.stream_state, &packet);
620
621         while(ogg_stream_pageout(&encoder->private_->ogg.stream_state, &encoder->private_->ogg.page) != 0) {
622                 if(encoder->private_->write_callback(encoder, encoder->private_->ogg.page.header, encoder->private_->ogg.page.header_len) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK)
623                         return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
624
625                 if(encoder->private_->write_callback(encoder, encoder->private_->ogg.page.body, encoder->private_->ogg.page.body_len) != FLAC__STREAM_ENCODER_WRITE_STATUS_OK)
626                         return FLAC__STREAM_ENCODER_WRITE_STATUS_FATAL_ERROR;
627         }
628
629         return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
630 }
631
632 void metadata_callback_(const FLAC__StreamEncoder *encoder, const FLAC__StreamMetadata *metadata, void *client_data)
633 {
634         /*
635          * We don't try to go back an update metadata blocks by mucking
636          * around inside the Ogg layer.  Maybe someday we will care to
637          * and an OggFLAC__SeekableStreamEncoder and OggFLAC__FileEncoder
638          * will be possible but it may just never be useful.
639          */
640         (void)encoder, (void)metadata, (void)client_data;
641 }