oops
[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 <time.h>
35 #include <unistd.h>
36 #include <stdlib.h>
37 #include <stdio.h>
38 #include <string.h>
39 #include <assert.h>
40 #include <opus_multistream.h>
41 #include "opusenc.h"
42 #include "opus_header.h"
43
44 #define LPC_PADDING 120
45
46 /* Allow up to 2 seconds for delayed decision. */
47 #define MAX_LOOKAHEAD 96000
48 /* We can't have a circular buffer (because of delayed decision), so let's not copy too often. */
49 #define BUFFER_EXTRA 24000
50
51 #define BUFFER_SAMPLES (MAX_LOOKAHEAD + BUFFER_EXTRA)
52
53 #define MIN(a,b) ((a) < (b) ? (a) : (b))
54 #define MAX(a,b) ((a) > (b) ? (a) : (b))
55
56 #define MAX_PACKET_SIZE (1276*8)
57
58 static int oe_write_page(ogg_page *page, OpusEncCallbacks *cb, void *user_data)
59 {
60    int err;
61    err = cb->write(user_data, page->header, page->header_len);
62    if (err) return -1;
63    err = cb->write(user_data, page->body, page->body_len);
64    if (err) return -1;
65    return page->header_len+page->body_len;
66 }
67
68 struct StdioObject {
69   FILE *file;
70 };
71
72 struct OggOpusEnc {
73   OpusMSEncoder *st;
74   int channels;
75   float *buffer;
76   int buffer_start;
77   int buffer_end;
78   int frame_size;
79   int decision_delay;
80   ogg_int64_t curr_granule;
81   OpusEncCallbacks callbacks;
82   void *user_data;
83   OpusHeader header;
84   char *comment;
85   int comment_length;
86   int os_allocated;
87   ogg_stream_state os;
88   int stream_is_init;
89   int packetno;
90 };
91
92 static int oe_flush_page(OggOpusEnc *enc) {
93   ogg_page og;
94   int ret;
95   int written = 0;
96   while ( (ret = ogg_stream_flush(&enc->os, &og)) ) {
97     if (!ret) break;
98     ret = oe_write_page(&og, &enc->callbacks, enc->user_data);
99     if (ret == -1) {
100       return -1;
101     }
102     written += ret;
103   }
104   return written;
105 }
106
107 int stdio_write(void *user_data, const unsigned char *ptr, int len) {
108   struct StdioObject *obj = (struct StdioObject*)user_data;
109   return fwrite(ptr, 1, len, obj->file) != (size_t)len;
110 }
111
112 int stdio_close(void *user_data) {
113   struct StdioObject *obj = (struct StdioObject*)user_data;
114   int ret = fclose(obj->file);
115   free(obj);
116   return ret;
117 }
118
119 static const OpusEncCallbacks stdio_callbacks = {
120   stdio_write,
121   stdio_close
122 };
123
124 /* Create a new OggOpus file. */
125 OggOpusEnc *ope_create_file(const char *path, int rate, int channels, int family, int *error) {
126   OggOpusEnc *enc;
127   struct StdioObject *obj;
128   obj = malloc(sizeof(*obj));
129   enc = ope_create_callbacks(&stdio_callbacks, obj, rate, channels, family, error);
130   if (enc == NULL || (error && *error)) {
131     return NULL;
132   }
133   obj->file = fopen(path, "wb");
134   if (!obj->file) {
135     if (error) *error = OPE_CANNOT_OPEN;
136     /* FIXME: Destroy the encoder properly. */
137     free(obj);
138     return NULL;
139   }
140   return enc;
141 }
142
143 /* Create a new OggOpus file (callback-based). */
144 OggOpusEnc *ope_create_callbacks(const OpusEncCallbacks *callbacks, void *user_data,
145     int rate, int channels, int family, int *error) {
146   OpusMSEncoder *st=NULL;
147   OggOpusEnc *enc=NULL;
148   int ret;
149   if (family != 0 && family != 1 && family != 255) {
150     if (error) *error = OPE_UNIMPLEMENTED;
151     return NULL;
152   }
153   if (channels <= 0 || channels > 255) {
154     if (error) *error = OPE_BAD_ARG;
155     return NULL;
156   }
157   /* FIXME: Add resampling support. */
158   if (rate != 48000) {
159     if (error) *error = OPE_UNIMPLEMENTED;
160     return NULL;
161   }
162   if ( (enc = malloc(sizeof(*enc))) == NULL) goto fail;
163   enc->channels = channels;
164   enc->frame_size = 960;
165   enc->decision_delay = 96000;
166   enc->header.channels=channels;
167   enc->header.channel_mapping=family;
168   enc->header.input_sample_rate=rate;
169   enc->header.gain=0;
170   st=opus_multistream_surround_encoder_create(48000, channels, enc->header.channel_mapping,
171       &enc->header.nb_streams, &enc->header.nb_coupled,
172       enc->header.stream_map, OPUS_APPLICATION_AUDIO, &ret);
173   if (! (ret == OPUS_OK && st != NULL) ) {
174     goto fail;
175   }
176   opus_multistream_encoder_ctl(st, OPUS_SET_EXPERT_FRAME_DURATION(OPUS_FRAMESIZE_20_MS));
177   enc->os_allocated = 0;
178   enc->stream_is_init = 0;
179   enc->comment = NULL;
180   {
181     opus_int32 tmp;
182     int ret;
183     ret = opus_multistream_encoder_ctl(st, OPUS_GET_LOOKAHEAD(&tmp));
184     if (ret == OPUS_OK) enc->curr_granule = -tmp;
185     else enc->curr_granule = 0;
186   }
187   comment_init(&enc->comment, &enc->comment_length, opus_get_version_string());
188   {
189     char encoder_string[1024];
190     snprintf(encoder_string, sizeof(encoder_string), "%s version %s", PACKAGE_NAME, PACKAGE_VERSION);
191     comment_add(&enc->comment, &enc->comment_length, "ENCODER", encoder_string);
192   }
193   if (enc->comment == NULL) goto fail;
194   if ( (enc->buffer = malloc(sizeof(*enc->buffer)*BUFFER_SAMPLES*channels)) == NULL) goto fail;
195   enc->st = st;
196   enc->callbacks = *callbacks;
197   enc->user_data = user_data;
198   if (error) *error = OPUS_OK;
199   return enc;
200 fail:
201   if (enc) {
202     free(enc);
203     if (enc->buffer) free(enc->buffer);
204   }
205   if (st) {
206     opus_multistream_encoder_destroy(st);
207   }
208   return NULL;
209 }
210
211 static void init_stream(OggOpusEnc *enc) {
212   time_t start_time;
213   int serialno;
214   assert(!enc->stream_is_init);
215   start_time = time(NULL);
216   srand(((getpid()&65535)<<15)^start_time);
217
218   serialno = rand();
219   if (ogg_stream_init(&enc->os, serialno) == -1) {
220     assert(0);
221     /* FIXME: How the hell do we handle that? */
222   }
223   /* FIXME: Compute preskip. */
224   enc->header.preskip = 0;
225   comment_pad(&enc->comment, &enc->comment_length, 512);
226
227   /*Write header*/
228   {
229     ogg_packet op;
230     /*The Identification Header is 19 bytes, plus a Channel Mapping Table for
231       mapping families other than 0. The Channel Mapping Table is 2 bytes +
232       1 byte per channel. Because the maximum number of channels is 255, the
233       maximum size of this header is 19 + 2 + 255 = 276 bytes.*/
234     unsigned char header_data[276];
235     int packet_size = opus_header_to_packet(&enc->header, header_data, sizeof(header_data));
236     op.packet=header_data;
237     op.bytes=packet_size;
238     op.b_o_s=1;
239     op.e_o_s=0;
240     op.granulepos=0;
241     op.packetno=0;
242     ogg_stream_packetin(&enc->os, &op);
243     oe_flush_page(enc);
244
245     op.packet = (unsigned char *)enc->comment;
246     op.bytes = enc->comment_length;
247     op.b_o_s = 0;
248     op.e_o_s = 0;
249     op.granulepos = 0;
250     op.packetno = 1;
251     ogg_stream_packetin(&enc->os, &op);
252     oe_flush_page(enc);
253   }
254   enc->stream_is_init = 1;
255   enc->packetno = 2;
256 }
257
258 static void encode_buffer(OggOpusEnc *enc) {
259   while (enc->buffer_end-enc->buffer_start > enc->frame_size + enc->decision_delay) {
260     ogg_packet op;
261     ogg_page og;
262     int nbBytes;
263     unsigned char packet[MAX_PACKET_SIZE];
264     nbBytes = opus_multistream_encode_float(enc->st, &enc->buffer[enc->channels*enc->buffer_start],
265         enc->buffer_end-enc->buffer_start, packet, MAX_PACKET_SIZE);
266     /* FIXME: How do we handle failure here. */
267     assert(nbBytes > 0);
268     enc->curr_granule += enc->frame_size;
269     op.packet=packet;
270     op.bytes=nbBytes;
271     op.b_o_s=0;
272     op.e_o_s=0;
273     op.packetno=enc->packetno++;
274     op.granulepos=enc->curr_granule;
275     ogg_stream_packetin(&enc->os, &op);
276     /* FIXME: Use flush to enforce latency constraint. */
277     while (ogg_stream_pageout_fill(&enc->os, &og, 255*255)) {
278       int ret = oe_write_page(&og, &enc->callbacks, enc->user_data);
279       /* FIXME: what do we do if this fails? */
280       assert(ret != -1);
281     }
282     enc->buffer_start += enc->frame_size;
283   }
284   /* If we've reached the end of the buffer, move everything back to the front. */
285   if (enc->buffer_end == BUFFER_SAMPLES) {
286     memmove(enc->buffer, &enc->buffer[enc->channels*enc->buffer_start], enc->channels*(enc->buffer_end-enc->buffer_start));
287     enc->buffer_end -= enc->buffer_start;
288     enc->buffer_start = 0;
289   }
290   /* This function must never leave the buffer full. */
291   assert(enc->buffer_end < BUFFER_SAMPLES);
292 }
293
294 /* Add/encode any number of float samples to the file. */
295 int ope_write_float(OggOpusEnc *enc, float *pcm, int samples_per_channel) {
296   int channels = enc->channels;
297   if (!enc->stream_is_init) init_stream(enc);
298   /* FIXME: Add resampling support. */
299   do {
300     int i;
301     int curr;
302     int space_left = BUFFER_SAMPLES-enc->buffer_end;
303     curr = MIN(samples_per_channel, space_left);
304     for (i=0;i<channels*curr;i++) {
305       enc->buffer[channels*enc->buffer_end+i] = pcm[i];
306     }
307     enc->buffer_end += curr;
308     pcm += curr*channels;
309     samples_per_channel -= curr;
310     encode_buffer(enc);
311   } while (samples_per_channel > 0);
312   return OPE_OK;
313 }
314
315 /* Add/encode any number of int16 samples to the file. */
316 int ope_write(OggOpusEnc *enc, opus_int16 *pcm, int samples_per_channel) {
317   int channels = enc->channels;
318   if (!enc->stream_is_init) init_stream(enc);
319   /* FIXME: Add resampling support. */
320   do {
321     int i;
322     int curr;
323     int space_left = BUFFER_SAMPLES-enc->buffer_end;
324     curr = MIN(samples_per_channel, space_left);
325     for (i=0;i<channels*curr;i++) {
326       enc->buffer[channels*enc->buffer_end+i] = (1.f/32768)*pcm[i];
327     }
328     enc->buffer_end += curr;
329     pcm += curr*channels;
330     samples_per_channel -= curr;
331     encode_buffer(enc);
332   } while (samples_per_channel > 0);
333   return OPE_OK;
334 }
335
336 static void finalize_stream(OggOpusEnc *enc) {
337   if (!enc->stream_is_init) init_stream(enc);
338 }
339
340 /* Close/finalize the stream. */
341 int ope_close_and_free(OggOpusEnc *enc) {
342   finalize_stream(enc);
343   free(enc->buffer);
344   opus_multistream_encoder_destroy(enc->st);
345   if (enc->os_allocated) ogg_stream_clear(&enc->os);
346   return OPE_OK;
347 }
348
349 /* Ends the stream and create a new stream within the same file. */
350 int ope_chain_current(OggOpusEnc *enc) {
351   (void)enc;
352   return OPE_UNIMPLEMENTED;
353 }
354
355 /* Ends the stream and create a new file. */
356 int ope_continue_new_file(OggOpusEnc *enc, const char *path) {
357   (void)enc;
358   (void)path;
359   return OPE_UNIMPLEMENTED;
360 }
361
362 /* Ends the stream and create a new file (callback-based). */
363 int ope_continue_new_callbacks(OggOpusEnc *enc, void *user_data) {
364   (void)enc;
365   (void)user_data;
366   return OPE_UNIMPLEMENTED;
367 }
368
369 /* Add a comment to the file (can only be called before encoding samples). */
370 int ope_add_comment(OggOpusEnc *enc, char *tag, char *val) {
371   if (comment_add(&enc->comment, &enc->comment_length, tag, val)) return OPE_INTERNAL_ERROR;
372   return OPE_OK;
373 }
374
375 /* Sets the Opus comment vendor string (optional, defaults to library info). */
376 int ope_set_vendor_string(OggOpusEnc *enc, char *vendor) {
377   (void)enc;
378   (void)vendor;
379   return OPE_UNIMPLEMENTED;
380 }
381
382 /* Goes straight to the libopus ctl() functions. */
383 int ope_encoder_ctl(OggOpusEnc *enc, int request, ...) {
384   (void)enc;
385   (void)request;
386   return OPE_UNIMPLEMENTED;
387 }
388
389 /* ctl()-type call for the OggOpus layer. */
390 int ope_set_params(OggOpusEnc *enc, int request, ...) {
391   (void)enc;
392   (void)request;
393   return OPE_UNIMPLEMENTED;
394 }