blob: e9ce93b3084ae53b5675320886ab6280d9e2f6d3 [file] [log] [blame]
Vignesh Venkatasubramanian2bd8b542014-02-20 10:50:35 -08001/* Copyright (c) 2011 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 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "opus.h"
33#include "opus_private.h"
34
35#ifndef DISABLE_FLOAT_API
36OPUS_EXPORT void opus_pcm_soft_clip(float *_x, int N, int C, float *declip_mem)
37{
38 int c;
39 int i;
40 float *x;
41
42 if (C<1 || N<1 || !_x || !declip_mem) return;
43
44 /* First thing: saturate everything to +/- 2 which is the highest level our
45 non-linearity can handle. At the point where the signal reaches +/-2,
46 the derivative will be zero anyway, so this doesn't introduce any
47 discontinuity in the derivative. */
48 for (i=0;i<N*C;i++)
49 _x[i] = MAX16(-2.f, MIN16(2.f, _x[i]));
50 for (c=0;c<C;c++)
51 {
52 float a;
53 float x0;
54 int curr;
55
56 x = _x+c;
57 a = declip_mem[c];
58 /* Continue applying the non-linearity from the previous frame to avoid
59 any discontinuity. */
60 for (i=0;i<N;i++)
61 {
62 if (x[i*C]*a>=0)
63 break;
64 x[i*C] = x[i*C]+a*x[i*C]*x[i*C];
65 }
66
67 curr=0;
68 x0 = x[0];
69 while(1)
70 {
71 int start, end;
72 float maxval;
73 int special=0;
74 int peak_pos;
75 for (i=curr;i<N;i++)
76 {
77 if (x[i*C]>1 || x[i*C]<-1)
78 break;
79 }
80 if (i==N)
81 {
82 a=0;
83 break;
84 }
85 peak_pos = i;
86 start=end=i;
87 maxval=ABS16(x[i*C]);
88 /* Look for first zero crossing before clipping */
89 while (start>0 && x[i*C]*x[(start-1)*C]>=0)
90 start--;
91 /* Look for first zero crossing after clipping */
92 while (end<N && x[i*C]*x[end*C]>=0)
93 {
94 /* Look for other peaks until the next zero-crossing. */
95 if (ABS16(x[end*C])>maxval)
96 {
97 maxval = ABS16(x[end*C]);
98 peak_pos = end;
99 }
100 end++;
101 }
102 /* Detect the special case where we clip before the first zero crossing */
103 special = (start==0 && x[i*C]*x[0]>=0);
104
105 /* Compute a such that maxval + a*maxval^2 = 1 */
106 a=(maxval-1)/(maxval*maxval);
107 if (x[i*C]>0)
108 a = -a;
109 /* Apply soft clipping */
110 for (i=start;i<end;i++)
111 x[i*C] = x[i*C]+a*x[i*C]*x[i*C];
112
113 if (special && peak_pos>=2)
114 {
115 /* Add a linear ramp from the first sample to the signal peak.
116 This avoids a discontinuity at the beginning of the frame. */
117 float delta;
118 float offset = x0-x[0];
119 delta = offset / peak_pos;
120 for (i=curr;i<peak_pos;i++)
121 {
122 offset -= delta;
123 x[i*C] += offset;
124 x[i*C] = MAX16(-1.f, MIN16(1.f, x[i*C]));
125 }
126 }
127 curr = end;
128 if (curr==N)
129 break;
130 }
131 declip_mem[c] = a;
132 }
133}
134#endif
135
136int encode_size(int size, unsigned char *data)
137{
138 if (size < 252)
139 {
140 data[0] = size;
141 return 1;
142 } else {
143 data[0] = 252+(size&0x3);
144 data[1] = (size-(int)data[0])>>2;
145 return 2;
146 }
147}
148
149static int parse_size(const unsigned char *data, opus_int32 len, opus_int16 *size)
150{
151 if (len<1)
152 {
153 *size = -1;
154 return -1;
155 } else if (data[0]<252)
156 {
157 *size = data[0];
158 return 1;
159 } else if (len<2)
160 {
161 *size = -1;
162 return -1;
163 } else {
164 *size = 4*data[1] + data[0];
165 return 2;
166 }
167}
168
flimc91ee5b2016-01-26 14:33:44 +0100169int opus_packet_get_samples_per_frame(const unsigned char *data,
170 opus_int32 Fs)
171{
172 int audiosize;
173 if (data[0]&0x80)
174 {
175 audiosize = ((data[0]>>3)&0x3);
176 audiosize = (Fs<<audiosize)/400;
177 } else if ((data[0]&0x60) == 0x60)
178 {
179 audiosize = (data[0]&0x08) ? Fs/50 : Fs/100;
180 } else {
181 audiosize = ((data[0]>>3)&0x3);
182 if (audiosize == 3)
183 audiosize = Fs*60/1000;
184 else
185 audiosize = (Fs<<audiosize)/100;
186 }
187 return audiosize;
188}
189
Vignesh Venkatasubramanian2bd8b542014-02-20 10:50:35 -0800190int opus_packet_parse_impl(const unsigned char *data, opus_int32 len,
191 int self_delimited, unsigned char *out_toc,
192 const unsigned char *frames[48], opus_int16 size[48],
193 int *payload_offset, opus_int32 *packet_offset)
194{
195 int i, bytes;
196 int count;
197 int cbr;
198 unsigned char ch, toc;
199 int framesize;
200 opus_int32 last_size;
201 opus_int32 pad = 0;
202 const unsigned char *data0 = data;
203
204 if (size==NULL)
205 return OPUS_BAD_ARG;
206
207 framesize = opus_packet_get_samples_per_frame(data, 48000);
208
209 cbr = 0;
210 toc = *data++;
211 len--;
212 last_size = len;
213 switch (toc&0x3)
214 {
215 /* One frame */
216 case 0:
217 count=1;
218 break;
219 /* Two CBR frames */
220 case 1:
221 count=2;
222 cbr = 1;
223 if (!self_delimited)
224 {
225 if (len&0x1)
226 return OPUS_INVALID_PACKET;
227 last_size = len/2;
228 /* If last_size doesn't fit in size[0], we'll catch it later */
229 size[0] = (opus_int16)last_size;
230 }
231 break;
232 /* Two VBR frames */
233 case 2:
234 count = 2;
235 bytes = parse_size(data, len, size);
236 len -= bytes;
237 if (size[0]<0 || size[0] > len)
238 return OPUS_INVALID_PACKET;
239 data += bytes;
240 last_size = len-size[0];
241 break;
242 /* Multiple CBR/VBR frames (from 0 to 120 ms) */
243 default: /*case 3:*/
244 if (len<1)
245 return OPUS_INVALID_PACKET;
246 /* Number of frames encoded in bits 0 to 5 */
247 ch = *data++;
248 count = ch&0x3F;
249 if (count <= 0 || framesize*count > 5760)
250 return OPUS_INVALID_PACKET;
251 len--;
252 /* Padding flag is bit 6 */
253 if (ch&0x40)
254 {
255 int p;
256 do {
257 int tmp;
258 if (len<=0)
259 return OPUS_INVALID_PACKET;
260 p = *data++;
261 len--;
262 tmp = p==255 ? 254: p;
263 len -= tmp;
264 pad += tmp;
265 } while (p==255);
266 }
267 if (len<0)
268 return OPUS_INVALID_PACKET;
269 /* VBR flag is bit 7 */
270 cbr = !(ch&0x80);
271 if (!cbr)
272 {
273 /* VBR case */
274 last_size = len;
275 for (i=0;i<count-1;i++)
276 {
277 bytes = parse_size(data, len, size+i);
278 len -= bytes;
279 if (size[i]<0 || size[i] > len)
280 return OPUS_INVALID_PACKET;
281 data += bytes;
282 last_size -= bytes+size[i];
283 }
284 if (last_size<0)
285 return OPUS_INVALID_PACKET;
286 } else if (!self_delimited)
287 {
288 /* CBR case */
289 last_size = len/count;
290 if (last_size*count!=len)
291 return OPUS_INVALID_PACKET;
292 for (i=0;i<count-1;i++)
293 size[i] = (opus_int16)last_size;
294 }
295 break;
296 }
297 /* Self-delimited framing has an extra size for the last frame. */
298 if (self_delimited)
299 {
300 bytes = parse_size(data, len, size+count-1);
301 len -= bytes;
302 if (size[count-1]<0 || size[count-1] > len)
303 return OPUS_INVALID_PACKET;
304 data += bytes;
305 /* For CBR packets, apply the size to all the frames. */
306 if (cbr)
307 {
308 if (size[count-1]*count > len)
309 return OPUS_INVALID_PACKET;
310 for (i=0;i<count-1;i++)
311 size[i] = size[count-1];
312 } else if (bytes+size[count-1] > last_size)
313 return OPUS_INVALID_PACKET;
314 } else
315 {
316 /* Because it's not encoded explicitly, it's possible the size of the
317 last packet (or all the packets, for the CBR case) is larger than
318 1275. Reject them here.*/
319 if (last_size > 1275)
320 return OPUS_INVALID_PACKET;
321 size[count-1] = (opus_int16)last_size;
322 }
323
324 if (payload_offset)
325 *payload_offset = (int)(data-data0);
326
327 for (i=0;i<count;i++)
328 {
329 if (frames)
330 frames[i] = data;
331 data += size[i];
332 }
333
334 if (packet_offset)
335 *packet_offset = pad+(opus_int32)(data-data0);
336
337 if (out_toc)
338 *out_toc = toc;
339
340 return count;
341}
342
343int opus_packet_parse(const unsigned char *data, opus_int32 len,
344 unsigned char *out_toc, const unsigned char *frames[48],
345 opus_int16 size[48], int *payload_offset)
346{
347 return opus_packet_parse_impl(data, len, 0, out_toc,
348 frames, size, payload_offset, NULL);
349}
350