opus.c (11274B)
1 /* Copyright (c) 2011 Xiph.Org Foundation, Skype Limited 2 Copyright (c) 2024 Arm Limited 3 Written by Jean-Marc Valin and Koen Vos */ 4 /* 5 Redistribution and use in source and binary forms, with or without 6 modification, are permitted provided that the following conditions 7 are met: 8 9 - Redistributions of source code must retain the above copyright 10 notice, this list of conditions and the following disclaimer. 11 12 - Redistributions in binary form must reproduce the above copyright 13 notice, this list of conditions and the following disclaimer in the 14 documentation and/or other materials provided with the distribution. 15 16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 20 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 23 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 24 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 25 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #ifdef HAVE_CONFIG_H 30 #include "config.h" 31 #endif 32 33 #include "opus.h" 34 #include "mathops.h" 35 #include "opus_private.h" 36 37 #ifndef DISABLE_FLOAT_API 38 39 void opus_pcm_soft_clip_impl(float *_x, int N, int C, float *declip_mem, int arch) 40 { 41 int c; 42 int i; 43 float *x; 44 int all_within_neg1pos1; 45 46 if (C<1 || N<1 || !_x || !declip_mem) return; 47 48 /* Clamp everything within the range [-2, +2] which is the domain of the soft 49 clipping non-linearity. Outside the defined range the derivative will be zero, 50 therefore there is no discontinuity introduced here. The implementation 51 might provide a hint if all input samples are within the [-1, +1] range. 52 53 `opus_limit2_checkwithin1()`: 54 - Clamps all samples within the valid range [-2, +2]. 55 - Generic C implementation: 56 * Does not attempt early detection whether samples are within hinted range. 57 * Always returns 0. 58 - Architecture specific implementation: 59 * Uses SIMD instructions to efficiently detect if all samples are 60 within the hinted range [-1, +1]. 61 * Returns 1 if no samples exceed the hinted range, 0 otherwise. 62 63 `all_within_neg1pos1`: 64 - Optimization hint to skip per-sample out-of-bound checks. 65 If true, the check can be skipped. */ 66 all_within_neg1pos1 = opus_limit2_checkwithin1(_x, N*C, arch); 67 68 for (c=0;c<C;c++) 69 { 70 float a; 71 float x0; 72 int curr; 73 74 x = _x+c; 75 a = declip_mem[c]; 76 /* Continue applying the non-linearity from the previous frame to avoid 77 any discontinuity. */ 78 for (i=0;i<N;i++) 79 { 80 if (x[i*C]*a>=0) 81 break; 82 x[i*C] = x[i*C]+a*x[i*C]*x[i*C]; 83 } 84 85 curr=0; 86 x0 = x[0]; 87 while(1) 88 { 89 int start, end; 90 float maxval; 91 int special=0; 92 int peak_pos; 93 /* Detection for early exit can be skipped if hinted by `all_within_neg1pos1` */ 94 if (all_within_neg1pos1) 95 { 96 i = N; 97 } else { 98 for (i=curr;i<N;i++) 99 { 100 if (x[i*C]>1 || x[i*C]<-1) 101 break; 102 } 103 } 104 if (i==N) 105 { 106 a=0; 107 break; 108 } 109 peak_pos = i; 110 start=end=i; 111 maxval=ABS16(x[i*C]); 112 /* Look for first zero crossing before clipping */ 113 while (start>0 && x[i*C]*x[(start-1)*C]>=0) 114 start--; 115 /* Look for first zero crossing after clipping */ 116 while (end<N && x[i*C]*x[end*C]>=0) 117 { 118 /* Look for other peaks until the next zero-crossing. */ 119 if (ABS16(x[end*C])>maxval) 120 { 121 maxval = ABS16(x[end*C]); 122 peak_pos = end; 123 } 124 end++; 125 } 126 /* Detect the special case where we clip before the first zero crossing */ 127 special = (start==0 && x[i*C]*x[0]>=0); 128 129 /* Compute a such that maxval + a*maxval^2 = 1 */ 130 a=(maxval-1)/(maxval*maxval); 131 /* Slightly boost "a" by 2^-22. This is just enough to ensure -ffast-math 132 does not cause output values larger than +/-1, but small enough not 133 to matter even for 24-bit output. */ 134 a += a*2.4e-7f; 135 if (x[i*C]>0) 136 a = -a; 137 /* Apply soft clipping */ 138 for (i=start;i<end;i++) 139 x[i*C] = x[i*C]+a*x[i*C]*x[i*C]; 140 141 if (special && peak_pos>=2) 142 { 143 /* Add a linear ramp from the first sample to the signal peak. 144 This avoids a discontinuity at the beginning of the frame. */ 145 float delta; 146 float offset = x0-x[0]; 147 delta = offset / peak_pos; 148 for (i=curr;i<peak_pos;i++) 149 { 150 offset -= delta; 151 x[i*C] += offset; 152 x[i*C] = MAX16(-1.f, MIN16(1.f, x[i*C])); 153 } 154 } 155 curr = end; 156 if (curr==N) 157 break; 158 } 159 declip_mem[c] = a; 160 } 161 } 162 163 OPUS_EXPORT void opus_pcm_soft_clip(float *_x, int N, int C, float *declip_mem) 164 { 165 opus_pcm_soft_clip_impl(_x, N, C, declip_mem, 0); 166 } 167 168 #endif 169 170 int encode_size(int size, unsigned char *data) 171 { 172 if (size < 252) 173 { 174 data[0] = size; 175 return 1; 176 } else { 177 data[0] = 252+(size&0x3); 178 data[1] = (size-(int)data[0])>>2; 179 return 2; 180 } 181 } 182 183 static int parse_size(const unsigned char *data, opus_int32 len, opus_int16 *size) 184 { 185 if (len<1) 186 { 187 *size = -1; 188 return -1; 189 } else if (data[0]<252) 190 { 191 *size = data[0]; 192 return 1; 193 } else if (len<2) 194 { 195 *size = -1; 196 return -1; 197 } else { 198 *size = 4*data[1] + data[0]; 199 return 2; 200 } 201 } 202 203 int opus_packet_get_samples_per_frame(const unsigned char *data, 204 opus_int32 Fs) 205 { 206 int audiosize; 207 if (data[0]&0x80) 208 { 209 audiosize = ((data[0]>>3)&0x3); 210 audiosize = (Fs<<audiosize)/400; 211 } else if ((data[0]&0x60) == 0x60) 212 { 213 audiosize = (data[0]&0x08) ? Fs/50 : Fs/100; 214 } else { 215 audiosize = ((data[0]>>3)&0x3); 216 if (audiosize == 3) 217 audiosize = Fs*60/1000; 218 else 219 audiosize = (Fs<<audiosize)/100; 220 } 221 return audiosize; 222 } 223 224 int opus_packet_parse_impl(const unsigned char *data, opus_int32 len, 225 int self_delimited, unsigned char *out_toc, 226 const unsigned char *frames[48], opus_int16 size[48], 227 int *payload_offset, opus_int32 *packet_offset, 228 const unsigned char **padding, opus_int32 *padding_len) 229 { 230 int i, bytes; 231 int count; 232 int cbr; 233 unsigned char ch, toc; 234 int framesize; 235 opus_int32 last_size; 236 opus_int32 pad = 0; 237 const unsigned char *data0 = data; 238 239 /* Make sure we return NULL/0 on error. */ 240 if (padding != NULL) 241 { 242 *padding = NULL; 243 *padding_len = 0; 244 } 245 246 if (size==NULL || len<0) 247 return OPUS_BAD_ARG; 248 if (len==0) 249 return OPUS_INVALID_PACKET; 250 251 framesize = opus_packet_get_samples_per_frame(data, 48000); 252 253 cbr = 0; 254 toc = *data++; 255 len--; 256 last_size = len; 257 switch (toc&0x3) 258 { 259 /* One frame */ 260 case 0: 261 count=1; 262 break; 263 /* Two CBR frames */ 264 case 1: 265 count=2; 266 cbr = 1; 267 if (!self_delimited) 268 { 269 if (len&0x1) 270 return OPUS_INVALID_PACKET; 271 last_size = len/2; 272 /* If last_size doesn't fit in size[0], we'll catch it later */ 273 size[0] = (opus_int16)last_size; 274 } 275 break; 276 /* Two VBR frames */ 277 case 2: 278 count = 2; 279 bytes = parse_size(data, len, size); 280 len -= bytes; 281 if (size[0]<0 || size[0] > len) 282 return OPUS_INVALID_PACKET; 283 data += bytes; 284 last_size = len-size[0]; 285 break; 286 /* Multiple CBR/VBR frames (from 0 to 120 ms) */ 287 default: /*case 3:*/ 288 if (len<1) 289 return OPUS_INVALID_PACKET; 290 /* Number of frames encoded in bits 0 to 5 */ 291 ch = *data++; 292 count = ch&0x3F; 293 if (count <= 0 || framesize*(opus_int32)count > 5760) 294 return OPUS_INVALID_PACKET; 295 len--; 296 /* Padding flag is bit 6 */ 297 if (ch&0x40) 298 { 299 int p; 300 do { 301 int tmp; 302 if (len<=0) 303 return OPUS_INVALID_PACKET; 304 p = *data++; 305 len--; 306 tmp = p==255 ? 254: p; 307 len -= tmp; 308 pad += tmp; 309 } while (p==255); 310 } 311 if (len<0) 312 return OPUS_INVALID_PACKET; 313 /* VBR flag is bit 7 */ 314 cbr = !(ch&0x80); 315 if (!cbr) 316 { 317 /* VBR case */ 318 last_size = len; 319 for (i=0;i<count-1;i++) 320 { 321 bytes = parse_size(data, len, size+i); 322 len -= bytes; 323 if (size[i]<0 || size[i] > len) 324 return OPUS_INVALID_PACKET; 325 data += bytes; 326 last_size -= bytes+size[i]; 327 } 328 if (last_size<0) 329 return OPUS_INVALID_PACKET; 330 } else if (!self_delimited) 331 { 332 /* CBR case */ 333 last_size = len/count; 334 if (last_size*count!=len) 335 return OPUS_INVALID_PACKET; 336 for (i=0;i<count-1;i++) 337 size[i] = (opus_int16)last_size; 338 } 339 break; 340 } 341 /* Self-delimited framing has an extra size for the last frame. */ 342 if (self_delimited) 343 { 344 bytes = parse_size(data, len, size+count-1); 345 len -= bytes; 346 if (size[count-1]<0 || size[count-1] > len) 347 return OPUS_INVALID_PACKET; 348 data += bytes; 349 /* For CBR packets, apply the size to all the frames. */ 350 if (cbr) 351 { 352 if (size[count-1]*count > len) 353 return OPUS_INVALID_PACKET; 354 for (i=0;i<count-1;i++) 355 size[i] = size[count-1]; 356 } else if (bytes+size[count-1] > last_size) 357 return OPUS_INVALID_PACKET; 358 } else 359 { 360 /* Because it's not encoded explicitly, it's possible the size of the 361 last packet (or all the packets, for the CBR case) is larger than 362 1275. Reject them here.*/ 363 if (last_size > 1275) 364 return OPUS_INVALID_PACKET; 365 size[count-1] = (opus_int16)last_size; 366 } 367 368 if (payload_offset) 369 *payload_offset = (int)(data-data0); 370 371 for (i=0;i<count;i++) 372 { 373 if (frames) 374 frames[i] = data; 375 data += size[i]; 376 } 377 378 if (padding != NULL) 379 { 380 *padding = data; 381 *padding_len = pad; 382 } 383 if (packet_offset) 384 *packet_offset = pad+(opus_int32)(data-data0); 385 386 if (out_toc) 387 *out_toc = toc; 388 389 return count; 390 } 391 392 int opus_packet_parse(const unsigned char *data, opus_int32 len, 393 unsigned char *out_toc, const unsigned char *frames[48], 394 opus_int16 size[48], int *payload_offset) 395 { 396 return opus_packet_parse_impl(data, len, 0, out_toc, 397 frames, size, payload_offset, NULL, NULL, NULL); 398 }