Better handling of test_opus bandwidth options
[opus.git] / src / opus_encoder.c
1 /* Copyright (c) 2010 Xiph.Org Foundation, Skype Limited
2    Written by Jean-Marc Valin and Koen Vos */
3 /*
4    Redistribution and use in source and binary forms, with or without
5    modification, are permitted provided that the following conditions
6    are met:
7
8    - Redistributions of source code must retain the above copyright
9    notice, this list of conditions and the following disclaimer.
10
11    - Redistributions in binary form must reproduce the above copyright
12    notice, this list of conditions and the following disclaimer in the
13    documentation and/or other materials provided with the distribution.
14
15    - Neither the name of the Xiph.org Foundation nor the names of its
16    contributors may be used to endorse or promote products derived from
17    this software without specific prior written permission.
18
19    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
23    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
27    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
28    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #ifdef HAVE_CONFIG_H
33 #include "config.h"
34 #endif
35
36 #include <stdlib.h>
37 #include <stdio.h>
38 #include <stdarg.h>
39 #include "opus_encoder.h"
40 #include "entenc.h"
41 #include "modes.h"
42 #include "SKP_Silk_SDK_API.h"
43
44 OpusEncoder *opus_encoder_create(int Fs, int channels)
45 {
46     char *raw_state;
47         OpusEncoder *st;
48         int ret, silkEncSizeBytes, celtEncSizeBytes;
49
50     /* Create SILK encoder */
51     ret = SKP_Silk_SDK_Get_Encoder_Size( &silkEncSizeBytes );
52     if( ret ) {
53         /* Handle error */
54     }
55     celtEncSizeBytes = celt_encoder_get_size(channels);
56     raw_state = calloc(sizeof(OpusEncoder)+silkEncSizeBytes+celtEncSizeBytes, 1);
57     st = (OpusEncoder*)raw_state;
58     st->silk_enc = (void*)(raw_state+sizeof(OpusEncoder));
59     st->celt_enc = (CELTEncoder*)(raw_state+sizeof(OpusEncoder)+silkEncSizeBytes);
60     st->stream_channels = st->channels = channels;
61
62     st->Fs = Fs;
63
64     ret = SKP_Silk_SDK_InitEncoder( st->silk_enc, &st->silk_mode );
65     if( ret ) {
66         /* Handle error */
67     }
68
69     /* default SILK parameters */
70     st->silk_mode.API_sampleRate        = st->Fs;
71     st->silk_mode.maxInternalSampleRate = 16000;
72     st->silk_mode.minInternalSampleRate = 8000;
73     st->silk_mode.payloadSize_ms        = 20;
74     st->silk_mode.packetLossPercentage  = 0;
75     st->silk_mode.useInBandFEC          = 0;
76     st->silk_mode.useDTX                = 0;
77     st->silk_mode.complexity            = 2;
78
79     /* Create CELT encoder */
80         /* Initialize CELT encoder */
81         st->celt_enc = celt_encoder_init(st->celt_enc, Fs, channels, NULL);
82
83         st->mode = MODE_HYBRID;
84         st->bandwidth = BANDWIDTH_FULLBAND;
85         st->use_vbr = 0;
86         st->bitrate_bps = 32000;
87
88         return st;
89 }
90
91 int opus_encode(OpusEncoder *st, const short *pcm, int frame_size,
92                 unsigned char *data, int max_data_bytes)
93 {
94     int i;
95         int ret=0;
96         SKP_int32 nBytes;
97         ec_enc enc;
98         ec_byte_buffer buf;
99         int framerate, period;
100     int silk_internal_bandwidth;
101     int bytes_target;
102
103         bytes_target = st->bitrate_bps * frame_size / (st->Fs * 8) - 1;
104
105         data += 1;
106         ec_byte_writeinit_buffer(&buf, data, max_data_bytes-1);
107         ec_enc_init(&enc,&buf);
108
109         /* SILK processing */
110     if (st->mode != MODE_CELT_ONLY)
111     {
112         st->silk_mode.bitRate = st->bitrate_bps - 8*st->Fs/frame_size;
113         if( st->mode == MODE_HYBRID ) {
114             /* FIXME: Tune this offset */
115             st->silk_mode.bitRate = (st->silk_mode.bitRate + 12000) / 2;
116             /* FIXME: Adjust for 10 ms frames */
117         }
118
119         st->silk_mode.payloadSize_ms = 1000 * frame_size / st->Fs;
120         if (st->bandwidth == BANDWIDTH_NARROWBAND) {
121             st->silk_mode.maxInternalSampleRate = 8000;
122         } else if (st->bandwidth == BANDWIDTH_MEDIUMBAND) {
123             st->silk_mode.maxInternalSampleRate = 12000;
124         } else {
125             SKP_assert( st->mode == MODE_HYBRID || st->bandwidth == BANDWIDTH_WIDEBAND );
126             st->silk_mode.maxInternalSampleRate = 16000;
127         }
128         if( st->mode == MODE_HYBRID ) {
129             /* Don't allow bandwidth reduction at lowest bitrates in hybrid mode */
130             st->silk_mode.minInternalSampleRate = st->silk_mode.maxInternalSampleRate ;
131         }
132
133         /* Call SILK encoder for the low band */
134         nBytes = max_data_bytes-1;
135         ret = SKP_Silk_SDK_Encode( st->silk_enc, &st->silk_mode, pcm, frame_size, &enc, &nBytes );
136         if( ret ) {
137             fprintf (stderr, "SILK encode error: %d\n", ret);
138             /* Handle error */
139         }
140         /* Extract SILK internal bandwidth for signaling in first byte */
141         if( st->mode == MODE_SILK_ONLY ) {
142             if( st->silk_mode.internalSampleRate == 8000 ) {
143                 silk_internal_bandwidth = BANDWIDTH_NARROWBAND;
144             } else if( st->silk_mode.internalSampleRate == 12000 ) {
145                 silk_internal_bandwidth = BANDWIDTH_MEDIUMBAND;
146             } else if( st->silk_mode.internalSampleRate == 16000 ) {
147                 silk_internal_bandwidth = BANDWIDTH_WIDEBAND;
148             }
149         }
150     }
151
152     /* CELT processing */
153         if (st->mode != MODE_SILK_ONLY)
154         {
155                 int endband;
156             short pcm_buf[960*2];
157             int nb_compr_bytes;
158
159             switch(st->bandwidth)
160             {
161             case BANDWIDTH_NARROWBAND:
162                 endband = 13;
163                 break;
164             case BANDWIDTH_WIDEBAND:
165                 endband = 17;
166                 break;
167             case BANDWIDTH_SUPERWIDEBAND:
168                 endband = 19;
169                 break;
170             case BANDWIDTH_FULLBAND:
171                 endband = 21;
172                 break;
173             }
174             celt_encoder_ctl(st->celt_enc, CELT_SET_END_BAND(endband));
175             celt_encoder_ctl(st->celt_enc, CELT_SET_CHANNELS(st->stream_channels));
176
177         celt_encoder_ctl(st->celt_enc, CELT_SET_VBR(0));
178         celt_encoder_ctl(st->celt_enc, CELT_SET_BITRATE(510000));
179         if (st->mode == MODE_HYBRID)
180         {
181             int len;
182             celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(17));
183
184             len = (ec_enc_tell(&enc, 0)+7)>>3;
185             if( st->use_vbr ) {
186                 nb_compr_bytes = len + (st->bitrate_bps - 12000) * frame_size / (2 * 8 * st->Fs);
187             } else {
188                 /* check if SILK used up too much */
189                 nb_compr_bytes = len > bytes_target ? len : bytes_target;
190             }
191         } else {
192             celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(0));
193             if (st->use_vbr)
194             {
195                 celt_encoder_ctl(st->celt_enc, CELT_SET_VBR(1));
196                 celt_encoder_ctl(st->celt_enc, CELT_SET_BITRATE(st->bitrate_bps));
197                 nb_compr_bytes = max_data_bytes-1;
198             } else {
199                 nb_compr_bytes = bytes_target;
200             }
201         }
202
203             for (i=0;i<ENCODER_DELAY_COMPENSATION*st->channels;i++)
204                 pcm_buf[i] = st->delay_buffer[i];
205         for (;i<frame_size*st->channels;i++)
206             pcm_buf[i] = pcm[i-ENCODER_DELAY_COMPENSATION*st->channels];
207
208         ec_byte_shrink(&buf, nb_compr_bytes);
209
210             /* Encode high band with CELT */
211             ret = celt_encode_with_ec(st->celt_enc, pcm_buf, frame_size, NULL, nb_compr_bytes, &enc);
212             for (i=0;i<ENCODER_DELAY_COMPENSATION*st->channels;i++)
213                 st->delay_buffer[i] = pcm[frame_size*st->channels-ENCODER_DELAY_COMPENSATION*st->channels+i];
214         } else {
215             ret = (ec_enc_tell(&enc, 0)+7)>>3;
216             ec_enc_done(&enc);
217         }
218
219         /* Signalling the mode in the first byte */
220         data--;
221         framerate = st->Fs/frame_size;
222         period = 0;
223         while (framerate < 400)
224         {
225             framerate <<= 1;
226             period++;
227         }
228     if (st->mode == MODE_SILK_ONLY)
229     {
230         data[0] = (silk_internal_bandwidth-BANDWIDTH_NARROWBAND)<<5;
231         data[0] |= (period-2)<<3;
232     } else if (st->mode == MODE_CELT_ONLY)
233     {
234         int tmp = st->bandwidth-BANDWIDTH_MEDIUMBAND;
235         if (tmp < 0)
236             tmp = 0;
237         data[0] = 0x80;
238         data[0] |= tmp << 5;
239         data[0] |= period<<3;
240     } else /* Hybrid */
241     {
242         data[0] = 0x60;
243         data[0] |= (st->bandwidth-BANDWIDTH_SUPERWIDEBAND)<<4;
244         data[0] |= (period-2)<<3;
245     }
246     data[0] |= (st->stream_channels==2)<<2;
247     /*printf ("%x\n", (int)data[0]);*/
248
249     return ret+1;
250 }
251
252 void opus_encoder_ctl(OpusEncoder *st, int request, ...)
253 {
254     va_list ap;
255
256     va_start(ap, request);
257
258     switch (request)
259     {
260         case OPUS_SET_MODE_REQUEST:
261         {
262             int value = va_arg(ap, int);
263             st->mode = value;
264         }
265         break;
266         case OPUS_GET_MODE_REQUEST:
267         {
268             int *value = va_arg(ap, int*);
269             *value = st->mode;
270         }
271         break;
272         case OPUS_SET_BITRATE_REQUEST:
273         {
274             int value = va_arg(ap, int);
275             st->bitrate_bps = value;
276         }
277         break;
278         case OPUS_GET_BITRATE_REQUEST:
279         {
280             int *value = va_arg(ap, int*);
281             *value = st->bitrate_bps;
282         }
283         break;
284         case OPUS_SET_BANDWIDTH_REQUEST:
285         {
286             int value = va_arg(ap, int);
287             st->bandwidth = value;
288             if (st->bandwidth == BANDWIDTH_NARROWBAND) {
289                 st->silk_mode.maxInternalSampleRate = 8000;
290             } else if (st->bandwidth == BANDWIDTH_MEDIUMBAND) {
291                 st->silk_mode.maxInternalSampleRate = 12000;
292             } else {
293                 st->silk_mode.maxInternalSampleRate = 16000;
294             }
295         }
296         break;
297         case OPUS_GET_BANDWIDTH_REQUEST:
298         {
299             int *value = va_arg(ap, int*);
300             *value = st->bandwidth;
301         }
302         break;
303         case OPUS_SET_DTX_FLAG_REQUEST:
304         {
305             int value = va_arg(ap, int);
306             st->silk_mode.useDTX = value;
307         }
308         break;
309         case OPUS_GET_DTX_FLAG_REQUEST:
310         {
311             int *value = va_arg(ap, int*);
312             *value = st->silk_mode.useDTX;
313         }
314         break;
315         case OPUS_SET_COMPLEXITY_REQUEST:
316         {
317             int value = va_arg(ap, int);
318             st->silk_mode.complexity = value;
319         }
320         break;
321         case OPUS_GET_COMPLEXITY_REQUEST:
322         {
323             int *value = va_arg(ap, int*);
324             *value = st->silk_mode.complexity;
325         }
326         break;
327         case OPUS_SET_INBAND_FEC_FLAG_REQUEST:
328         {
329             int value = va_arg(ap, int);
330             st->silk_mode.useInBandFEC = value;
331         }
332         break;
333         case OPUS_GET_INBAND_FEC_FLAG_REQUEST:
334         {
335             int *value = va_arg(ap, int*);
336             *value = st->silk_mode.useInBandFEC;
337         }
338         break;
339         case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
340         {
341             int value = va_arg(ap, int);
342             st->silk_mode.packetLossPercentage = value;
343         }
344         break;
345         case OPUS_GET_PACKET_LOSS_PERC_REQUEST:
346         {
347             int *value = va_arg(ap, int*);
348             *value = st->silk_mode.packetLossPercentage;
349         }
350         break;
351         case OPUS_SET_VBR_FLAG_REQUEST:
352         {
353             int value = va_arg(ap, int);
354             st->use_vbr = value;
355             st->silk_mode.useCBR = 1-value;
356         }
357         break;
358         case OPUS_GET_VBR_FLAG_REQUEST:
359         {
360             int *value = va_arg(ap, int*);
361             *value = st->use_vbr;
362         }
363         break;
364         default:
365             fprintf(stderr, "unknown opus_encoder_ctl() request: %d", request);
366             break;
367     }
368
369     va_end(ap);
370 }
371
372 void opus_encoder_destroy(OpusEncoder *st)
373 {
374         free(st);
375 }
376