OLD | NEW |
1 /* Copyright (c) 2011 Xiph.Org Foundation, Skype Limited | 1 /* Copyright (c) 2011 Xiph.Org Foundation, Skype Limited |
2 Written by Jean-Marc Valin and Koen Vos */ | 2 Written by Jean-Marc Valin and Koen Vos */ |
3 /* | 3 /* |
4 Redistribution and use in source and binary forms, with or without | 4 Redistribution and use in source and binary forms, with or without |
5 modification, are permitted provided that the following conditions | 5 modification, are permitted provided that the following conditions |
6 are met: | 6 are met: |
7 | 7 |
8 - Redistributions of source code must retain the above copyright | 8 - Redistributions of source code must retain the above copyright |
9 notice, this list of conditions and the following disclaimer. | 9 notice, this list of conditions and the following disclaimer. |
10 | 10 |
(...skipping 14 matching lines...) Expand all Loading... |
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 */ | 26 */ |
27 | 27 |
28 #ifdef HAVE_CONFIG_H | 28 #ifdef HAVE_CONFIG_H |
29 #include "config.h" | 29 #include "config.h" |
30 #endif | 30 #endif |
31 | 31 |
32 #include "opus.h" | 32 #include "opus.h" |
33 #include "opus_private.h" | 33 #include "opus_private.h" |
34 | 34 |
| 35 #ifndef DISABLE_FLOAT_API |
| 36 OPUS_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 /* First thing: saturate everything to +/- 2 which is the highest level our |
| 43 non-linearity can handle. At the point where the signal reaches +/-2, |
| 44 the derivative will be zero anyway, so this doesn't introduce any |
| 45 discontinuity in the derivative. */ |
| 46 for (i=0;i<N*C;i++) |
| 47 _x[i] = MAX16(-2.f, MIN16(2.f, _x[i])); |
| 48 for (c=0;c<C;c++) |
| 49 { |
| 50 float a; |
| 51 float x0; |
| 52 int curr; |
| 53 |
| 54 x = _x+c; |
| 55 a = declip_mem[c]; |
| 56 /* Continue applying the non-linearity from the previous frame to avoid |
| 57 any discontinuity. */ |
| 58 for (i=0;i<N;i++) |
| 59 { |
| 60 if (x[i*C]*a>=0) |
| 61 break; |
| 62 x[i*C] = x[i*C]+a*x[i*C]*x[i*C]; |
| 63 } |
| 64 |
| 65 curr=0; |
| 66 x0 = x[0]; |
| 67 while(1) |
| 68 { |
| 69 int start, end; |
| 70 float maxval; |
| 71 int special=0; |
| 72 int peak_pos; |
| 73 for (i=curr;i<N;i++) |
| 74 { |
| 75 if (x[i*C]>1 || x[i*C]<-1) |
| 76 break; |
| 77 } |
| 78 if (i==N) |
| 79 { |
| 80 a=0; |
| 81 break; |
| 82 } |
| 83 peak_pos = i; |
| 84 start=end=i; |
| 85 maxval=ABS16(x[i*C]); |
| 86 /* Look for first zero crossing before clipping */ |
| 87 while (start>0 && x[i*C]*x[(start-1)*C]>=0) |
| 88 start--; |
| 89 /* Look for first zero crossing after clipping */ |
| 90 while (end<N && x[i*C]*x[end*C]>=0) |
| 91 { |
| 92 /* Look for other peaks until the next zero-crossing. */ |
| 93 if (ABS16(x[end*C])>maxval) |
| 94 { |
| 95 maxval = ABS16(x[end*C]); |
| 96 peak_pos = end; |
| 97 } |
| 98 end++; |
| 99 } |
| 100 /* Detect the special case where we clip before the first zero crossing
*/ |
| 101 special = (start==0 && x[i*C]*x[0]>=0); |
| 102 |
| 103 /* Compute a such that maxval + a*maxval^2 = 1 */ |
| 104 a=(maxval-1)/(maxval*maxval); |
| 105 if (x[i*C]>0) |
| 106 a = -a; |
| 107 /* Apply soft clipping */ |
| 108 for (i=start;i<end;i++) |
| 109 x[i*C] = x[i*C]+a*x[i*C]*x[i*C]; |
| 110 |
| 111 if (special && peak_pos>=2) |
| 112 { |
| 113 /* Add a linear ramp from the first sample to the signal peak. |
| 114 This avoids a discontinuity at the beginning of the frame. */ |
| 115 float delta; |
| 116 float offset = x0-x[0]; |
| 117 delta = offset / peak_pos; |
| 118 for (i=curr;i<peak_pos;i++) |
| 119 { |
| 120 offset -= delta; |
| 121 x[i*C] += offset; |
| 122 x[i*C] = MAX16(-1.f, MIN16(1.f, x[i*C])); |
| 123 } |
| 124 } |
| 125 curr = end; |
| 126 if (curr==N) |
| 127 break; |
| 128 } |
| 129 declip_mem[c] = a; |
| 130 } |
| 131 } |
| 132 #endif |
| 133 |
35 int encode_size(int size, unsigned char *data) | 134 int encode_size(int size, unsigned char *data) |
36 { | 135 { |
37 if (size < 252) | 136 if (size < 252) |
38 { | 137 { |
39 data[0] = size; | 138 data[0] = size; |
40 return 1; | 139 return 1; |
41 } else { | 140 } else { |
42 data[0] = 252+(size&0x3); | 141 data[0] = 252+(size&0x3); |
43 data[1] = (size-(int)data[0])>>2; | 142 data[1] = (size-(int)data[0])>>2; |
44 return 2; | 143 return 2; |
45 } | 144 } |
46 } | 145 } |
47 | 146 |
OLD | NEW |