opus_encoder.c 14.3 KB
Newer Older
1
2
/* Copyright (c) 2010 Xiph.Org Foundation, Skype Limited
   Written by Jean-Marc Valin and Koen Vos */
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/*
   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions
   are met:

   - Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.

   - Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.

   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <stdlib.h>
33
#include <stdio.h>
34
#include <stdarg.h>
Jean-Marc Valin's avatar
Jean-Marc Valin committed
35
#include "opus_encoder.h"
Jean-Marc Valin's avatar
Jean-Marc Valin committed
36
37
#include "entenc.h"
#include "modes.h"
38
#include "SKP_Silk_SDK_API.h"
39

40
OpusEncoder *opus_encoder_create(int Fs, int channels)
41
{
42
    char *raw_state;
Jean-Marc Valin's avatar
Jean-Marc Valin committed
43
	OpusEncoder *st;
44
	int ret, silkEncSizeBytes, celtEncSizeBytes;
45

46
    /* Create SILK encoder */
47
    ret = SKP_Silk_SDK_Get_Encoder_Size( &silkEncSizeBytes );
48
49
50
    if( ret ) {
    	/* Handle error */
    }
Jean-Marc Valin's avatar
Jean-Marc Valin committed
51
    celtEncSizeBytes = celt_encoder_get_size(channels);
Jean-Marc Valin's avatar
Jean-Marc Valin committed
52
53
54
55
    raw_state = calloc(sizeof(OpusEncoder)+silkEncSizeBytes+celtEncSizeBytes, 1);
    st = (OpusEncoder*)raw_state;
    st->silk_enc = (void*)(raw_state+sizeof(OpusEncoder));
    st->celt_enc = (CELTEncoder*)(raw_state+sizeof(OpusEncoder)+silkEncSizeBytes);
56
    st->stream_channels = st->channels = channels;
57
58

    st->Fs = Fs;
59

60
    ret = SKP_Silk_SDK_InitEncoder( st->silk_enc, &st->silk_mode );
61
62
63
    if( ret ) {
        /* Handle error */
    }
64

65
66
67
68
69
70
71
72
    /* default SILK parameters */
    st->silk_mode.API_sampleRate        = st->Fs;
    st->silk_mode.maxInternalSampleRate = 16000;
    st->silk_mode.minInternalSampleRate = 8000;
    st->silk_mode.payloadSize_ms        = 20;
    st->silk_mode.packetLossPercentage  = 0;
    st->silk_mode.useInBandFEC          = 0;
    st->silk_mode.useDTX                = 0;
Koen Vos's avatar
Koen Vos committed
73
    st->silk_mode.complexity            = 10;
74

75
    /* Create CELT encoder */
76
	/* Initialize CELT encoder */
77
	st->celt_enc = celt_encoder_init(st->celt_enc, Fs, channels, NULL);
78

79
80
	st->mode = MODE_HYBRID;
	st->bandwidth = BANDWIDTH_FULLBAND;
81
82
	st->use_vbr = 0;
	st->bitrate_bps = 32000;
83

84
85
86
	return st;
}

Jean-Marc Valin's avatar
Jean-Marc Valin committed
87
int opus_encode(OpusEncoder *st, const short *pcm, int frame_size,
88
		unsigned char *data, int max_data_bytes)
89
{
90
    int i;
91
	int ret=0;
92
	SKP_int32 nBytes;
Jean-Marc Valin's avatar
Jean-Marc Valin committed
93
	ec_enc enc;
94
	int framerate, period;
95
96
    int silk_internal_bandwidth;
    int bytes_target;
97
    int prefill=0;
98
99
    int start_band;
    int redundancy = 0;
100
101

	bytes_target = st->bitrate_bps * frame_size / (st->Fs * 8) - 1;
Jean-Marc Valin's avatar
Jean-Marc Valin committed
102

103
	data += 1;
104
105
106
107
	if (st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY)
	{
		SKP_SILK_SDK_EncControlStruct dummy;
		SKP_Silk_SDK_InitEncoder( st->silk_enc, &dummy);
108
		prefill=1;
109
110
	}

111
	ec_enc_init(&enc, data, max_data_bytes-1);
Jean-Marc Valin's avatar
Jean-Marc Valin committed
112

113
	/* SILK processing */
114
115
    if (st->mode != MODE_CELT_ONLY)
    {
116
117
        st->silk_mode.bitRate = st->bitrate_bps - 8*st->Fs/frame_size;
        if( st->mode == MODE_HYBRID ) {
Karsten Vandborg Sorensen's avatar
Karsten Vandborg Sorensen committed
118
119
120
            if( st->bandwidth == BANDWIDTH_SUPERWIDEBAND ) {
                if( st->Fs == 100 * frame_size ) {
                    /* 24 kHz, 10 ms */
Koen Vos's avatar
Koen Vos committed
121
                    st->silk_mode.bitRate = ( ( st->silk_mode.bitRate + 2000 + st->use_vbr * 1000 ) * 2 ) / 3;
Karsten Vandborg Sorensen's avatar
Karsten Vandborg Sorensen committed
122
123
                } else {
                    /* 24 kHz, 20 ms */
Koen Vos's avatar
Koen Vos committed
124
                    st->silk_mode.bitRate = ( ( st->silk_mode.bitRate + 1000 + st->use_vbr * 1000 ) * 2 ) / 3;
Karsten Vandborg Sorensen's avatar
Karsten Vandborg Sorensen committed
125
126
127
128
                }
            } else {
                if( st->Fs == 100 * frame_size ) {
                    /* 48 kHz, 10 ms */
Koen Vos's avatar
Koen Vos committed
129
                    st->silk_mode.bitRate = ( st->silk_mode.bitRate + 8000 + st->use_vbr * 3000 ) / 2;
Karsten Vandborg Sorensen's avatar
Karsten Vandborg Sorensen committed
130
131
                } else {
                    /* 48 kHz, 20 ms */
Koen Vos's avatar
Koen Vos committed
132
                    st->silk_mode.bitRate = ( st->silk_mode.bitRate + 9000 + st->use_vbr * 1000 ) / 2;
Karsten Vandborg Sorensen's avatar
Karsten Vandborg Sorensen committed
133
134
                }
            }
135
136
137
138
            /* don't let SILK use more than 80% */
            if( st->silk_mode.bitRate > ( st->bitrate_bps - 8*st->Fs/frame_size ) * 4/5 ) {
                st->silk_mode.bitRate = ( st->bitrate_bps - 8*st->Fs/frame_size ) * 4/5;
            }
139
        }
140

141
142
143
144
145
146
147
148
149
150
151
        st->silk_mode.payloadSize_ms = 1000 * frame_size / st->Fs;
        if (st->bandwidth == BANDWIDTH_NARROWBAND) {
            st->silk_mode.maxInternalSampleRate = 8000;
        } else if (st->bandwidth == BANDWIDTH_MEDIUMBAND) {
            st->silk_mode.maxInternalSampleRate = 12000;
        } else {
            SKP_assert( st->mode == MODE_HYBRID || st->bandwidth == BANDWIDTH_WIDEBAND );
            st->silk_mode.maxInternalSampleRate = 16000;
        }
        if( st->mode == MODE_HYBRID ) {
            /* Don't allow bandwidth reduction at lowest bitrates in hybrid mode */
Koen Vos's avatar
Koen Vos committed
152
153
154
            st->silk_mode.minInternalSampleRate = 16000;
        } else {
            st->silk_mode.minInternalSampleRate = 8000;
155
        }
156

157
158
        /* Call SILK encoder for the low band */
        nBytes = max_data_bytes-1;
159
        if (prefill)
160
161
162
163
        {
            int zero=0;
        	SKP_Silk_SDK_Encode( st->silk_enc, &st->silk_mode, st->delay_buffer, ENCODER_BUFFER, NULL, &zero, 1 );
        }
164

Jean-Marc Valin's avatar
Jean-Marc Valin committed
165
        ret = SKP_Silk_SDK_Encode( st->silk_enc, &st->silk_mode, pcm, frame_size, &enc, &nBytes, 0 );
166
167
168
169
170
171
172
173
174
175
176
177
178
        if( ret ) {
            fprintf (stderr, "SILK encode error: %d\n", ret);
            /* Handle error */
        }
        /* Extract SILK internal bandwidth for signaling in first byte */
        if( st->mode == MODE_SILK_ONLY ) {
            if( st->silk_mode.internalSampleRate == 8000 ) {
                silk_internal_bandwidth = BANDWIDTH_NARROWBAND;
            } else if( st->silk_mode.internalSampleRate == 12000 ) {
                silk_internal_bandwidth = BANDWIDTH_MEDIUMBAND;
            } else if( st->silk_mode.internalSampleRate == 16000 ) {
                silk_internal_bandwidth = BANDWIDTH_WIDEBAND;
            }
179
180
        } else {
            SKP_assert( st->silk_mode.internalSampleRate == 16000 );
181
182
183
184
185
        }
    }

    /* CELT processing */
	if (st->mode != MODE_SILK_ONLY)
186
	{
Jean-Marc Valin's avatar
Jean-Marc Valin committed
187
		int endband;
Jean-Marc Valin's avatar
Jean-Marc Valin committed
188
	    short pcm_buf[960*2];
189
	    int nb_compr_bytes;
190

Jean-Marc Valin's avatar
Jean-Marc Valin committed
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
	    switch(st->bandwidth)
	    {
	    case BANDWIDTH_NARROWBAND:
	    	endband = 13;
	    	break;
	    case BANDWIDTH_WIDEBAND:
	    	endband = 17;
	    	break;
	    case BANDWIDTH_SUPERWIDEBAND:
	    	endband = 19;
	    	break;
	    case BANDWIDTH_FULLBAND:
	    	endband = 21;
	    	break;
	    }
	    celt_encoder_ctl(st->celt_enc, CELT_SET_END_BAND(endband));
207
	    celt_encoder_ctl(st->celt_enc, CELT_SET_CHANNELS(st->stream_channels));
208

Jean-Marc Valin's avatar
Jean-Marc Valin committed
209
210
        celt_encoder_ctl(st->celt_enc, CELT_SET_VBR(0));
        celt_encoder_ctl(st->celt_enc, CELT_SET_BITRATE(510000));
211
212
        if (st->prev_mode == MODE_SILK_ONLY)
        {
213
        	unsigned char dummy[2];
214
215
        	celt_encoder_ctl(st->celt_enc, CELT_RESET_STATE);
        	celt_encoder_ctl(st->celt_enc, CELT_SET_PREDICTION(0));
216
217
        	/* FIXME: This wastes CPU a bit compared to just prefilling the buffer */
        	celt_encode(st->celt_enc, &st->delay_buffer[(ENCODER_BUFFER-ENCODER_DELAY_COMPENSATION-120)*st->channels], 120, dummy, 10);
218
219
220
        } else {
        	celt_encoder_ctl(st->celt_enc, CELT_SET_PREDICTION(2));
        }
221
222
223
224
225
226
227
228
229
230
231

        start_band = 0;
        if (st->mode == MODE_HYBRID)
        {
            /* Check if we have a redundant 0-8 kHz band */
            ec_enc_bit_logp(&enc, redundancy, 12);
            if (!redundancy)
                start_band = 17;
        }
        celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(start_band));

232
233
234
235
236
        if (st->mode == MODE_HYBRID)
        {
            int len;
            celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(17));

237
            len = (ec_tell(&enc)+7)>>3;
238
            if( st->use_vbr ) {
Koen Vos's avatar
Koen Vos committed
239
                nb_compr_bytes = len + bytes_target - (st->silk_mode.bitRate * frame_size) / (8 * st->Fs);
240
241
242
243
244
245
            } else {
                /* check if SILK used up too much */
                nb_compr_bytes = len > bytes_target ? len : bytes_target;
            }
        } else {
            celt_encoder_ctl(st->celt_enc, CELT_SET_START_BAND(0));
Jean-Marc Valin's avatar
Jean-Marc Valin committed
246
247
248
249
250
251
252
253
            if (st->use_vbr)
            {
                celt_encoder_ctl(st->celt_enc, CELT_SET_VBR(1));
                celt_encoder_ctl(st->celt_enc, CELT_SET_BITRATE(st->bitrate_bps));
                nb_compr_bytes = max_data_bytes-1;
            } else {
                nb_compr_bytes = bytes_target;
            }
254
255
        }

256
        for (i=0;i<IMIN(frame_size, ENCODER_DELAY_COMPENSATION)*st->channels;i++)
257
            pcm_buf[i] = st->delay_buffer[(ENCODER_BUFFER-ENCODER_DELAY_COMPENSATION)*st->channels+i];
Jean-Marc Valin's avatar
Jean-Marc Valin committed
258
259
        for (;i<frame_size*st->channels;i++)
            pcm_buf[i] = pcm[i-ENCODER_DELAY_COMPENSATION*st->channels];
260

261
        ec_enc_shrink(&enc, nb_compr_bytes);
Jean-Marc Valin's avatar
Jean-Marc Valin committed
262

263
	    /* Encode high band with CELT */
264
	    ret = celt_encode_with_ec(st->celt_enc, pcm_buf, frame_size, NULL, nb_compr_bytes, &enc);
265

266
	    if (frame_size>ENCODER_BUFFER)
267
	    {
268
269
	        for (i=0;i<ENCODER_BUFFER*st->channels;i++)
	            st->delay_buffer[i] = pcm[(frame_size-ENCODER_BUFFER)*st->channels+i];
270
	    } else {
271
	        int tmp = ENCODER_BUFFER-frame_size;
272
273
274
275
276
	        for (i=0;i<tmp*st->channels;i++)
	            st->delay_buffer[i] = st->delay_buffer[i+frame_size*st->channels];
	        for (i=0;i<frame_size*st->channels;i++)
	            st->delay_buffer[tmp*st->channels+i] = pcm[i];
	    }
277
	} else {
278
	    ret = (ec_tell(&enc)+7)>>3;
279
280
281
	    ec_enc_done(&enc);
	}

282
283
284
285
286
287
288
289
290
291
292
	/* Signalling the mode in the first byte */
	data--;
	framerate = st->Fs/frame_size;
	period = 0;
	while (framerate < 400)
	{
	    framerate <<= 1;
	    period++;
	}
    if (st->mode == MODE_SILK_ONLY)
    {
293
        data[0] = (silk_internal_bandwidth-BANDWIDTH_NARROWBAND)<<5;
294
295
296
297
298
299
300
301
302
        data[0] |= (period-2)<<3;
    } else if (st->mode == MODE_CELT_ONLY)
    {
        int tmp = st->bandwidth-BANDWIDTH_MEDIUMBAND;
        if (tmp < 0)
            tmp = 0;
        data[0] = 0x80;
        data[0] |= tmp << 5;
        data[0] |= period<<3;
303
    } else /* Hybrid */
304
305
306
307
308
    {
        data[0] = 0x60;
        data[0] |= (st->bandwidth-BANDWIDTH_SUPERWIDEBAND)<<4;
        data[0] |= (period-2)<<3;
    }
309
    data[0] |= (st->stream_channels==2)<<2;
310
311
    /*printf ("%x\n", (int)data[0]);*/

Koen Vos's avatar
Koen Vos committed
312
313
314
#if OPUS_TEST_RANGE_CODER_STATE
    st->rangeFinal = enc.rng;
#endif
315
    st->prev_mode = st->mode;
316
    return ret+1;
317
}
318

Jean-Marc Valin's avatar
Jean-Marc Valin committed
319
void opus_encoder_ctl(OpusEncoder *st, int request, ...)
320
321
322
323
324
325
326
{
    va_list ap;

    va_start(ap, request);

    switch (request)
    {
Jean-Marc Valin's avatar
Jean-Marc Valin committed
327
        case OPUS_SET_MODE_REQUEST:
328
329
330
331
332
        {
            int value = va_arg(ap, int);
            st->mode = value;
        }
        break;
Jean-Marc Valin's avatar
Jean-Marc Valin committed
333
        case OPUS_GET_MODE_REQUEST:
334
335
336
337
338
        {
            int *value = va_arg(ap, int*);
            *value = st->mode;
        }
        break;
339
340
341
342
343
344
345
346
347
348
349
350
        case OPUS_SET_BITRATE_REQUEST:
        {
            int value = va_arg(ap, int);
            st->bitrate_bps = value;
        }
        break;
        case OPUS_GET_BITRATE_REQUEST:
        {
            int *value = va_arg(ap, int*);
            *value = st->bitrate_bps;
        }
        break;
Jean-Marc Valin's avatar
Jean-Marc Valin committed
351
        case OPUS_SET_BANDWIDTH_REQUEST:
352
353
354
        {
            int value = va_arg(ap, int);
            st->bandwidth = value;
355
356
357
358
359
360
361
            if (st->bandwidth == BANDWIDTH_NARROWBAND) {
                st->silk_mode.maxInternalSampleRate = 8000;
            } else if (st->bandwidth == BANDWIDTH_MEDIUMBAND) {
                st->silk_mode.maxInternalSampleRate = 12000;
            } else {
                st->silk_mode.maxInternalSampleRate = 16000;
            }
362
363
        }
        break;
Jean-Marc Valin's avatar
Jean-Marc Valin committed
364
        case OPUS_GET_BANDWIDTH_REQUEST:
365
366
367
368
369
        {
            int *value = va_arg(ap, int*);
            *value = st->bandwidth;
        }
        break;
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
        case OPUS_SET_DTX_FLAG_REQUEST:
        {
            int value = va_arg(ap, int);
            st->silk_mode.useDTX = value;
        }
        break;
        case OPUS_GET_DTX_FLAG_REQUEST:
        {
            int *value = va_arg(ap, int*);
            *value = st->silk_mode.useDTX;
        }
        break;
        case OPUS_SET_COMPLEXITY_REQUEST:
        {
            int value = va_arg(ap, int);
            st->silk_mode.complexity = value;
Jean-Marc Valin's avatar
Jean-Marc Valin committed
386
            celt_encoder_ctl(st->celt_enc, CELT_SET_COMPLEXITY(value));
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
        }
        break;
        case OPUS_GET_COMPLEXITY_REQUEST:
        {
            int *value = va_arg(ap, int*);
            *value = st->silk_mode.complexity;
        }
        break;
        case OPUS_SET_INBAND_FEC_FLAG_REQUEST:
        {
            int value = va_arg(ap, int);
            st->silk_mode.useInBandFEC = value;
        }
        break;
        case OPUS_GET_INBAND_FEC_FLAG_REQUEST:
        {
            int *value = va_arg(ap, int*);
            *value = st->silk_mode.useInBandFEC;
        }
        break;
        case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
        {
            int value = va_arg(ap, int);
            st->silk_mode.packetLossPercentage = value;
        }
        break;
        case OPUS_GET_PACKET_LOSS_PERC_REQUEST:
        {
            int *value = va_arg(ap, int*);
            *value = st->silk_mode.packetLossPercentage;
        }
        break;
        case OPUS_SET_VBR_FLAG_REQUEST:
420
421
        {
            int value = va_arg(ap, int);
422
423
            st->use_vbr = value;
            st->silk_mode.useCBR = 1-value;
424
425
        }
        break;
426
        case OPUS_GET_VBR_FLAG_REQUEST:
427
428
        {
            int *value = va_arg(ap, int*);
429
            *value = st->use_vbr;
430
431
432
        }
        break;
        default:
Jean-Marc Valin's avatar
Jean-Marc Valin committed
433
            fprintf(stderr, "unknown opus_encoder_ctl() request: %d", request);
434
            break;
435
    }
Alfred E. Heggestad's avatar
Alfred E. Heggestad committed
436
437

    va_end(ap);
438
439
}

Jean-Marc Valin's avatar
Jean-Marc Valin committed
440
void opus_encoder_destroy(OpusEncoder *st)
441
442
443
{
	free(st);
}
444

Koen Vos's avatar
Koen Vos committed
445
446
447
448
449
450
#if OPUS_TEST_RANGE_CODER_STATE
int opus_encoder_get_final_range(OpusEncoder *st)
{
    return st->rangeFinal;
}
#endif