0b8a786635dd89e1d3b98be6aa553911296b1130
[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->buffer_start = enc->buffer_end = 0;
196   enc->st = st;
197   enc->callbacks = *callbacks;
198   enc->user_data = user_data;
199   if (error) *error = OPUS_OK;
200   return enc;
201 fail:
202   if (enc) {
203     free(enc);
204     if (enc->buffer) free(enc->buffer);
205   }
206   if (st) {
207     opus_multistream_encoder_destroy(st);
208   }
209   return NULL;
210 }
211
212 static void init_stream(OggOpusEnc *enc) {
213   time_t start_time;
214   int serialno;
215   assert(!enc->stream_is_init);
216   start_time = time(NULL);
217   srand(((getpid()&65535)<<15)^start_time);
218
219   serialno = rand();
220   if (ogg_stream_init(&enc->os, serialno) == -1) {
221     assert(0);
222     /* FIXME: How the hell do we handle that? */
223   }
224   /* FIXME: Compute preskip. */
225   enc->header.preskip = 0;
226   comment_pad(&enc->comment, &enc->comment_length, 512);
227
228   /*Write header*/
229   {
230     ogg_packet op;
231     /*The Identification Header is 19 bytes, plus a Channel Mapping Table for
232       mapping families other than 0. The Channel Mapping Table is 2 bytes +
233       1 byte per channel. Because the maximum number of channels is 255, the
234       maximum size of this header is 19 + 2 + 255 = 276 bytes.*/
235     unsigned char header_data[276];
236     int packet_size = opus_header_to_packet(&enc->header, header_data, sizeof(header_data));
237     op.packet=header_data;
238     op.bytes=packet_size;
239     op.b_o_s=1;
240     op.e_o_s=0;
241     op.granulepos=0;
242     op.packetno=0;
243     ogg_stream_packetin(&enc->os, &op);
244     oe_flush_page(enc);
245
246     op.packet = (unsigned char *)enc->comment;
247     op.bytes = enc->comment_length;
248     op.b_o_s = 0;
249     op.e_o_s = 0;
250     op.granulepos = 0;
251     op.packetno = 1;
252     ogg_stream_packetin(&enc->os, &op);
253     oe_flush_page(enc);
254   }
255   enc->stream_is_init = 1;
256   enc->packetno = 2;
257 }
258
259 static void encode_buffer(OggOpusEnc *enc) {
260   while (enc->buffer_end-enc->buffer_start > enc->frame_size + enc->decision_delay) {
261     ogg_packet op;
262     ogg_page og;
263     int nbBytes;
264     unsigned char packet[MAX_PACKET_SIZE];
265     nbBytes = opus_multistream_encode_float(enc->st, &enc->buffer[enc->channels*enc->buffer_start],
266         enc->buffer_end-enc->buffer_start, packet, MAX_PACKET_SIZE);
267     /* FIXME: How do we handle failure here. */
268     assert(nbBytes > 0);
269     enc->curr_granule += enc->frame_size;
270     op.packet=packet;
271     op.bytes=nbBytes;
272     op.b_o_s=0;
273     op.e_o_s=0;
274     op.packetno=enc->packetno++;
275     op.granulepos=enc->curr_granule;
276     ogg_stream_packetin(&enc->os, &op);
277     /* FIXME: Use flush to enforce latency constraint. */
278     while (ogg_stream_pageout_fill(&enc->os, &og, 255*255)) {
279       int ret = oe_write_page(&og, &enc->callbacks, enc->user_data);
280       /* FIXME: what do we do if this fails? */
281       assert(ret != -1);
282     }
283     enc->buffer_start += enc->frame_size;
284   }
285   /* If we've reached the end of the buffer, move everything back to the front. */
286   if (enc->buffer_end == BUFFER_SAMPLES) {
287     memmove(enc->buffer, &enc->buffer[enc->channels*enc->buffer_start], enc->channels*(enc->buffer_end-enc->buffer_start)*sizeof(*enc->buffer));
288     enc->buffer_end -= enc->buffer_start;
289     enc->buffer_start = 0;
290   }
291   /* This function must never leave the buffer full. */
292   assert(enc->buffer_end < BUFFER_SAMPLES);
293 }
294
295 /* Add/encode any number of float samples to the file. */
296 int ope_write_float(OggOpusEnc *enc, const float *pcm, int samples_per_channel) {
297   int channels = enc->channels;
298   if (!enc->stream_is_init) init_stream(enc);
299   /* FIXME: Add resampling support. */
300   do {
301     int i;
302     int curr;
303     int space_left = BUFFER_SAMPLES-enc->buffer_end;
304     curr = MIN(samples_per_channel, space_left);
305     for (i=0;i<channels*curr;i++) {
306       enc->buffer[channels*enc->buffer_end+i] = pcm[i];
307     }
308     enc->buffer_end += curr;
309     pcm += curr*channels;
310     samples_per_channel -= curr;
311     encode_buffer(enc);
312   } while (samples_per_channel > 0);
313   return OPE_OK;
314 }
315
316 /* Add/encode any number of int16 samples to the file. */
317 int ope_write(OggOpusEnc *enc, const opus_int16 *pcm, int samples_per_channel) {
318   int channels = enc->channels;
319   if (!enc->stream_is_init) init_stream(enc);
320   /* FIXME: Add resampling support. */
321   do {
322     int i;
323     int curr;
324     int space_left = BUFFER_SAMPLES-enc->buffer_end;
325     curr = MIN(samples_per_channel, space_left);
326     for (i=0;i<channels*curr;i++) {
327       enc->buffer[channels*enc->buffer_end+i] = (1.f/32768)*pcm[i];
328     }
329     enc->buffer_end += curr;
330     pcm += curr*channels;
331     samples_per_channel -= curr;
332     encode_buffer(enc);
333   } while (samples_per_channel > 0);
334   return OPE_OK;
335 }
336
337 static void finalize_stream(OggOpusEnc *enc) {
338   if (!enc->stream_is_init) init_stream(enc);
339 }
340
341 /* Close/finalize the stream. */
342 int ope_close_and_free(OggOpusEnc *enc) {
343   finalize_stream(enc);
344   free(enc->buffer);
345   opus_multistream_encoder_destroy(enc->st);
346   if (enc->os_allocated) ogg_stream_clear(&enc->os);
347   return OPE_OK;
348 }
349
350 /* Ends the stream and create a new stream within the same file. */
351 int ope_chain_current(OggOpusEnc *enc) {
352   (void)enc;
353   return OPE_UNIMPLEMENTED;
354 }
355
356 /* Ends the stream and create a new file. */
357 int ope_continue_new_file(OggOpusEnc *enc, const char *path) {
358   (void)enc;
359   (void)path;
360   return OPE_UNIMPLEMENTED;
361 }
362
363 /* Ends the stream and create a new file (callback-based). */
364 int ope_continue_new_callbacks(OggOpusEnc *enc, void *user_data) {
365   (void)enc;
366   (void)user_data;
367   return OPE_UNIMPLEMENTED;
368 }
369
370 /* Add a comment to the file (can only be called before encoding samples). */
371 int ope_add_comment(OggOpusEnc *enc, const char *tag, const char *val) {
372   if (comment_add(&enc->comment, &enc->comment_length, tag, val)) return OPE_INTERNAL_ERROR;
373   return OPE_OK;
374 }
375
376 /* Sets the Opus comment vendor string (optional, defaults to library info). */
377 int ope_set_vendor_string(OggOpusEnc *enc, const char *vendor) {
378   (void)enc;
379   (void)vendor;
380   return OPE_UNIMPLEMENTED;
381 }
382
383 /* Goes straight to the libopus ctl() functions. */
384 int ope_encoder_ctl(OggOpusEnc *enc, int request, ...) {
385   (void)enc;
386   (void)request;
387   return OPE_UNIMPLEMENTED;
388 }
389
390 /* ctl()-type call for the OggOpus layer. */
391 int ope_set_params(OggOpusEnc *enc, int request, ...) {
392   (void)enc;
393   (void)request;
394   return OPE_UNIMPLEMENTED;
395 }