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