Remove const on OggOpusComments
[libopusenc.git] / src / opusenc.c
1 /* Copyright (C)2002-2017 Jean-Marc Valin
2    Copyright (C)2007-2013 Xiph.Org Foundation
3    Copyright (C)2008-2013 Gregory Maxwell
4    File: opusenc.c
5
6    Redistribution and use in source and binary forms, with or without
7    modification, are permitted provided that the following conditions
8    are met:
9
10    - Redistributions of source code must retain the above copyright
11    notice, this list of conditions and the following disclaimer.
12
13    - Redistributions in binary form must reproduce the above copyright
14    notice, this list of conditions and the following disclaimer in the
15    documentation and/or other materials provided with the distribution.
16
17    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
21    OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
25    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #ifdef HAVE_CONFIG_H
31 #include "config.h"
32 #endif
33
34 #include <stdarg.h>
35 #include <stdlib.h>
36 #include <stdio.h>
37 #include <string.h>
38 #include <assert.h>
39 #include <opus_multistream.h>
40 #include "opusenc.h"
41 #include "opus_header.h"
42 #include "speex_resampler.h"
43 #include "picture.h"
44 #include "ogg_packer.h"
45
46 /* Bump this when we change the ABI. */
47 #define OPE_ABI_VERSION 0
48
49 #define LPC_PADDING 120
50 #define LPC_ORDER 24
51 #define LPC_INPUT 480
52 /* Make the following constant always equal to 2*cos(M_PI/LPC_PADDING) */
53 #define LPC_GOERTZEL_CONST 1.99931465f
54
55 /* Allow up to 2 seconds for delayed decision. */
56 #define MAX_LOOKAHEAD 96000
57 /* We can't have a circular buffer (because of delayed decision), so let's not copy too often. */
58 #define BUFFER_EXTRA 24000
59
60 #define BUFFER_SAMPLES (MAX_LOOKAHEAD + BUFFER_EXTRA)
61
62 #define MIN(a,b) ((a) < (b) ? (a) : (b))
63 #define MAX(a,b) ((a) > (b) ? (a) : (b))
64
65 #define MAX_PACKET_SIZE (1276*8)
66
67 struct StdioObject {
68   FILE *file;
69 };
70
71 struct OggOpusComments {
72   char *comment;
73   int comment_length;
74   int seen_file_icons;
75 };
76
77 /* Create a new comments object. The vendor string is optional. */
78 OggOpusComments *ope_comments_create() {
79   OggOpusComments *c;
80   const char *libopus_str;
81   char vendor_str[1024];
82   c = malloc(sizeof(*c));
83   if (c == NULL) return NULL;
84   libopus_str = opus_get_version_string();
85   snprintf(vendor_str, sizeof(vendor_str), "%s, %s version %s", libopus_str, PACKAGE_NAME, PACKAGE_VERSION);
86   comment_init(&c->comment, &c->comment_length, vendor_str);
87   if (c->comment == NULL) {
88     free(c);
89     return NULL;
90   } else {
91     return c;
92   }
93 }
94
95 /* Create a deep copy of a comments object. */
96 OggOpusComments *ope_comments_copy(OggOpusComments *comments) {
97   OggOpusComments *c;
98   c = malloc(sizeof(*c));
99   if (c == NULL) return NULL;
100   memcpy(c, comments, sizeof(*c));
101   c->comment = malloc(comments->comment_length);
102   if (c->comment == NULL) {
103     free(c);
104     return NULL;
105   } else {
106     memcpy(c->comment, comments->comment, comments->comment_length);
107     return c;
108   }
109 }
110
111 /* Destroys a comments object. */
112 void ope_comments_destroy(OggOpusComments *comments){
113   free(comments->comment);
114   free(comments);
115 }
116
117 /* Add a comment. */
118 int ope_comments_add(OggOpusComments *comments, const char *tag, const char *val) {
119   if (tag == NULL || val == NULL) return OPE_BAD_ARG;
120   if (strchr(tag, '=')) return OPE_BAD_ARG;
121   if (comment_add(&comments->comment, &comments->comment_length, tag, val)) return OPE_ALLOC_FAIL;
122   return OPE_OK;
123 }
124
125 /* Add a comment. */
126 int ope_comments_add_string(OggOpusComments *comments, const char *tag_and_val) {
127   if (!strchr(tag_and_val, '=')) return OPE_BAD_ARG;
128   if (comment_add(&comments->comment, &comments->comment_length, tag_and_val, NULL)) return OPE_ALLOC_FAIL;
129   return OPE_OK;
130 }
131
132 int ope_comments_add_picture(OggOpusComments *comments, const char *spec) {
133   const char *error_message;
134   char *picture_data;
135   picture_data = parse_picture_specification(spec, &error_message, &comments->seen_file_icons);
136   if(picture_data==NULL){
137     /* FIXME: return proper errors rather than printing a message. */
138     fprintf(stderr,"Error parsing picture option: %s\n",error_message);
139     return OPE_BAD_ARG;
140   }
141   comment_add(&comments->comment, &comments->comment_length, "METADATA_BLOCK_PICTURE", picture_data);
142   free(picture_data);
143   return OPE_OK;
144 }
145
146
147 typedef struct EncStream EncStream;
148
149 struct EncStream {
150   void *user_data;
151   int serialno_is_set;
152   int serialno;
153   int stream_is_init;
154   int packetno;
155   char *comment;
156   int comment_length;
157   int seen_file_icons;
158   int close_at_end;
159   int header_is_frozen;
160   opus_int64 end_granule;
161   opus_int64 granule_offset;
162   EncStream *next;
163 };
164
165 struct OggOpusEnc {
166   OpusMSEncoder *st;
167   oggpacker *oggp;
168   int unrecoverable;
169   int pull_api;
170   int rate;
171   int channels;
172   float *buffer;
173   int buffer_start;
174   int buffer_end;
175   SpeexResamplerState *re;
176   int frame_size;
177   int decision_delay;
178   int max_ogg_delay;
179   int global_granule_offset;
180   opus_int64 curr_granule;
181   opus_int64 write_granule;
182   opus_int64 last_page_granule;
183   unsigned char *chaining_keyframe;
184   int chaining_keyframe_length;
185   OpusEncCallbacks callbacks;
186   ope_packet_func packet_callback;
187   void *packet_callback_data;
188   OpusHeader header;
189   int comment_padding;
190   EncStream *streams;
191   EncStream *last_stream;
192 };
193
194 static void output_pages(OggOpusEnc *enc) {
195   unsigned char *page;
196   int len;
197   while (oggp_get_next_page(enc->oggp, &page, &len)) {
198     enc->callbacks.write(enc->streams->user_data, page, len);
199   }
200 }
201 static void oe_flush_page(OggOpusEnc *enc) {
202   oggp_flush_page(enc->oggp);
203   if (!enc->pull_api) output_pages(enc);
204 }
205
206 int stdio_write(void *user_data, const unsigned char *ptr, opus_int32 len) {
207   struct StdioObject *obj = (struct StdioObject*)user_data;
208   return fwrite(ptr, 1, len, obj->file) != (size_t)len;
209 }
210
211 int stdio_close(void *user_data) {
212   struct StdioObject *obj = (struct StdioObject*)user_data;
213   int ret = 0;
214   if (obj->file) ret = fclose(obj->file);
215   free(obj);
216   return ret;
217 }
218
219 static const OpusEncCallbacks stdio_callbacks = {
220   stdio_write,
221   stdio_close
222 };
223
224 /* Create a new OggOpus file. */
225 OggOpusEnc *ope_encoder_create_file(const char *path, OggOpusComments *comments, opus_int32 rate, int channels, int family, int *error) {
226   OggOpusEnc *enc;
227   struct StdioObject *obj;
228   obj = malloc(sizeof(*obj));
229   enc = ope_encoder_create_callbacks(&stdio_callbacks, obj, comments, rate, channels, family, error);
230   if (enc == NULL || (error && *error)) {
231     return NULL;
232   }
233   obj->file = fopen(path, "wb");
234   if (!obj->file) {
235     if (error) *error = OPE_CANNOT_OPEN;
236     ope_encoder_destroy(enc);
237     return NULL;
238   }
239   return enc;
240 }
241
242 EncStream *stream_create(OggOpusComments *comments) {
243   EncStream *stream;
244   stream = malloc(sizeof(*stream));
245   if (!stream) return NULL;
246   stream->next = NULL;
247   stream->close_at_end = 1;
248   stream->serialno_is_set = 0;
249   stream->stream_is_init = 0;
250   stream->header_is_frozen = 0;
251   stream->granule_offset = 0;
252   stream->comment = malloc(comments->comment_length);
253   if (stream->comment == NULL) goto fail;
254   memcpy(stream->comment, comments->comment, comments->comment_length);
255   stream->comment_length = comments->comment_length;
256   stream->seen_file_icons = comments->seen_file_icons;
257   return stream;
258 fail:
259   if (stream->comment) free(stream->comment);
260   free(stream);
261   return NULL;
262 }
263
264 static void stream_destroy(EncStream *stream) {
265   if (stream->comment) free(stream->comment);
266   free(stream);
267 }
268
269 /* Create a new OggOpus file (callback-based). */
270 OggOpusEnc *ope_encoder_create_callbacks(const OpusEncCallbacks *callbacks, void *user_data,
271     OggOpusComments *comments, opus_int32 rate, int channels, int family, int *error) {
272   OpusMSEncoder *st=NULL;
273   OggOpusEnc *enc=NULL;
274   int ret;
275   if (family != 0 && family != 1 && family != 255) {
276     if (error) *error = OPE_UNIMPLEMENTED;
277     return NULL;
278   }
279   if (channels <= 0 || channels > 255) {
280     if (error) *error = OPE_BAD_ARG;
281     return NULL;
282   }
283   if (rate <= 0) {
284     if (error) *error = OPE_BAD_ARG;
285     return NULL;
286   }
287
288   if ( (enc = malloc(sizeof(*enc))) == NULL) goto fail;
289   enc->streams = NULL;
290   if ( (enc->streams = stream_create(comments)) == NULL) goto fail;
291   enc->streams->next = NULL;
292   enc->last_stream = enc->streams;
293   enc->oggp = NULL;
294   enc->unrecoverable = 0;
295   enc->pull_api = 0;
296   enc->packet_callback = NULL;
297   enc->rate = rate;
298   enc->channels = channels;
299   enc->frame_size = 960;
300   enc->decision_delay = 96000;
301   enc->max_ogg_delay = 48000;
302   enc->chaining_keyframe = NULL;
303   enc->chaining_keyframe_length = -1;
304   enc->comment_padding = 512;
305   enc->header.channels=channels;
306   enc->header.channel_mapping=family;
307   enc->header.input_sample_rate=rate;
308   enc->header.gain=0;
309   st=opus_multistream_surround_encoder_create(48000, channels, enc->header.channel_mapping,
310       &enc->header.nb_streams, &enc->header.nb_coupled,
311       enc->header.stream_map, OPUS_APPLICATION_AUDIO, &ret);
312   if (! (ret == OPUS_OK && st != NULL) ) {
313     goto fail;
314   }
315   if (rate != 48000) {
316     enc->re = speex_resampler_init(channels, rate, 48000, 5, NULL);
317     if (enc->re == NULL) goto fail;
318     speex_resampler_skip_zeros(enc->re);
319   } else {
320     enc->re = NULL;
321   }
322   opus_multistream_encoder_ctl(st, OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_20_MS));
323   {
324     opus_int32 tmp;
325     int ret;
326     ret = opus_multistream_encoder_ctl(st, OPUS_GET_LOOKAHEAD(&tmp));
327     if (ret == OPUS_OK) enc->header.preskip = tmp;
328     else enc->header.preskip = 0;
329     enc->global_granule_offset = enc->header.preskip;
330   }
331   enc->curr_granule = 0;
332   enc->write_granule = 0;
333   enc->last_page_granule = 0;
334   if ( (enc->buffer = malloc(sizeof(*enc->buffer)*BUFFER_SAMPLES*channels)) == NULL) goto fail;
335   enc->buffer_start = enc->buffer_end = 0;
336   enc->st = st;
337   enc->callbacks = *callbacks;
338   enc->streams->user_data = user_data;
339   if (error) *error = OPE_OK;
340   return enc;
341 fail:
342   if (enc) {
343     free(enc);
344     if (enc->buffer) free(enc->buffer);
345     if (enc->streams) stream_destroy(enc->streams);
346   }
347   if (st) {
348     opus_multistream_encoder_destroy(st);
349   }
350   if (error) *error = OPE_ALLOC_FAIL;
351   return NULL;
352 }
353
354 /* Create a new OggOpus stream, pulling one page at a time. */
355 OPE_EXPORT OggOpusEnc *ope_encoder_create_pull(OggOpusComments *comments, opus_int32 rate, int channels, int family, int *error) {
356   OggOpusEnc *enc = ope_encoder_create_callbacks(NULL, NULL, comments, rate, channels, family, error);
357   enc->pull_api = 1;
358   return enc;
359 }
360
361 static void init_stream(OggOpusEnc *enc) {
362   assert(!enc->streams->stream_is_init);
363   if (!enc->streams->serialno_is_set) {
364     enc->streams->serialno = rand();
365   }
366
367   if (enc->oggp != NULL) oggp_chain(enc->oggp, enc->streams->serialno);
368   else {
369     enc->oggp = oggp_create(enc->streams->serialno);
370     if (enc->oggp == NULL) {
371       enc->unrecoverable = 1;
372       return;
373     }
374     oggp_set_muxing_delay(enc->oggp, enc->max_ogg_delay);
375   }
376   comment_pad(&enc->streams->comment, &enc->streams->comment_length, enc->comment_padding);
377
378   /*Write header*/
379   {
380     unsigned char *p;
381     p = oggp_get_packet_buffer(enc->oggp, 276);
382     int packet_size = opus_header_to_packet(&enc->header, p, 276);
383     oggp_commit_packet(enc->oggp, packet_size, 0, 0);
384     if (enc->packet_callback) enc->packet_callback(enc->packet_callback_data, p, packet_size, 0);
385     oe_flush_page(enc);
386     p = oggp_get_packet_buffer(enc->oggp, enc->streams->comment_length);
387     memcpy(p, enc->streams->comment, enc->streams->comment_length);
388     oggp_commit_packet(enc->oggp, enc->streams->comment_length, 0, 0);
389     if (enc->packet_callback) enc->packet_callback(enc->packet_callback_data, p, enc->streams->comment_length, 0);
390     oe_flush_page(enc);
391   }
392   enc->streams->stream_is_init = 1;
393   enc->streams->packetno = 2;
394 }
395
396 static void shift_buffer(OggOpusEnc *enc) {
397   /* Leaving enough in the buffer to do LPC extension if needed. */
398   if (enc->buffer_start > LPC_INPUT) {
399     memmove(&enc->buffer[enc->channels*LPC_INPUT], &enc->buffer[enc->channels*enc->buffer_start], enc->channels*(enc->buffer_end-enc->buffer_start)*sizeof(*enc->buffer));
400     enc->buffer_end -= enc->buffer_start-LPC_INPUT;
401     enc->buffer_start = LPC_INPUT;
402   }
403 }
404
405 static void encode_buffer(OggOpusEnc *enc) {
406   /* Round up when converting the granule pos because the decoder will round down. */
407   opus_int64 end_granule48k = (enc->streams->end_granule*48000 + enc->rate - 1)/enc->rate + enc->global_granule_offset;
408   while (enc->buffer_end-enc->buffer_start > enc->frame_size + enc->decision_delay) {
409     int cont;
410     int e_o_s;
411     opus_int32 pred;
412     int nbBytes;
413     unsigned char packet[MAX_PACKET_SIZE];
414     int is_keyframe=0;
415     if (enc->unrecoverable) return;
416     opus_multistream_encoder_ctl(enc->st, OPUS_GET_PREDICTION_DISABLED(&pred));
417     /* FIXME: a frame that follows a keyframe generally doesn't need to be a keyframe
418        unless there's two consecutive stream boundaries. */
419     if (enc->curr_granule + 2*enc->frame_size>= end_granule48k && enc->streams->next) {
420       opus_multistream_encoder_ctl(enc->st, OPUS_SET_PREDICTION_DISABLED(1));
421       is_keyframe = 1;
422     }
423     nbBytes = opus_multistream_encode_float(enc->st, &enc->buffer[enc->channels*enc->buffer_start],
424         enc->buffer_end-enc->buffer_start, packet, MAX_PACKET_SIZE);
425     if (nbBytes < 0) {
426       /* Anything better we can do here? */
427       enc->unrecoverable = 1;
428       return;
429     }
430     opus_multistream_encoder_ctl(enc->st, OPUS_SET_PREDICTION_DISABLED(pred));
431     assert(nbBytes > 0);
432     enc->curr_granule += enc->frame_size;
433     do {
434       unsigned char *p;
435       opus_int64 granulepos;
436       granulepos=enc->curr_granule-enc->streams->granule_offset;
437       e_o_s=enc->curr_granule >= end_granule48k;
438       cont = 0;
439       if (e_o_s) granulepos=end_granule48k-enc->streams->granule_offset;
440       p = oggp_get_packet_buffer(enc->oggp, MAX_PACKET_SIZE);
441       memcpy(p, packet, nbBytes);
442       oggp_commit_packet(enc->oggp, nbBytes, granulepos, e_o_s);
443       if (enc->packet_callback) enc->packet_callback(enc->packet_callback_data, packet, nbBytes, 0);
444       if (e_o_s) oe_flush_page(enc);
445       else if (!enc->pull_api) output_pages(enc);
446       if (e_o_s) {
447         EncStream *tmp;
448         tmp = enc->streams->next;
449         if (enc->streams->close_at_end) enc->callbacks.close(enc->streams->user_data);
450         stream_destroy(enc->streams);
451         enc->streams = tmp;
452         if (!tmp) enc->last_stream = NULL;
453         if (enc->last_stream == NULL) return;
454         /* We're done with this stream, start the next one. */
455         enc->header.preskip = end_granule48k + enc->frame_size - enc->curr_granule;
456         enc->streams->granule_offset = enc->curr_granule - enc->frame_size;
457         if (enc->chaining_keyframe) {
458           enc->header.preskip += enc->frame_size;
459           enc->streams->granule_offset -= enc->frame_size;
460         }
461         init_stream(enc);
462         if (enc->chaining_keyframe) {
463           opus_int64 granulepos2=enc->curr_granule - enc->streams->granule_offset - enc->frame_size;
464           p = oggp_get_packet_buffer(enc->oggp, MAX_PACKET_SIZE);
465           memcpy(p, enc->chaining_keyframe, enc->chaining_keyframe_length);
466           oggp_commit_packet(enc->oggp, enc->chaining_keyframe_length, granulepos2, 0);
467           if (enc->packet_callback) enc->packet_callback(enc->packet_callback_data, enc->chaining_keyframe, enc->chaining_keyframe_length, 0);
468         }
469         end_granule48k = (enc->streams->end_granule*48000 + enc->rate - 1)/enc->rate + enc->global_granule_offset;
470         cont = 1;
471       }
472     } while (cont);
473     if (enc->chaining_keyframe) free(enc->chaining_keyframe);
474     if (is_keyframe) {
475       enc->chaining_keyframe = malloc(nbBytes);
476       enc->chaining_keyframe_length = nbBytes;
477       memcpy(enc->chaining_keyframe, packet, nbBytes);
478     } else {
479       enc->chaining_keyframe = NULL;
480       enc->chaining_keyframe_length = -1;
481     }
482     enc->buffer_start += enc->frame_size;
483   }
484   /* If we've reached the end of the buffer, move everything back to the front. */
485   if (enc->buffer_end == BUFFER_SAMPLES) {
486     shift_buffer(enc);
487   }
488   /* This function must never leave the buffer full. */
489   assert(enc->buffer_end < BUFFER_SAMPLES);
490 }
491
492 /* Add/encode any number of float samples to the file. */
493 int ope_encoder_write_float(OggOpusEnc *enc, const float *pcm, int samples_per_channel) {
494   int channels = enc->channels;
495   if (enc->unrecoverable) return OPE_UNRECOVERABLE;
496   enc->last_stream->header_is_frozen = 1;
497   if (!enc->streams->stream_is_init) init_stream(enc);
498   if (samples_per_channel < 0) return OPE_BAD_ARG;
499   enc->write_granule += samples_per_channel;
500   enc->last_stream->end_granule = enc->write_granule;
501   do {
502     int i;
503     spx_uint32_t in_samples, out_samples;
504     out_samples = BUFFER_SAMPLES-enc->buffer_end;
505     if (enc->re != NULL) {
506       in_samples = samples_per_channel;
507       speex_resampler_process_interleaved_float(enc->re, pcm, &in_samples, &enc->buffer[channels*enc->buffer_end], &out_samples);
508     } else {
509       int curr;
510       curr = MIN((spx_uint32_t)samples_per_channel, out_samples);
511       for (i=0;i<channels*curr;i++) {
512       enc->buffer[channels*enc->buffer_end+i] = pcm[i];
513       }
514       in_samples = out_samples = curr;
515     }
516     enc->buffer_end += out_samples;
517     pcm += in_samples*channels;
518     samples_per_channel -= in_samples;
519     encode_buffer(enc);
520     if (enc->unrecoverable) return OPE_UNRECOVERABLE;
521   } while (samples_per_channel > 0);
522   return OPE_OK;
523 }
524
525 #define CONVERT_BUFFER 4096
526
527 /* Add/encode any number of int16 samples to the file. */
528 int ope_encoder_write(OggOpusEnc *enc, const opus_int16 *pcm, int samples_per_channel) {
529   int channels = enc->channels;
530   if (enc->unrecoverable) return OPE_UNRECOVERABLE;
531   enc->last_stream->header_is_frozen = 1;
532   if (!enc->streams->stream_is_init) init_stream(enc);
533   if (samples_per_channel < 0) return OPE_BAD_ARG;
534   enc->write_granule += samples_per_channel;
535   enc->last_stream->end_granule = enc->write_granule;
536   do {
537     int i;
538     spx_uint32_t in_samples, out_samples;
539     out_samples = BUFFER_SAMPLES-enc->buffer_end;
540     if (enc->re != NULL) {
541       float buf[CONVERT_BUFFER];
542       in_samples = MIN(CONVERT_BUFFER/channels, samples_per_channel);
543       for (i=0;i<channels*(int)in_samples;i++) {
544         buf[i] = (1.f/32768)*pcm[i];
545       }
546       speex_resampler_process_interleaved_float(enc->re, buf, &in_samples, &enc->buffer[channels*enc->buffer_end], &out_samples);
547     } else {
548       int curr;
549       curr = MIN((spx_uint32_t)samples_per_channel, out_samples);
550       for (i=0;i<channels*curr;i++) {
551         enc->buffer[channels*enc->buffer_end+i] = (1.f/32768)*pcm[i];
552       }
553       in_samples = out_samples = curr;
554     }
555     enc->buffer_end += out_samples;
556     pcm += in_samples*channels;
557     samples_per_channel -= in_samples;
558     encode_buffer(enc);
559     if (enc->unrecoverable) return OPE_UNRECOVERABLE;
560   } while (samples_per_channel > 0);
561   return OPE_OK;
562 }
563
564 /* Get the next page from the stream. Returns 1 if there is a page available, 0 if not. */
565 OPE_EXPORT int ope_encoder_get_page(OggOpusEnc *enc, unsigned char **page, opus_int32 *len, int flush) {
566   if (enc->unrecoverable) return OPE_UNRECOVERABLE;
567   if (!enc->pull_api) return 0;
568   else {
569     if (flush) oggp_flush_page(enc->oggp);
570     return oggp_get_next_page(enc->oggp, page, len);
571   }
572 }
573
574 static void extend_signal(float *x, int before, int after, int channels);
575
576 int ope_encoder_drain(OggOpusEnc *enc) {
577   int pad_samples;
578   if (enc->unrecoverable) return OPE_UNRECOVERABLE;
579   /* Check if it's already been drained. */
580   if (enc->streams == NULL) return OPE_TOO_LATE;
581   pad_samples = MAX(LPC_PADDING, enc->global_granule_offset + enc->frame_size);
582   if (!enc->streams->stream_is_init) init_stream(enc);
583   shift_buffer(enc);
584   assert(enc->buffer_end + pad_samples <= BUFFER_SAMPLES);
585   memset(&enc->buffer[enc->channels*enc->buffer_end], 0, pad_samples*enc->channels*sizeof(enc->buffer[0]));
586   extend_signal(&enc->buffer[enc->channels*enc->buffer_end], enc->buffer_end, LPC_PADDING, enc->channels);
587   enc->decision_delay = 0;
588   enc->buffer_end += pad_samples;
589   assert(enc->buffer_end <= BUFFER_SAMPLES);
590   encode_buffer(enc);
591   if (enc->unrecoverable) return OPE_UNRECOVERABLE;
592   /* Draining should have called all the streams to complete. */
593   assert(enc->streams == NULL);
594   return OPE_OK;
595 }
596
597 void ope_encoder_destroy(OggOpusEnc *enc) {
598   EncStream *stream;
599   stream = enc->streams;
600   while (stream != NULL) {
601     EncStream *tmp = stream;
602     stream = stream->next;
603     if (tmp->close_at_end) enc->callbacks.close(tmp->user_data);
604     stream_destroy(tmp);
605   }
606   if (enc->chaining_keyframe) free(enc->chaining_keyframe);
607   free(enc->buffer);
608   if (enc->oggp) oggp_destroy(enc->oggp);
609   opus_multistream_encoder_destroy(enc->st);
610   if (enc->re) speex_resampler_destroy(enc->re);
611   free(enc);
612 }
613
614 /* Ends the stream and create a new stream within the same file. */
615 int ope_encoder_chain_current(OggOpusEnc *enc, OggOpusComments *comments) {
616   enc->last_stream->close_at_end = 0;
617   return ope_encoder_continue_new_callbacks(enc, enc->last_stream->user_data, comments);
618 }
619
620 /* Ends the stream and create a new file. */
621 int ope_encoder_continue_new_file(OggOpusEnc *enc, const char *path, OggOpusComments *comments) {
622   int ret;
623   struct StdioObject *obj;
624   if (!(obj = malloc(sizeof(*obj)))) return OPE_ALLOC_FAIL;
625   obj->file = fopen(path, "wb");
626   if (!obj->file) {
627     free(obj);
628     /* By trying to open the file first, we can recover if we can't open it. */
629     return OPE_CANNOT_OPEN;
630   }
631   ret = ope_encoder_continue_new_callbacks(enc, obj, comments);
632   if (ret == OPE_OK) return ret;
633   fclose(obj->file);
634   free(obj);
635   return ret;
636 }
637
638 /* Ends the stream and create a new file (callback-based). */
639 int ope_encoder_continue_new_callbacks(OggOpusEnc *enc, void *user_data, OggOpusComments *comments) {
640   if (enc->unrecoverable) return OPE_UNRECOVERABLE;
641   EncStream *new_stream;
642   assert(enc->streams);
643   assert(enc->last_stream);
644   new_stream = stream_create(comments);
645   if (!new_stream) return OPE_ALLOC_FAIL;
646   new_stream->user_data = user_data;
647   new_stream->end_granule = enc->write_granule;
648   enc->last_stream->next = new_stream;
649   enc->last_stream = new_stream;
650   return OPE_OK;
651 }
652
653 int ope_encoder_flush_header(OggOpusEnc *enc) {
654   if (enc->unrecoverable) return OPE_UNRECOVERABLE;
655   if (enc->last_stream->header_is_frozen) return OPE_TOO_LATE;
656   if (enc->last_stream->stream_is_init) return OPE_TOO_LATE;
657   else init_stream(enc);
658   return OPE_OK;
659 }
660
661 /* Goes straight to the libopus ctl() functions. */
662 int ope_encoder_ctl(OggOpusEnc *enc, int request, ...) {
663   int ret;
664   int translate;
665   va_list ap;
666   if (enc->unrecoverable) return OPE_UNRECOVERABLE;
667   va_start(ap, request);
668   switch (request) {
669     case OPUS_SET_APPLICATION_REQUEST:
670     case OPUS_SET_BITRATE_REQUEST:
671     case OPUS_SET_MAX_BANDWIDTH_REQUEST:
672     case OPUS_SET_VBR_REQUEST:
673     case OPUS_SET_BANDWIDTH_REQUEST:
674     case OPUS_SET_COMPLEXITY_REQUEST:
675     case OPUS_SET_INBAND_FEC_REQUEST:
676     case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
677     case OPUS_SET_DTX_REQUEST:
678     case OPUS_SET_VBR_CONSTRAINT_REQUEST:
679     case OPUS_SET_FORCE_CHANNELS_REQUEST:
680     case OPUS_SET_SIGNAL_REQUEST:
681     case OPUS_SET_LSB_DEPTH_REQUEST:
682     case OPUS_SET_PREDICTION_DISABLED_REQUEST:
683 #ifdef OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST
684     case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST:
685 #endif
686     {
687       opus_int32 value = va_arg(ap, opus_int32);
688       ret = opus_multistream_encoder_ctl(enc->st, request, value);
689     }
690     break;
691     case OPUS_GET_LOOKAHEAD_REQUEST:
692     {
693       opus_int32 *value = va_arg(ap, opus_int32*);
694       ret = opus_multistream_encoder_ctl(enc->st, request, value);
695     }
696     break;
697     case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST:
698     {
699       opus_int32 value = va_arg(ap, opus_int32);
700       int max_supported = OPUS_FRAMESIZE_60_MS;
701 #ifdef OPUS_FRAMESIZE_120_MS
702       max_supported = OPUS_FRAMESIZE_120_MS;
703 #endif
704       if (value < OPUS_FRAMESIZE_2_5_MS || value > max_supported) {
705         ret = OPUS_UNIMPLEMENTED;
706         break;
707       }
708       ret = opus_multistream_encoder_ctl(enc->st, request, value);
709       if (ret == OPUS_OK) {
710         if (value <= OPUS_FRAMESIZE_40_MS)
711           enc->frame_size = 120<<(value-OPUS_FRAMESIZE_2_5_MS);
712         else
713           enc->frame_size = (value-OPUS_FRAMESIZE_2_5_MS-2)*960;
714       }
715     }
716     break;
717     case OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST:
718     {
719       opus_int32 stream_id;
720       OpusEncoder **value;
721       stream_id = va_arg(ap, opus_int32);
722       value = va_arg(ap, OpusEncoder**);
723       ret = opus_multistream_encoder_ctl(enc->st, request, stream_id, value);
724     }
725     break;
726
727     /* ****************** libopusenc-specific requests. ********************** */
728     case OPE_SET_DECISION_DELAY_REQUEST:
729     {
730       opus_int32 value = va_arg(ap, opus_int32);
731       if (value < 0) {
732         ret = OPE_BAD_ARG;
733         break;
734       }
735       enc->decision_delay = value;
736       ret = OPE_OK;
737     }
738     break;
739     case OPE_SET_MUXING_DELAY_REQUEST:
740     {
741       opus_int32 value = va_arg(ap, opus_int32);
742       if (value < 0) {
743         ret = OPE_BAD_ARG;
744         break;
745       }
746       enc->max_ogg_delay = value;
747       oggp_set_muxing_delay(enc->oggp, enc->max_ogg_delay);
748       ret = OPE_OK;
749     }
750     break;
751     case OPE_SET_COMMENT_PADDING_REQUEST:
752     {
753       opus_int32 value = va_arg(ap, opus_int32);
754       if (value < 0) {
755         ret = OPE_BAD_ARG;
756         break;
757       }
758       enc->comment_padding = value;
759       ret = OPE_OK;
760     }
761     break;
762     case OPE_SET_SERIALNO_REQUEST:
763     {
764       opus_int32 value = va_arg(ap, opus_int32);
765       if (enc->last_stream->header_is_frozen) return OPE_TOO_LATE;
766       enc->last_stream->serialno = value;
767       enc->last_stream->serialno_is_set = 1;
768       ret = OPE_OK;
769     }
770     break;
771     case OPE_SET_PACKET_CALLBACK_REQUEST:
772     {
773       ope_packet_func value = va_arg(ap, ope_packet_func);
774       void *data = va_arg(ap, void *);
775       enc->packet_callback = value;
776       enc->packet_callback_data = data;
777       ret = OPE_OK;
778     }
779     break;
780     default:
781       return OPE_UNIMPLEMENTED;
782   }
783   va_end(ap);
784   translate = ret != 0 && (request < 14000 || (ret < 0 && ret >= -10));
785   if (translate) {
786     if (ret == OPUS_BAD_ARG) ret = OPE_BAD_ARG;
787     else if (ret == OPUS_INTERNAL_ERROR) ret = OPE_INTERNAL_ERROR;
788     else if (ret == OPUS_UNIMPLEMENTED) ret = OPE_UNIMPLEMENTED;
789     else if (ret == OPUS_ALLOC_FAIL) ret = OPE_ALLOC_FAIL;
790     else ret = OPE_INTERNAL_ERROR;
791   }
792   assert(ret == 0 || ret < -10);
793   return ret;
794 }
795
796 const char *ope_get_version_string(void)
797 {
798   return "libopusenc " PACKAGE_VERSION;
799 }
800
801 int ope_get_abi_version(void) {
802   return OPE_ABI_VERSION;
803 }
804
805 static void vorbis_lpc_from_data(float *data, float *lpci, int n, int stride);
806
807 static void extend_signal(float *x, int before, int after, int channels) {
808   int c;
809   int i;
810   float window[LPC_PADDING];
811   if (after==0) return;
812   before = MIN(before, LPC_INPUT);
813   if (before < 4*LPC_ORDER) {
814     int i;
815     for (i=0;i<after*channels;i++) x[i] = 0;
816     return;
817   }
818   {
819     /* Generate Window using a resonating IIR aka Goertzel's algorithm. */
820     float m0=1, m1=.5*LPC_GOERTZEL_CONST;
821     float a1 = LPC_GOERTZEL_CONST;
822     window[0] = 1;
823     for (i=1;i<LPC_PADDING;i++) {
824       window[i] = a1*m0 - m1;
825       m1 = m0;
826       m0 = window[i];
827     }
828     for (i=0;i<LPC_PADDING;i++) window[i] = .5+.5*window[i];
829   }
830   for (c=0;c<channels;c++) {
831     float lpc[LPC_ORDER];
832     vorbis_lpc_from_data(x-channels*before+c, lpc, before, channels);
833     for (i=0;i<after;i++) {
834       float sum;
835       int j;
836       sum = 0;
837       for (j=0;j<LPC_ORDER;j++) sum -= x[(i-j-1)*channels + c]*lpc[j];
838       x[i*channels + c] = sum;
839     }
840     for (i=0;i<after;i++) x[i*channels + c] *= window[i];
841   }
842 }
843
844 /* Some of these routines (autocorrelator, LPC coefficient estimator)
845    are derived from code written by Jutta Degener and Carsten Bormann;
846    thus we include their copyright below.  The entirety of this file
847    is freely redistributable on the condition that both of these
848    copyright notices are preserved without modification.  */
849
850 /* Preserved Copyright: *********************************************/
851
852 /* Copyright 1992, 1993, 1994 by Jutta Degener and Carsten Bormann,
853 Technische Universita"t Berlin
854
855 Any use of this software is permitted provided that this notice is not
856 removed and that neither the authors nor the Technische Universita"t
857 Berlin are deemed to have made any representations as to the
858 suitability of this software for any purpose nor are held responsible
859 for any defects of this software. THERE IS ABSOLUTELY NO WARRANTY FOR
860 THIS SOFTWARE.
861
862 As a matter of courtesy, the authors request to be informed about uses
863 this software has found, about bugs in this software, and about any
864 improvements that may be of general interest.
865
866 Berlin, 28.11.1994
867 Jutta Degener
868 Carsten Bormann
869
870 *********************************************************************/
871
872 static void vorbis_lpc_from_data(float *data, float *lpci, int n, int stride) {
873   double aut[LPC_ORDER+1];
874   double lpc[LPC_ORDER];
875   double error;
876   double epsilon;
877   int i,j;
878
879   /* FIXME: Apply a window to the input. */
880   /* autocorrelation, p+1 lag coefficients */
881   j=LPC_ORDER+1;
882   while(j--){
883     double d=0; /* double needed for accumulator depth */
884     for(i=j;i<n;i++)d+=(double)data[i*stride]*data[(i-j)*stride];
885     aut[j]=d;
886   }
887
888   /* Apply lag windowing (better than bandwidth expansion) */
889   if (LPC_ORDER <= 64) {
890     for (i=1;i<=LPC_ORDER;i++) {
891       /* Approximate this gaussian for low enough order. */
892       /* aut[i] *= exp(-.5*(2*M_PI*.002*i)*(2*M_PI*.002*i));*/
893       aut[i] -= aut[i]*(0.008f*0.008f)*i*i;
894     }
895   }
896   /* Generate lpc coefficients from autocorr values */
897
898   /* set our noise floor to about -100dB */
899   error=aut[0] * (1. + 1e-7);
900   epsilon=1e-6*aut[0]+1e-7;
901
902   for(i=0;i<LPC_ORDER;i++){
903     double r= -aut[i+1];
904
905     if(error<epsilon){
906       memset(lpc+i,0,(LPC_ORDER-i)*sizeof(*lpc));
907       goto done;
908     }
909
910     /* Sum up this iteration's reflection coefficient; note that in
911        Vorbis we don't save it.  If anyone wants to recycle this code
912        and needs reflection coefficients, save the results of 'r' from
913        each iteration. */
914
915     for(j=0;j<i;j++)r-=lpc[j]*aut[i-j];
916     r/=error;
917
918     /* Update LPC coefficients and total error */
919
920     lpc[i]=r;
921     for(j=0;j<i/2;j++){
922       double tmp=lpc[j];
923
924       lpc[j]+=r*lpc[i-1-j];
925       lpc[i-1-j]+=r*tmp;
926     }
927     if(i&1)lpc[j]+=lpc[j]*r;
928
929     error*=1.-r*r;
930
931   }
932
933  done:
934
935   /* slightly damp the filter */
936   {
937     double g = .999;
938     double damp = g;
939     for(j=0;j<LPC_ORDER;j++){
940       lpc[j]*=damp;
941       damp*=g;
942     }
943   }
944
945   for(j=0;j<LPC_ORDER;j++)lpci[j]=(float)lpc[j];
946 }
947