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