Updated to CELT's new API
[opus.git] / src / opus_decoder.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_decoder.h"
40 #include "entdec.h"
41 #include "modes.h"
42 #include "SKP_Silk_SDK_API.h"
43
44
45 OpusDecoder *opus_decoder_create(int Fs)
46 {
47     char *raw_state;
48         int ret, silkDecSizeBytes, celtDecSizeBytes;
49         OpusDecoder *st;
50
51         /* Initialize SILK encoder */
52     ret = SKP_Silk_SDK_Get_Decoder_Size( &silkDecSizeBytes );
53     if( ret ) {
54         /* Handle error */
55     }
56     celtDecSizeBytes = celt_decoder_get_size(1);
57     raw_state = calloc(sizeof(OpusDecoder)+silkDecSizeBytes+celtDecSizeBytes, 1);
58     st = (OpusDecoder*)raw_state;
59     st->silk_dec = (void*)(raw_state+sizeof(OpusDecoder));
60     st->celt_dec = (CELTDecoder*)(raw_state+sizeof(OpusDecoder)+silkDecSizeBytes);
61
62     st->Fs = Fs;
63
64     /* Reset decoder */
65     ret = SKP_Silk_SDK_InitDecoder( st->silk_dec );
66     if( ret ) {
67         /* Handle error */
68     }
69
70         /* Initialize CELT decoder */
71         st->celt_dec = celt_decoder_init(st->celt_dec, 48000, 1, NULL);
72
73         return st;
74
75 }
76 int opus_decode(OpusDecoder *st, const unsigned char *data,
77                 int len, short *pcm, int frame_size)
78 {
79         int i, silk_ret=0, celt_ret=0;
80         ec_dec dec;
81         ec_byte_buffer buf;
82     SKP_SILK_SDK_DecControlStruct DecControl;
83     SKP_int32 silk_frame_size;
84     short pcm_celt[960];
85     int audiosize;
86
87     if (data != NULL)
88     {
89         /* Decoding mode/bandwidth/framesize from first byte */
90         if (data[0]&0x80)
91         {
92             st->mode = MODE_CELT_ONLY;
93             st->bandwidth = BANDWIDTH_MEDIUMBAND + ((data[0]>>5)&0x3);
94             if (st->bandwidth == BANDWIDTH_MEDIUMBAND)
95                 st->bandwidth = BANDWIDTH_NARROWBAND;
96             audiosize = ((data[0]>>3)&0x3);
97             audiosize = (st->Fs<<audiosize)/400;
98         } else if ((data[0]&0x60) == 0x60)
99         {
100             st->mode = MODE_HYBRID;
101             st->bandwidth = (data[0]&0x10) ? BANDWIDTH_FULLBAND : BANDWIDTH_SUPERWIDEBAND;
102             audiosize = (data[0]&0x08) ? st->Fs/50 : st->Fs/100;
103         } else {
104
105             st->mode = MODE_SILK_ONLY;
106             st->bandwidth = BANDWIDTH_NARROWBAND + ((data[0]>>5)&0x3);
107             audiosize = ((data[0]>>3)&0x3);
108             if (audiosize == 3)
109                 audiosize = st->Fs*60/1000;
110             else
111                 audiosize = (st->Fs<<audiosize)/100;
112         }
113         /*printf ("%d %d %d\n", st->mode, st->bandwidth, audiosize);*/
114
115         len -= 1;
116         data += 1;
117         ec_byte_readinit(&buf,(unsigned char*)data,len);
118         ec_dec_init(&dec,&buf);
119     }
120
121     if (st->mode != MODE_CELT_ONLY)
122     {
123         DecControl.API_sampleRate = st->Fs;
124         DecControl.payloadSize_ms = 1000 * audiosize / st->Fs;
125         if( st->mode == MODE_SILK_ONLY ) {
126             if( st->bandwidth == BANDWIDTH_NARROWBAND ) {
127                 DecControl.internalSampleRate = 8000;
128             } else if( st->bandwidth == BANDWIDTH_MEDIUMBAND ) {
129                 DecControl.internalSampleRate = 12000;
130             } else if( st->bandwidth == BANDWIDTH_WIDEBAND ) {
131                 DecControl.internalSampleRate = 16000;
132             } else {
133                 SKP_assert( 0 );
134             }
135         } else {
136             /* Hybrid mode */
137             DecControl.internalSampleRate = 16000;
138         }
139
140         /* We Should eventually have to set the bandwidth here */
141
142         /* Call SILK encoder for the low band */
143         silk_ret = SKP_Silk_SDK_Decode( st->silk_dec, &DecControl, data == NULL, &dec, len, pcm, &silk_frame_size );
144         if (silk_ret)
145         {
146             fprintf (stderr, "SILK decode error\n");
147             /* Handle error */
148         }
149     } else {
150         for (i=0;i<frame_size;i++)
151             pcm[i] = 0;
152     }
153
154     if (st->mode == MODE_HYBRID)
155     {
156         /* This should be adjusted based on the SILK bandwidth */
157         celt_decoder_ctl(st->celt_dec, CELT_SET_START_BAND(17));
158     } else {
159         celt_decoder_ctl(st->celt_dec, CELT_SET_START_BAND(0));
160     }
161
162     if (st->mode != MODE_SILK_ONLY && st->bandwidth > BANDWIDTH_WIDEBAND)
163     {
164         int endband;
165
166             switch(st->bandwidth)
167             {
168             case BANDWIDTH_NARROWBAND:
169                 endband = 13;
170                 break;
171             case BANDWIDTH_WIDEBAND:
172                 endband = 17;
173                 break;
174             case BANDWIDTH_SUPERWIDEBAND:
175                 endband = 19;
176                 break;
177             case BANDWIDTH_FULLBAND:
178                 endband = 21;
179                 break;
180             }
181             celt_decoder_ctl(st->celt_dec, CELT_SET_END_BAND(endband));
182
183         /* Encode high band with CELT */
184         celt_ret = celt_decode_with_ec(st->celt_dec, data, len, pcm_celt, frame_size, &dec);
185         for (i=0;i<frame_size;i++)
186             pcm[i] += pcm_celt[i];
187     }
188         return celt_ret;
189
190 }
191
192 void opus_decoder_ctl(OpusDecoder *st, int request, ...)
193 {
194     va_list ap;
195
196     va_start(ap, request);
197
198     switch (request)
199     {
200         case OPUS_SET_MODE_REQUEST:
201         {
202             int value = va_arg(ap, int);
203             st->mode = value;
204         }
205         break;
206         case OPUS_GET_MODE_REQUEST:
207         {
208             int *value = va_arg(ap, int*);
209             *value = st->mode;
210         }
211         break;
212         case OPUS_SET_BANDWIDTH_REQUEST:
213         {
214             int value = va_arg(ap, int);
215             st->bandwidth = value;
216         }
217         break;
218         case OPUS_GET_BANDWIDTH_REQUEST:
219         {
220             int *value = va_arg(ap, int*);
221             *value = st->bandwidth;
222         }
223         break;
224         default:
225             fprintf(stderr, "unknown opus_decoder_ctl() request: %d", request);
226             break;
227     }
228
229     va_end(ap);
230 }
231
232 void opus_decoder_destroy(OpusDecoder *st)
233 {
234         free(st);
235 }