/src/opus/src/opus_multistream_encoder.c
Line | Count | Source |
1 | | /* Copyright (c) 2011 Xiph.Org Foundation |
2 | | Written by Jean-Marc Valin */ |
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_multistream.h" |
33 | | #include "opus.h" |
34 | | #include "opus_private.h" |
35 | | #include "stack_alloc.h" |
36 | | #include <stdarg.h> |
37 | | #include "float_cast.h" |
38 | | #include "os_support.h" |
39 | | #include "mathops.h" |
40 | | #include "mdct.h" |
41 | | #include "modes.h" |
42 | | #include "bands.h" |
43 | | #include "quant_bands.h" |
44 | | #include "pitch.h" |
45 | | |
46 | | typedef struct { |
47 | | int nb_streams; |
48 | | int nb_coupled_streams; |
49 | | unsigned char mapping[8]; |
50 | | } VorbisLayout; |
51 | | |
52 | | /* Index is nb_channel-1*/ |
53 | | static const VorbisLayout vorbis_mappings[8] = { |
54 | | {1, 0, {0}}, /* 1: mono */ |
55 | | {1, 1, {0, 1}}, /* 2: stereo */ |
56 | | {2, 1, {0, 2, 1}}, /* 3: 1-d surround */ |
57 | | {2, 2, {0, 1, 2, 3}}, /* 4: quadraphonic surround */ |
58 | | {3, 2, {0, 4, 1, 2, 3}}, /* 5: 5-channel surround */ |
59 | | {4, 2, {0, 4, 1, 2, 3, 5}}, /* 6: 5.1 surround */ |
60 | | {4, 3, {0, 4, 1, 2, 3, 5, 6}}, /* 7: 6.1 surround */ |
61 | | {5, 3, {0, 6, 1, 2, 3, 4, 5, 7}}, /* 8: 7.1 surround */ |
62 | | }; |
63 | | |
64 | | #ifdef ENABLE_QEXT |
65 | 7.39k | #define MAX_OVERLAP 240 |
66 | | #else |
67 | | #define MAX_OVERLAP 120 |
68 | | #endif |
69 | | |
70 | | static opus_val32 *ms_get_preemph_mem(OpusMSEncoder *st) |
71 | 4.92k | { |
72 | 4.92k | int s; |
73 | 4.92k | char *ptr; |
74 | 4.92k | int coupled_size, mono_size; |
75 | | |
76 | 4.92k | coupled_size = opus_encoder_init(NULL, st->Fs, 2, st->application); |
77 | 4.92k | mono_size = opus_encoder_init(NULL, st->Fs, 1, st->application); |
78 | 4.92k | ptr = (char*)st + align(sizeof(OpusMSEncoder)); |
79 | 19.3k | for (s=0;s<st->layout.nb_streams;s++) |
80 | 14.4k | { |
81 | 14.4k | if (s < st->layout.nb_coupled_streams) |
82 | 9.38k | ptr += align(coupled_size); |
83 | 5.03k | else |
84 | 5.03k | ptr += align(mono_size); |
85 | 14.4k | } |
86 | | /* void* cast avoids clang -Wcast-align warning */ |
87 | 4.92k | return (opus_val32*)(void*)(ptr+st->layout.nb_channels*MAX_OVERLAP*sizeof(opus_val32)); |
88 | 4.92k | } |
89 | | |
90 | | static opus_val32 *ms_get_window_mem(OpusMSEncoder *st) |
91 | 4.92k | { |
92 | 4.92k | int s; |
93 | 4.92k | char *ptr; |
94 | 4.92k | int coupled_size, mono_size; |
95 | | |
96 | 4.92k | coupled_size = opus_encoder_init(NULL, st->Fs, 2, st->application); |
97 | 4.92k | mono_size = opus_encoder_init(NULL, st->Fs, 1, st->application); |
98 | 4.92k | ptr = (char*)st + align(sizeof(OpusMSEncoder)); |
99 | 19.3k | for (s=0;s<st->layout.nb_streams;s++) |
100 | 14.4k | { |
101 | 14.4k | if (s < st->layout.nb_coupled_streams) |
102 | 9.38k | ptr += align(coupled_size); |
103 | 5.03k | else |
104 | 5.03k | ptr += align(mono_size); |
105 | 14.4k | } |
106 | | /* void* cast avoids clang -Wcast-align warning */ |
107 | 4.92k | return (opus_val32*)(void*)ptr; |
108 | 4.92k | } |
109 | | |
110 | | static int validate_ambisonics(int nb_channels, int *nb_streams, int *nb_coupled_streams) |
111 | 11.2k | { |
112 | 11.2k | int order_plus_one; |
113 | 11.2k | int acn_channels; |
114 | 11.2k | int nondiegetic_channels; |
115 | | |
116 | 11.2k | if (nb_channels < 1 || nb_channels > 227) |
117 | 8 | return 0; |
118 | | |
119 | 11.2k | order_plus_one = isqrt32(nb_channels); |
120 | 11.2k | acn_channels = order_plus_one * order_plus_one; |
121 | 11.2k | nondiegetic_channels = nb_channels - acn_channels; |
122 | | |
123 | 11.2k | if (nondiegetic_channels != 0 && nondiegetic_channels != 2) |
124 | 93 | return 0; |
125 | | |
126 | 11.1k | if (nb_streams) |
127 | 7.46k | *nb_streams = acn_channels + (nondiegetic_channels != 0); |
128 | 11.1k | if (nb_coupled_streams) |
129 | 7.46k | *nb_coupled_streams = nondiegetic_channels != 0; |
130 | 11.1k | return 1; |
131 | 11.2k | } |
132 | | |
133 | | static int validate_encoder_layout(const ChannelLayout *layout) |
134 | 69.9k | { |
135 | 69.9k | int s; |
136 | 593k | for (s=0;s<layout->nb_streams;s++) |
137 | 523k | { |
138 | 523k | if (s < layout->nb_coupled_streams) |
139 | 167k | { |
140 | 167k | if (get_left_channel(layout, s, -1)==-1) |
141 | 63 | return 0; |
142 | 167k | if (get_right_channel(layout, s, -1)==-1) |
143 | 131 | return 0; |
144 | 355k | } else { |
145 | 355k | if (get_mono_channel(layout, s, -1)==-1) |
146 | 141 | return 0; |
147 | 355k | } |
148 | 523k | } |
149 | 69.5k | return 1; |
150 | 69.9k | } |
151 | | |
152 | | static void channel_pos(int channels, int pos[8]) |
153 | 2.44k | { |
154 | | /* Position in the mix: 0 don't mix, 1: left, 2: center, 3:right */ |
155 | 2.44k | if (channels==4) |
156 | 449 | { |
157 | 449 | pos[0]=1; |
158 | 449 | pos[1]=3; |
159 | 449 | pos[2]=1; |
160 | 449 | pos[3]=3; |
161 | 1.99k | } else if (channels==3||channels==5||channels==6) |
162 | 1.32k | { |
163 | 1.32k | pos[0]=1; |
164 | 1.32k | pos[1]=2; |
165 | 1.32k | pos[2]=3; |
166 | 1.32k | pos[3]=1; |
167 | 1.32k | pos[4]=3; |
168 | 1.32k | pos[5]=0; |
169 | 1.32k | } else if (channels==7) |
170 | 410 | { |
171 | 410 | pos[0]=1; |
172 | 410 | pos[1]=2; |
173 | 410 | pos[2]=3; |
174 | 410 | pos[3]=1; |
175 | 410 | pos[4]=3; |
176 | 410 | pos[5]=2; |
177 | 410 | pos[6]=0; |
178 | 410 | } else if (channels==8) |
179 | 255 | { |
180 | 255 | pos[0]=1; |
181 | 255 | pos[1]=2; |
182 | 255 | pos[2]=3; |
183 | 255 | pos[3]=1; |
184 | 255 | pos[4]=3; |
185 | 255 | pos[5]=1; |
186 | 255 | pos[6]=3; |
187 | 255 | pos[7]=0; |
188 | 255 | } |
189 | 2.44k | } |
190 | | |
191 | | #if 1 |
192 | | /* Computes a rough approximation of log2(2^a + 2^b) */ |
193 | | static opus_val16 logSum(celt_glog a, celt_glog b) |
194 | 279k | { |
195 | 279k | celt_glog max; |
196 | 279k | celt_glog diff; |
197 | 279k | celt_glog frac; |
198 | 279k | static const celt_glog diff_table[17] = { |
199 | 279k | GCONST(0.5000000f), GCONST(0.2924813f), GCONST(0.1609640f), GCONST(0.0849625f), |
200 | 279k | GCONST(0.0437314f), GCONST(0.0221971f), GCONST(0.0111839f), GCONST(0.0056136f), |
201 | 279k | GCONST(0.0028123f) |
202 | 279k | }; |
203 | 279k | int low; |
204 | 279k | if (a>b) |
205 | 82.3k | { |
206 | 82.3k | max = a; |
207 | 82.3k | diff = SUB32(a,b); |
208 | 197k | } else { |
209 | 197k | max = b; |
210 | 197k | diff = SUB32(b,a); |
211 | 197k | } |
212 | 279k | if (!(diff < GCONST(8.f))) /* inverted to catch NaNs */ |
213 | 115k | return max; |
214 | | #ifdef FIXED_POINT |
215 | 96.5k | low = SHR32(diff, DB_SHIFT-1); |
216 | 96.5k | frac = VSHR32(diff - SHL32(low, DB_SHIFT-1), DB_SHIFT-16); |
217 | | #else |
218 | 67.2k | low = (int)floor(2*diff); |
219 | 67.2k | frac = 2*diff - low; |
220 | 67.2k | #endif |
221 | 163k | return max + diff_table[low] + MULT16_32_Q15(frac, SUB32(diff_table[low+1], diff_table[low])); |
222 | 279k | } opus_multistream_encoder.c:logSum Line | Count | Source | 194 | 166k | { | 195 | 166k | celt_glog max; | 196 | 166k | celt_glog diff; | 197 | 166k | celt_glog frac; | 198 | 166k | static const celt_glog diff_table[17] = { | 199 | 166k | GCONST(0.5000000f), GCONST(0.2924813f), GCONST(0.1609640f), GCONST(0.0849625f), | 200 | 166k | GCONST(0.0437314f), GCONST(0.0221971f), GCONST(0.0111839f), GCONST(0.0056136f), | 201 | 166k | GCONST(0.0028123f) | 202 | 166k | }; | 203 | 166k | int low; | 204 | 166k | if (a>b) | 205 | 37.3k | { | 206 | 37.3k | max = a; | 207 | 37.3k | diff = SUB32(a,b); | 208 | 128k | } else { | 209 | 128k | max = b; | 210 | 128k | diff = SUB32(b,a); | 211 | 128k | } | 212 | 166k | if (!(diff < GCONST(8.f))) /* inverted to catch NaNs */ | 213 | 69.4k | return max; | 214 | 96.5k | #ifdef FIXED_POINT | 215 | 96.5k | low = SHR32(diff, DB_SHIFT-1); | 216 | 96.5k | frac = VSHR32(diff - SHL32(low, DB_SHIFT-1), DB_SHIFT-16); | 217 | | #else | 218 | | low = (int)floor(2*diff); | 219 | | frac = 2*diff - low; | 220 | | #endif | 221 | 96.5k | return max + diff_table[low] + MULT16_32_Q15(frac, SUB32(diff_table[low+1], diff_table[low])); | 222 | 166k | } |
opus_multistream_encoder.c:logSum Line | Count | Source | 194 | 113k | { | 195 | 113k | celt_glog max; | 196 | 113k | celt_glog diff; | 197 | 113k | celt_glog frac; | 198 | 113k | static const celt_glog diff_table[17] = { | 199 | 113k | GCONST(0.5000000f), GCONST(0.2924813f), GCONST(0.1609640f), GCONST(0.0849625f), | 200 | 113k | GCONST(0.0437314f), GCONST(0.0221971f), GCONST(0.0111839f), GCONST(0.0056136f), | 201 | 113k | GCONST(0.0028123f) | 202 | 113k | }; | 203 | 113k | int low; | 204 | 113k | if (a>b) | 205 | 44.9k | { | 206 | 44.9k | max = a; | 207 | 44.9k | diff = SUB32(a,b); | 208 | 68.3k | } else { | 209 | 68.3k | max = b; | 210 | 68.3k | diff = SUB32(b,a); | 211 | 68.3k | } | 212 | 113k | if (!(diff < GCONST(8.f))) /* inverted to catch NaNs */ | 213 | 46.0k | return max; | 214 | | #ifdef FIXED_POINT | 215 | | low = SHR32(diff, DB_SHIFT-1); | 216 | | frac = VSHR32(diff - SHL32(low, DB_SHIFT-1), DB_SHIFT-16); | 217 | | #else | 218 | 67.2k | low = (int)floor(2*diff); | 219 | 67.2k | frac = 2*diff - low; | 220 | 67.2k | #endif | 221 | 67.2k | return max + diff_table[low] + MULT16_32_Q15(frac, SUB32(diff_table[low+1], diff_table[low])); | 222 | 113k | } |
|
223 | | #else |
224 | | opus_val16 logSum(opus_val16 a, opus_val16 b) |
225 | | { |
226 | | return log2(pow(4, a)+ pow(4, b))/2; |
227 | | } |
228 | | #endif |
229 | | |
230 | | void surround_analysis(const CELTMode *celt_mode, const void *pcm, celt_glog *bandLogE, opus_val32 *mem, opus_val32 *preemph_mem, |
231 | | int len, int overlap, int channels, int rate, opus_copy_channel_in_func copy_channel_in, int arch |
232 | | ) |
233 | 2.44k | { |
234 | 2.44k | int c; |
235 | 2.44k | int i; |
236 | 2.44k | int LM; |
237 | 2.44k | int pos[8] = {0}; |
238 | 2.44k | int upsample; |
239 | 2.44k | int frame_size; |
240 | 2.44k | int freq_size; |
241 | 2.44k | opus_val16 channel_offset; |
242 | 2.44k | opus_val32 bandE[21]; |
243 | 2.44k | celt_glog maskLogE[3][21]; |
244 | 2.44k | VARDECL(opus_val32, in); |
245 | 2.44k | VARDECL(opus_res, x); |
246 | 2.44k | VARDECL(opus_val32, freq); |
247 | 2.44k | SAVE_STACK; |
248 | | |
249 | 2.44k | upsample = resampling_factor(rate); |
250 | 2.44k | frame_size = len*upsample; |
251 | | |
252 | | /* LM = log2(frame_size / 120) */ |
253 | 5.95k | for (LM=0;LM<celt_mode->maxLM;LM++) |
254 | 5.08k | if (celt_mode->shortMdctSize<<LM==frame_size) |
255 | 1.56k | break; |
256 | | |
257 | 2.44k | freq_size = celt_mode->shortMdctSize<<LM; |
258 | | |
259 | 2.44k | ALLOC(in, frame_size+overlap, opus_val32); |
260 | 2.44k | ALLOC(x, len, opus_res); |
261 | 2.44k | ALLOC(freq, freq_size, opus_val32); |
262 | | |
263 | 2.44k | channel_pos(channels, pos); |
264 | | |
265 | 9.76k | for (c=0;c<3;c++) |
266 | 161k | for (i=0;i<21;i++) |
267 | 153k | maskLogE[c][i] = -GCONST(28.f); |
268 | | |
269 | 14.2k | for (c=0;c<channels;c++) |
270 | 11.8k | { |
271 | 11.8k | int frame; |
272 | 11.8k | int nb_frames = frame_size/freq_size; |
273 | 11.8k | celt_assert(nb_frames*freq_size == frame_size); |
274 | 11.8k | OPUS_COPY(in, mem+c*overlap, overlap); |
275 | 11.8k | (*copy_channel_in)(x, 1, pcm, channels, c, len, NULL); |
276 | 11.8k | celt_preemphasis(x, in+overlap, frame_size, 1, upsample, celt_mode->preemph, preemph_mem+c, 0); |
277 | | #ifndef FIXED_POINT |
278 | | { |
279 | | opus_val32 sum; |
280 | 4.81k | sum = celt_inner_prod(in, in, frame_size+overlap, 0); |
281 | | /* This should filter out both NaNs and ridiculous signals that could |
282 | | cause NaNs further down. */ |
283 | 4.81k | if (!(sum < 1e18f) || celt_isnan(sum)) |
284 | 0 | { |
285 | 0 | OPUS_CLEAR(in, frame_size+overlap); |
286 | 0 | preemph_mem[c] = 0; |
287 | 0 | } |
288 | | } |
289 | | #endif |
290 | 11.8k | OPUS_CLEAR(bandE, 21); |
291 | 37.6k | for (frame=0;frame<nb_frames;frame++) |
292 | 25.8k | { |
293 | 25.8k | opus_val32 tmpE[21]; |
294 | 25.8k | clt_mdct_forward(&celt_mode->mdct, in+freq_size*frame, freq, celt_mode->window, |
295 | 25.8k | overlap, celt_mode->maxLM-LM, 1, arch); |
296 | 25.8k | if (upsample != 1) |
297 | 24.0k | { |
298 | 24.0k | int bound = freq_size/upsample; |
299 | 3.57M | for (i=0;i<bound;i++) |
300 | 3.55M | freq[i] *= upsample; |
301 | 14.4M | for (;i<freq_size;i++) |
302 | 14.4M | freq[i] = 0; |
303 | 24.0k | } |
304 | | |
305 | 25.8k | compute_band_energies(celt_mode, freq, tmpE, 21, 1, LM, arch); |
306 | | /* If we have multiple frames, take the max energy. */ |
307 | 569k | for (i=0;i<21;i++) |
308 | 543k | bandE[i] = MAX32(bandE[i], tmpE[i]); |
309 | 25.8k | } |
310 | 11.8k | amp2Log2(celt_mode, 21, 21, bandE, bandLogE+21*c, 1); |
311 | | /* Apply spreading function with -6 dB/band going up and -12 dB/band going down. */ |
312 | 248k | for (i=1;i<21;i++) |
313 | 236k | bandLogE[21*c+i] = MAXG(bandLogE[21*c+i], bandLogE[21*c+i-1]-GCONST(1.f)); |
314 | 248k | for (i=19;i>=0;i--) |
315 | 236k | bandLogE[21*c+i] = MAXG(bandLogE[21*c+i], bandLogE[21*c+i+1]-GCONST(2.f)); |
316 | 11.8k | if (pos[c]==1) |
317 | 4.24k | { |
318 | 93.4k | for (i=0;i<21;i++) |
319 | 89.2k | maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]); |
320 | 7.56k | } else if (pos[c]==3) |
321 | 4.24k | { |
322 | 93.4k | for (i=0;i<21;i++) |
323 | 89.2k | maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]); |
324 | 4.24k | } else if (pos[c]==2) |
325 | 2.40k | { |
326 | 52.8k | for (i=0;i<21;i++) |
327 | 50.4k | { |
328 | 50.4k | maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]-GCONST(.5f)); |
329 | 50.4k | maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]-GCONST(.5f)); |
330 | 50.4k | } |
331 | 2.40k | } |
332 | | #if 0 |
333 | | for (i=0;i<21;i++) |
334 | | printf("%f ", bandLogE[21*c+i]); |
335 | | float sum=0; |
336 | | for (i=0;i<21;i++) |
337 | | sum += bandLogE[21*c+i]; |
338 | | printf("%f ", sum/21); |
339 | | #endif |
340 | 11.8k | OPUS_COPY(mem+c*overlap, in+frame_size, overlap); |
341 | 11.8k | } |
342 | 53.7k | for (i=0;i<21;i++) |
343 | 51.2k | maskLogE[1][i] = MIN32(maskLogE[0][i],maskLogE[2][i]); |
344 | 2.44k | channel_offset = HALF16(celt_log2(QCONST32(2.f,14)/(channels-1))); |
345 | 9.76k | for (c=0;c<3;c++) |
346 | 161k | for (i=0;i<21;i++) |
347 | 153k | maskLogE[c][i] += channel_offset; |
348 | | #if 0 |
349 | | for (c=0;c<3;c++) |
350 | | { |
351 | | for (i=0;i<21;i++) |
352 | | printf("%f ", maskLogE[c][i]); |
353 | | } |
354 | | #endif |
355 | 14.2k | for (c=0;c<channels;c++) |
356 | 11.8k | { |
357 | 11.8k | celt_glog *mask; |
358 | 11.8k | if (pos[c]!=0) |
359 | 10.9k | { |
360 | 10.9k | mask = &maskLogE[pos[c]-1][0]; |
361 | 239k | for (i=0;i<21;i++) |
362 | 228k | bandLogE[21*c+i] = bandLogE[21*c+i] - mask[i]; |
363 | 10.9k | } else { |
364 | 20.1k | for (i=0;i<21;i++) |
365 | 19.2k | bandLogE[21*c+i] = 0; |
366 | 915 | } |
367 | | #if 0 |
368 | | for (i=0;i<21;i++) |
369 | | printf("%f ", bandLogE[21*c+i]); |
370 | | printf("\n"); |
371 | | #endif |
372 | | #if 0 |
373 | | float sum=0; |
374 | | for (i=0;i<21;i++) |
375 | | sum += bandLogE[21*c+i]; |
376 | | printf("%f ", sum/(float)QCONST32(21.f, DB_SHIFT)); |
377 | | printf("\n"); |
378 | | #endif |
379 | 11.8k | } |
380 | 2.44k | RESTORE_STACK; |
381 | 2.44k | } Line | Count | Source | 233 | 1.45k | { | 234 | 1.45k | int c; | 235 | 1.45k | int i; | 236 | 1.45k | int LM; | 237 | 1.45k | int pos[8] = {0}; | 238 | 1.45k | int upsample; | 239 | 1.45k | int frame_size; | 240 | 1.45k | int freq_size; | 241 | 1.45k | opus_val16 channel_offset; | 242 | 1.45k | opus_val32 bandE[21]; | 243 | 1.45k | celt_glog maskLogE[3][21]; | 244 | 1.45k | VARDECL(opus_val32, in); | 245 | 1.45k | VARDECL(opus_res, x); | 246 | 1.45k | VARDECL(opus_val32, freq); | 247 | 1.45k | SAVE_STACK; | 248 | | | 249 | 1.45k | upsample = resampling_factor(rate); | 250 | 1.45k | frame_size = len*upsample; | 251 | | | 252 | | /* LM = log2(frame_size / 120) */ | 253 | 3.34k | for (LM=0;LM<celt_mode->maxLM;LM++) | 254 | 2.89k | if (celt_mode->shortMdctSize<<LM==frame_size) | 255 | 1.00k | break; | 256 | | | 257 | 1.45k | freq_size = celt_mode->shortMdctSize<<LM; | 258 | | | 259 | 1.45k | ALLOC(in, frame_size+overlap, opus_val32); | 260 | 1.45k | ALLOC(x, len, opus_res); | 261 | 1.45k | ALLOC(freq, freq_size, opus_val32); | 262 | | | 263 | 1.45k | channel_pos(channels, pos); | 264 | | | 265 | 5.83k | for (c=0;c<3;c++) | 266 | 96.2k | for (i=0;i<21;i++) | 267 | 91.9k | maskLogE[c][i] = -GCONST(28.f); | 268 | | | 269 | 8.46k | for (c=0;c<channels;c++) | 270 | 7.00k | { | 271 | 7.00k | int frame; | 272 | 7.00k | int nb_frames = frame_size/freq_size; | 273 | 7.00k | celt_assert(nb_frames*freq_size == frame_size); | 274 | 7.00k | OPUS_COPY(in, mem+c*overlap, overlap); | 275 | 7.00k | (*copy_channel_in)(x, 1, pcm, channels, c, len, NULL); | 276 | 7.00k | celt_preemphasis(x, in+overlap, frame_size, 1, upsample, celt_mode->preemph, preemph_mem+c, 0); | 277 | | #ifndef FIXED_POINT | 278 | | { | 279 | | opus_val32 sum; | 280 | | sum = celt_inner_prod(in, in, frame_size+overlap, 0); | 281 | | /* This should filter out both NaNs and ridiculous signals that could | 282 | | cause NaNs further down. */ | 283 | | if (!(sum < 1e18f) || celt_isnan(sum)) | 284 | | { | 285 | | OPUS_CLEAR(in, frame_size+overlap); | 286 | | preemph_mem[c] = 0; | 287 | | } | 288 | | } | 289 | | #endif | 290 | 7.00k | OPUS_CLEAR(bandE, 21); | 291 | 21.7k | for (frame=0;frame<nb_frames;frame++) | 292 | 14.7k | { | 293 | 14.7k | opus_val32 tmpE[21]; | 294 | 14.7k | clt_mdct_forward(&celt_mode->mdct, in+freq_size*frame, freq, celt_mode->window, | 295 | 14.7k | overlap, celt_mode->maxLM-LM, 1, arch); | 296 | 14.7k | if (upsample != 1) | 297 | 13.5k | { | 298 | 13.5k | int bound = freq_size/upsample; | 299 | 1.91M | for (i=0;i<bound;i++) | 300 | 1.90M | freq[i] *= upsample; | 301 | 7.79M | for (;i<freq_size;i++) | 302 | 7.78M | freq[i] = 0; | 303 | 13.5k | } | 304 | | | 305 | 14.7k | compute_band_energies(celt_mode, freq, tmpE, 21, 1, LM, arch); | 306 | | /* If we have multiple frames, take the max energy. */ | 307 | 323k | for (i=0;i<21;i++) | 308 | 308k | bandE[i] = MAX32(bandE[i], tmpE[i]); | 309 | 14.7k | } | 310 | 7.00k | amp2Log2(celt_mode, 21, 21, bandE, bandLogE+21*c, 1); | 311 | | /* Apply spreading function with -6 dB/band going up and -12 dB/band going down. */ | 312 | 147k | for (i=1;i<21;i++) | 313 | 140k | bandLogE[21*c+i] = MAXG(bandLogE[21*c+i], bandLogE[21*c+i-1]-GCONST(1.f)); | 314 | 147k | for (i=19;i>=0;i--) | 315 | 140k | bandLogE[21*c+i] = MAXG(bandLogE[21*c+i], bandLogE[21*c+i+1]-GCONST(2.f)); | 316 | 7.00k | if (pos[c]==1) | 317 | 2.51k | { | 318 | 55.3k | for (i=0;i<21;i++) | 319 | 52.7k | maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]); | 320 | 4.48k | } else if (pos[c]==3) | 321 | 2.51k | { | 322 | 55.3k | for (i=0;i<21;i++) | 323 | 52.7k | maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]); | 324 | 2.51k | } else if (pos[c]==2) | 325 | 1.44k | { | 326 | 31.6k | for (i=0;i<21;i++) | 327 | 30.2k | { | 328 | 30.2k | maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]-GCONST(.5f)); | 329 | 30.2k | maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]-GCONST(.5f)); | 330 | 30.2k | } | 331 | 1.44k | } | 332 | | #if 0 | 333 | | for (i=0;i<21;i++) | 334 | | printf("%f ", bandLogE[21*c+i]); | 335 | | float sum=0; | 336 | | for (i=0;i<21;i++) | 337 | | sum += bandLogE[21*c+i]; | 338 | | printf("%f ", sum/21); | 339 | | #endif | 340 | 7.00k | OPUS_COPY(mem+c*overlap, in+frame_size, overlap); | 341 | 7.00k | } | 342 | 32.0k | for (i=0;i<21;i++) | 343 | 30.6k | maskLogE[1][i] = MIN32(maskLogE[0][i],maskLogE[2][i]); | 344 | 1.45k | channel_offset = HALF16(celt_log2(QCONST32(2.f,14)/(channels-1))); | 345 | 5.83k | for (c=0;c<3;c++) | 346 | 96.2k | for (i=0;i<21;i++) | 347 | 91.9k | maskLogE[c][i] += channel_offset; | 348 | | #if 0 | 349 | | for (c=0;c<3;c++) | 350 | | { | 351 | | for (i=0;i<21;i++) | 352 | | printf("%f ", maskLogE[c][i]); | 353 | | } | 354 | | #endif | 355 | 8.46k | for (c=0;c<channels;c++) | 356 | 7.00k | { | 357 | 7.00k | celt_glog *mask; | 358 | 7.00k | if (pos[c]!=0) | 359 | 6.46k | { | 360 | 6.46k | mask = &maskLogE[pos[c]-1][0]; | 361 | 142k | for (i=0;i<21;i++) | 362 | 135k | bandLogE[21*c+i] = bandLogE[21*c+i] - mask[i]; | 363 | 6.46k | } else { | 364 | 11.7k | for (i=0;i<21;i++) | 365 | 11.2k | bandLogE[21*c+i] = 0; | 366 | 534 | } | 367 | | #if 0 | 368 | | for (i=0;i<21;i++) | 369 | | printf("%f ", bandLogE[21*c+i]); | 370 | | printf("\n"); | 371 | | #endif | 372 | | #if 0 | 373 | | float sum=0; | 374 | | for (i=0;i<21;i++) | 375 | | sum += bandLogE[21*c+i]; | 376 | | printf("%f ", sum/(float)QCONST32(21.f, DB_SHIFT)); | 377 | | printf("\n"); | 378 | | #endif | 379 | 7.00k | } | 380 | 1.45k | RESTORE_STACK; | 381 | 1.45k | } |
Line | Count | Source | 233 | 983 | { | 234 | 983 | int c; | 235 | 983 | int i; | 236 | 983 | int LM; | 237 | 983 | int pos[8] = {0}; | 238 | 983 | int upsample; | 239 | 983 | int frame_size; | 240 | 983 | int freq_size; | 241 | 983 | opus_val16 channel_offset; | 242 | 983 | opus_val32 bandE[21]; | 243 | 983 | celt_glog maskLogE[3][21]; | 244 | 983 | VARDECL(opus_val32, in); | 245 | 983 | VARDECL(opus_res, x); | 246 | 983 | VARDECL(opus_val32, freq); | 247 | 983 | SAVE_STACK; | 248 | | | 249 | 983 | upsample = resampling_factor(rate); | 250 | 983 | frame_size = len*upsample; | 251 | | | 252 | | /* LM = log2(frame_size / 120) */ | 253 | 2.60k | for (LM=0;LM<celt_mode->maxLM;LM++) | 254 | 2.18k | if (celt_mode->shortMdctSize<<LM==frame_size) | 255 | 566 | break; | 256 | | | 257 | 983 | freq_size = celt_mode->shortMdctSize<<LM; | 258 | | | 259 | 983 | ALLOC(in, frame_size+overlap, opus_val32); | 260 | 983 | ALLOC(x, len, opus_res); | 261 | 983 | ALLOC(freq, freq_size, opus_val32); | 262 | | | 263 | 983 | channel_pos(channels, pos); | 264 | | | 265 | 3.93k | for (c=0;c<3;c++) | 266 | 64.8k | for (i=0;i<21;i++) | 267 | 61.9k | maskLogE[c][i] = -GCONST(28.f); | 268 | | | 269 | 5.79k | for (c=0;c<channels;c++) | 270 | 4.81k | { | 271 | 4.81k | int frame; | 272 | 4.81k | int nb_frames = frame_size/freq_size; | 273 | 4.81k | celt_assert(nb_frames*freq_size == frame_size); | 274 | 4.81k | OPUS_COPY(in, mem+c*overlap, overlap); | 275 | 4.81k | (*copy_channel_in)(x, 1, pcm, channels, c, len, NULL); | 276 | 4.81k | celt_preemphasis(x, in+overlap, frame_size, 1, upsample, celt_mode->preemph, preemph_mem+c, 0); | 277 | 4.81k | #ifndef FIXED_POINT | 278 | 4.81k | { | 279 | 4.81k | opus_val32 sum; | 280 | 4.81k | sum = celt_inner_prod(in, in, frame_size+overlap, 0); | 281 | | /* This should filter out both NaNs and ridiculous signals that could | 282 | | cause NaNs further down. */ | 283 | 4.81k | if (!(sum < 1e18f) || celt_isnan(sum)) | 284 | 0 | { | 285 | 0 | OPUS_CLEAR(in, frame_size+overlap); | 286 | 0 | preemph_mem[c] = 0; | 287 | 0 | } | 288 | 4.81k | } | 289 | 4.81k | #endif | 290 | 4.81k | OPUS_CLEAR(bandE, 21); | 291 | 15.9k | for (frame=0;frame<nb_frames;frame++) | 292 | 11.1k | { | 293 | 11.1k | opus_val32 tmpE[21]; | 294 | 11.1k | clt_mdct_forward(&celt_mode->mdct, in+freq_size*frame, freq, celt_mode->window, | 295 | 11.1k | overlap, celt_mode->maxLM-LM, 1, arch); | 296 | 11.1k | if (upsample != 1) | 297 | 10.5k | { | 298 | 10.5k | int bound = freq_size/upsample; | 299 | 1.65M | for (i=0;i<bound;i++) | 300 | 1.64M | freq[i] *= upsample; | 301 | 6.67M | for (;i<freq_size;i++) | 302 | 6.66M | freq[i] = 0; | 303 | 10.5k | } | 304 | | | 305 | 11.1k | compute_band_energies(celt_mode, freq, tmpE, 21, 1, LM, arch); | 306 | | /* If we have multiple frames, take the max energy. */ | 307 | 245k | for (i=0;i<21;i++) | 308 | 234k | bandE[i] = MAX32(bandE[i], tmpE[i]); | 309 | 11.1k | } | 310 | 4.81k | amp2Log2(celt_mode, 21, 21, bandE, bandLogE+21*c, 1); | 311 | | /* Apply spreading function with -6 dB/band going up and -12 dB/band going down. */ | 312 | 101k | for (i=1;i<21;i++) | 313 | 96.2k | bandLogE[21*c+i] = MAXG(bandLogE[21*c+i], bandLogE[21*c+i-1]-GCONST(1.f)); | 314 | 101k | for (i=19;i>=0;i--) | 315 | 96.2k | bandLogE[21*c+i] = MAXG(bandLogE[21*c+i], bandLogE[21*c+i+1]-GCONST(2.f)); | 316 | 4.81k | if (pos[c]==1) | 317 | 1.73k | { | 318 | 38.1k | for (i=0;i<21;i++) | 319 | 36.4k | maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]); | 320 | 3.07k | } else if (pos[c]==3) | 321 | 1.73k | { | 322 | 38.1k | for (i=0;i<21;i++) | 323 | 36.4k | maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]); | 324 | 1.73k | } else if (pos[c]==2) | 325 | 963 | { | 326 | 21.1k | for (i=0;i<21;i++) | 327 | 20.2k | { | 328 | 20.2k | maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]-GCONST(.5f)); | 329 | 20.2k | maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]-GCONST(.5f)); | 330 | 20.2k | } | 331 | 963 | } | 332 | | #if 0 | 333 | | for (i=0;i<21;i++) | 334 | | printf("%f ", bandLogE[21*c+i]); | 335 | | float sum=0; | 336 | | for (i=0;i<21;i++) | 337 | | sum += bandLogE[21*c+i]; | 338 | | printf("%f ", sum/21); | 339 | | #endif | 340 | 4.81k | OPUS_COPY(mem+c*overlap, in+frame_size, overlap); | 341 | 4.81k | } | 342 | 21.6k | for (i=0;i<21;i++) | 343 | 20.6k | maskLogE[1][i] = MIN32(maskLogE[0][i],maskLogE[2][i]); | 344 | 983 | channel_offset = HALF16(celt_log2(QCONST32(2.f,14)/(channels-1))); | 345 | 3.93k | for (c=0;c<3;c++) | 346 | 64.8k | for (i=0;i<21;i++) | 347 | 61.9k | maskLogE[c][i] += channel_offset; | 348 | | #if 0 | 349 | | for (c=0;c<3;c++) | 350 | | { | 351 | | for (i=0;i<21;i++) | 352 | | printf("%f ", maskLogE[c][i]); | 353 | | } | 354 | | #endif | 355 | 5.79k | for (c=0;c<channels;c++) | 356 | 4.81k | { | 357 | 4.81k | celt_glog *mask; | 358 | 4.81k | if (pos[c]!=0) | 359 | 4.43k | { | 360 | 4.43k | mask = &maskLogE[pos[c]-1][0]; | 361 | 97.5k | for (i=0;i<21;i++) | 362 | 93.0k | bandLogE[21*c+i] = bandLogE[21*c+i] - mask[i]; | 363 | 4.43k | } else { | 364 | 8.38k | for (i=0;i<21;i++) | 365 | 8.00k | bandLogE[21*c+i] = 0; | 366 | 381 | } | 367 | | #if 0 | 368 | | for (i=0;i<21;i++) | 369 | | printf("%f ", bandLogE[21*c+i]); | 370 | | printf("\n"); | 371 | | #endif | 372 | | #if 0 | 373 | | float sum=0; | 374 | | for (i=0;i<21;i++) | 375 | | sum += bandLogE[21*c+i]; | 376 | | printf("%f ", sum/(float)QCONST32(21.f, DB_SHIFT)); | 377 | | printf("\n"); | 378 | | #endif | 379 | 4.81k | } | 380 | 983 | RESTORE_STACK; | 381 | 983 | } |
|
382 | | |
383 | | opus_int32 opus_multistream_encoder_get_size(int nb_streams, int nb_coupled_streams) |
384 | 30.1k | { |
385 | 30.1k | int coupled_size; |
386 | 30.1k | int mono_size; |
387 | | |
388 | 30.1k | if(nb_streams<1||nb_coupled_streams>nb_streams||nb_coupled_streams<0)return 0; |
389 | 30.1k | coupled_size = opus_encoder_get_size(2); |
390 | 30.1k | mono_size = opus_encoder_get_size(1); |
391 | 30.1k | return align(sizeof(OpusMSEncoder)) |
392 | 30.1k | + nb_coupled_streams * align(coupled_size) |
393 | 30.1k | + (nb_streams-nb_coupled_streams) * align(mono_size); |
394 | 30.1k | } |
395 | | |
396 | | opus_int32 opus_multistream_surround_encoder_get_size(int channels, int mapping_family) |
397 | 0 | { |
398 | 0 | int nb_streams; |
399 | 0 | int nb_coupled_streams; |
400 | 0 | opus_int32 size; |
401 | |
|
402 | 0 | if (mapping_family==0) |
403 | 0 | { |
404 | 0 | if (channels==1) |
405 | 0 | { |
406 | 0 | nb_streams=1; |
407 | 0 | nb_coupled_streams=0; |
408 | 0 | } else if (channels==2) |
409 | 0 | { |
410 | 0 | nb_streams=1; |
411 | 0 | nb_coupled_streams=1; |
412 | 0 | } else |
413 | 0 | return 0; |
414 | 0 | } else if (mapping_family==1 && channels<=8 && channels>=1) |
415 | 0 | { |
416 | 0 | nb_streams=vorbis_mappings[channels-1].nb_streams; |
417 | 0 | nb_coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams; |
418 | 0 | } else if (mapping_family==255) |
419 | 0 | { |
420 | 0 | nb_streams=channels; |
421 | 0 | nb_coupled_streams=0; |
422 | 0 | } else if (mapping_family==2) |
423 | 0 | { |
424 | 0 | if (!validate_ambisonics(channels, &nb_streams, &nb_coupled_streams)) |
425 | 0 | return 0; |
426 | 0 | } else |
427 | 0 | return 0; |
428 | 0 | size = opus_multistream_encoder_get_size(nb_streams, nb_coupled_streams); |
429 | 0 | if (channels>2) |
430 | 0 | { |
431 | 0 | size += channels*(MAX_OVERLAP*sizeof(opus_val32) + sizeof(opus_val32)); |
432 | 0 | } |
433 | 0 | return size; |
434 | 0 | } |
435 | | |
436 | | static int opus_multistream_encoder_init_impl( |
437 | | OpusMSEncoder *st, |
438 | | opus_int32 Fs, |
439 | | int channels, |
440 | | int streams, |
441 | | int coupled_streams, |
442 | | const unsigned char *mapping, |
443 | | int application, |
444 | | MappingType mapping_type |
445 | | ) |
446 | 109k | { |
447 | 109k | int coupled_size; |
448 | 109k | int mono_size; |
449 | 109k | int i, ret; |
450 | 109k | char *ptr; |
451 | | |
452 | 109k | if ((channels>255) || (channels<1) || (coupled_streams>streams) || |
453 | 109k | (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams) || |
454 | 109k | (streams+coupled_streams>channels)) |
455 | 0 | return OPUS_BAD_ARG; |
456 | | |
457 | 109k | coupled_size = opus_encoder_init(NULL, Fs, 2, application); |
458 | 109k | if (coupled_size < 0) |
459 | 0 | return coupled_size; |
460 | 109k | mono_size = opus_encoder_init(NULL, Fs, 1, application); |
461 | 109k | if (mono_size < 0) |
462 | 0 | return mono_size; |
463 | 109k | if (st == NULL) |
464 | 39.7k | { |
465 | 39.7k | int surround_size=0; |
466 | 39.7k | if (mapping_type == MAPPING_TYPE_SURROUND) { |
467 | 2.47k | surround_size = channels*(MAX_OVERLAP*sizeof(opus_val32) + sizeof(opus_val32)); |
468 | 2.47k | } |
469 | | |
470 | 39.7k | return align(sizeof(OpusMSEncoder)) + coupled_streams*align(coupled_size) |
471 | 39.7k | + (streams-coupled_streams)*align(mono_size) + surround_size; |
472 | 39.7k | } |
473 | | |
474 | 69.9k | st->arch = opus_select_arch(); |
475 | 69.9k | st->layout.nb_channels = channels; |
476 | 69.9k | st->layout.nb_streams = streams; |
477 | 69.9k | st->layout.nb_coupled_streams = coupled_streams; |
478 | 69.9k | if (mapping_type != MAPPING_TYPE_SURROUND) |
479 | 67.4k | st->lfe_stream = -1; |
480 | 69.9k | st->bitrate_bps = OPUS_AUTO; |
481 | 69.9k | st->application = application; |
482 | 69.9k | st->Fs = Fs; |
483 | 69.9k | st->variable_duration = OPUS_FRAMESIZE_ARG; |
484 | 859k | for (i=0;i<st->layout.nb_channels;i++) |
485 | 789k | st->layout.mapping[i] = mapping[i]; |
486 | 69.9k | if (!validate_layout(&st->layout)) |
487 | 25 | return OPUS_BAD_ARG; |
488 | 69.9k | if (!validate_encoder_layout(&st->layout)) |
489 | 335 | return OPUS_BAD_ARG; |
490 | 69.5k | if (mapping_type == MAPPING_TYPE_AMBISONICS && |
491 | 3.73k | !validate_ambisonics(st->layout.nb_channels, NULL, NULL)) |
492 | 0 | return OPUS_BAD_ARG; |
493 | 69.5k | ptr = (char*)st + align(sizeof(OpusMSEncoder)); |
494 | 236k | for (i=0;i<st->layout.nb_coupled_streams;i++) |
495 | 166k | { |
496 | 166k | ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 2, application); |
497 | 166k | if(ret!=OPUS_OK)return ret; |
498 | 166k | if (i==st->lfe_stream) |
499 | 0 | opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1)); |
500 | 166k | ptr += align(coupled_size); |
501 | 166k | } |
502 | 424k | for (;i<st->layout.nb_streams;i++) |
503 | 355k | { |
504 | 355k | ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 1, application); |
505 | 355k | if(ret!=OPUS_OK)return ret; |
506 | 355k | if (i==st->lfe_stream) |
507 | 927 | opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1)); |
508 | 355k | ptr += align(mono_size); |
509 | 355k | } |
510 | 69.5k | if (mapping_type == MAPPING_TYPE_SURROUND) |
511 | 2.47k | { |
512 | 2.47k | OPUS_CLEAR(ms_get_preemph_mem(st), channels); |
513 | 2.47k | OPUS_CLEAR(ms_get_window_mem(st), channels*MAX_OVERLAP); |
514 | 2.47k | } |
515 | 69.5k | st->mapping_type = mapping_type; |
516 | 69.5k | return OPUS_OK; |
517 | 69.5k | } |
518 | | |
519 | | int opus_multistream_encoder_init( |
520 | | OpusMSEncoder *st, |
521 | | opus_int32 Fs, |
522 | | int channels, |
523 | | int streams, |
524 | | int coupled_streams, |
525 | | const unsigned char *mapping, |
526 | | int application |
527 | | ) |
528 | 59.7k | { |
529 | 59.7k | return opus_multistream_encoder_init_impl(st, Fs, channels, streams, |
530 | 59.7k | coupled_streams, mapping, |
531 | 59.7k | application, MAPPING_TYPE_NONE); |
532 | 59.7k | } |
533 | | |
534 | | int opus_multistream_surround_encoder_init( |
535 | | OpusMSEncoder *st, |
536 | | opus_int32 Fs, |
537 | | int channels, |
538 | | int mapping_family, |
539 | | int *streams, |
540 | | int *coupled_streams, |
541 | | unsigned char *mapping, |
542 | | int application |
543 | | ) |
544 | 50.1k | { |
545 | 50.1k | MappingType mapping_type; |
546 | 50.1k | int lfe_stream; |
547 | | |
548 | 50.1k | if ((channels>255) || (channels<1)) |
549 | 0 | return OPUS_BAD_ARG; |
550 | 50.1k | lfe_stream = -1; |
551 | 50.1k | if (mapping_family==0) |
552 | 11.4k | { |
553 | 11.4k | if (channels==1) |
554 | 5.76k | { |
555 | 5.76k | *streams=1; |
556 | 5.76k | *coupled_streams=0; |
557 | 5.76k | mapping[0]=0; |
558 | 5.76k | } else if (channels==2) |
559 | 5.59k | { |
560 | 5.59k | *streams=1; |
561 | 5.59k | *coupled_streams=1; |
562 | 5.59k | mapping[0]=0; |
563 | 5.59k | mapping[1]=1; |
564 | 5.59k | } else |
565 | 84 | return OPUS_UNIMPLEMENTED; |
566 | 38.7k | } else if (mapping_family==1 && channels<=8 && channels>=1) |
567 | 8.08k | { |
568 | 8.08k | int i; |
569 | 8.08k | *streams=vorbis_mappings[channels-1].nb_streams; |
570 | 8.08k | *coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams; |
571 | 36.7k | for (i=0;i<channels;i++) |
572 | 28.6k | mapping[i] = vorbis_mappings[channels-1].mapping[i]; |
573 | 8.08k | if (channels>=6) |
574 | 1.85k | lfe_stream = *streams-1; |
575 | 30.6k | } else if (mapping_family==255) |
576 | 23.0k | { |
577 | 23.0k | int i; |
578 | 23.0k | *streams=channels; |
579 | 23.0k | *coupled_streams=0; |
580 | 581k | for(i=0;i<channels;i++) |
581 | 558k | mapping[i] = i; |
582 | 23.0k | } else if (mapping_family==2) |
583 | 7.56k | { |
584 | 7.56k | int i; |
585 | 7.56k | if (!validate_ambisonics(channels, streams, coupled_streams)) |
586 | 101 | return OPUS_BAD_ARG; |
587 | 112k | for(i = 0; i < (*streams - *coupled_streams); i++) |
588 | 104k | mapping[i] = i + (*coupled_streams * 2); |
589 | 10.3k | for(i = 0; i < *coupled_streams * 2; i++) |
590 | 2.87k | mapping[i + (*streams - *coupled_streams)] = i; |
591 | 7.46k | } else |
592 | 29 | return OPUS_UNIMPLEMENTED; |
593 | | |
594 | 49.9k | if (channels>2 && mapping_family==1) { |
595 | 4.95k | mapping_type = MAPPING_TYPE_SURROUND; |
596 | 45.0k | } else if (mapping_family==2) |
597 | 7.46k | { |
598 | 7.46k | mapping_type = MAPPING_TYPE_AMBISONICS; |
599 | 7.46k | } else |
600 | 37.5k | { |
601 | 37.5k | mapping_type = MAPPING_TYPE_NONE; |
602 | 37.5k | } |
603 | 49.9k | if (st != NULL) { |
604 | 24.9k | st->lfe_stream = lfe_stream; |
605 | 24.9k | } |
606 | 49.9k | return opus_multistream_encoder_init_impl(st, Fs, channels, *streams, |
607 | 49.9k | *coupled_streams, mapping, |
608 | 49.9k | application, mapping_type); |
609 | 50.1k | } |
610 | | |
611 | | OpusMSEncoder *opus_multistream_encoder_create( |
612 | | opus_int32 Fs, |
613 | | int channels, |
614 | | int streams, |
615 | | int coupled_streams, |
616 | | const unsigned char *mapping, |
617 | | int application, |
618 | | int *error |
619 | | ) |
620 | 14.9k | { |
621 | 14.9k | int ret; |
622 | 14.9k | OpusMSEncoder *st; |
623 | 14.9k | opus_int32 size; |
624 | 14.9k | if ((channels>255) || (channels<1) || (coupled_streams>streams) || |
625 | 14.9k | (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams) || |
626 | 14.7k | (streams+coupled_streams>channels)) |
627 | 240 | { |
628 | 240 | if (error) |
629 | 240 | *error = OPUS_BAD_ARG; |
630 | 240 | return NULL; |
631 | 240 | } |
632 | 14.7k | size = opus_multistream_encoder_init(NULL, Fs, channels, streams, coupled_streams, mapping, application); |
633 | 14.7k | if (size < 0) |
634 | 0 | { |
635 | 0 | if (error) |
636 | 0 | *error = size; |
637 | 0 | return NULL; |
638 | 0 | } |
639 | 14.7k | st = (OpusMSEncoder *)opus_alloc(size); |
640 | 14.7k | if (st==NULL) |
641 | 0 | { |
642 | 0 | if (error) |
643 | 0 | *error = OPUS_ALLOC_FAIL; |
644 | 0 | return NULL; |
645 | 0 | } |
646 | 14.7k | ret = opus_multistream_encoder_init(st, Fs, channels, streams, coupled_streams, mapping, application); |
647 | 14.7k | if (ret != OPUS_OK) |
648 | 360 | { |
649 | 360 | opus_free(st); |
650 | 360 | st = NULL; |
651 | 360 | } |
652 | 14.7k | if (error) |
653 | 14.7k | *error = ret; |
654 | 14.7k | return st; |
655 | 14.7k | } |
656 | | |
657 | | OpusMSEncoder *opus_multistream_surround_encoder_create( |
658 | | opus_int32 Fs, |
659 | | int channels, |
660 | | int mapping_family, |
661 | | int *streams, |
662 | | int *coupled_streams, |
663 | | unsigned char *mapping, |
664 | | int application, |
665 | | int *error |
666 | | ) |
667 | 25.2k | { |
668 | 25.2k | int ret; |
669 | 25.2k | opus_int32 size; |
670 | 25.2k | OpusMSEncoder *st; |
671 | 25.2k | if ((channels>255) || (channels<1)) |
672 | 46 | { |
673 | 46 | if (error) |
674 | 46 | *error = OPUS_BAD_ARG; |
675 | 46 | return NULL; |
676 | 46 | } |
677 | 25.2k | size = opus_multistream_surround_encoder_init(NULL, Fs, channels, mapping_family, streams, coupled_streams, mapping, application); |
678 | 25.2k | if (size < 0) |
679 | 214 | { |
680 | 214 | if (error) |
681 | 214 | *error = size; |
682 | 214 | return NULL; |
683 | 214 | } |
684 | 24.9k | st = (OpusMSEncoder *)opus_alloc(size); |
685 | 24.9k | if (st==NULL) |
686 | 0 | { |
687 | 0 | if (error) |
688 | 0 | *error = OPUS_ALLOC_FAIL; |
689 | 0 | return NULL; |
690 | 0 | } |
691 | 24.9k | ret = opus_multistream_surround_encoder_init(st, Fs, channels, mapping_family, streams, coupled_streams, mapping, application); |
692 | 24.9k | if (ret != OPUS_OK) |
693 | 0 | { |
694 | 0 | opus_free(st); |
695 | 0 | st = NULL; |
696 | 0 | } |
697 | 24.9k | if (error) |
698 | 24.9k | *error = ret; |
699 | 24.9k | return st; |
700 | 24.9k | } |
701 | | |
702 | | static void surround_rate_allocation( |
703 | | OpusMSEncoder *st, |
704 | | opus_int32 *rate, |
705 | | int frame_size, |
706 | | opus_int32 Fs |
707 | | ) |
708 | 64.0k | { |
709 | 64.0k | int i; |
710 | 64.0k | opus_int32 channel_rate; |
711 | 64.0k | int stream_offset; |
712 | 64.0k | int lfe_offset; |
713 | 64.0k | int coupled_ratio; /* Q8 */ |
714 | 64.0k | int lfe_ratio; /* Q8 */ |
715 | 64.0k | int nb_lfe; |
716 | 64.0k | int nb_uncoupled; |
717 | 64.0k | int nb_coupled; |
718 | 64.0k | int nb_normal; |
719 | 64.0k | opus_int32 channel_offset; |
720 | 64.0k | opus_int32 bitrate; |
721 | 64.0k | int total; |
722 | | |
723 | 64.0k | nb_lfe = (st->lfe_stream!=-1); |
724 | 64.0k | nb_coupled = st->layout.nb_coupled_streams; |
725 | 64.0k | nb_uncoupled = st->layout.nb_streams-nb_coupled-nb_lfe; |
726 | 64.0k | nb_normal = 2*nb_coupled + nb_uncoupled; |
727 | | |
728 | | /* Give each non-LFE channel enough bits per channel for coding band energy. */ |
729 | 64.0k | channel_offset = 40*IMAX(50, Fs/frame_size); |
730 | | |
731 | 64.0k | if (st->bitrate_bps==OPUS_AUTO) |
732 | 64.0k | { |
733 | 64.0k | bitrate = nb_normal*(channel_offset + Fs + 10000) + 8000*nb_lfe; |
734 | 64.0k | } else if (st->bitrate_bps==OPUS_BITRATE_MAX) |
735 | 0 | { |
736 | 0 | bitrate = nb_normal*750000 + nb_lfe*128000; |
737 | 0 | } else { |
738 | 0 | bitrate = st->bitrate_bps; |
739 | 0 | } |
740 | | |
741 | | /* Give LFE some basic stream_channel allocation but never exceed 1/20 of the |
742 | | total rate for the non-energy part to avoid problems at really low rate. */ |
743 | 64.0k | lfe_offset = IMIN(bitrate/20, 3000) + 15*IMAX(50, Fs/frame_size); |
744 | | |
745 | | /* We give each stream (coupled or uncoupled) a starting bitrate. |
746 | | This models the main saving of coupled channels over uncoupled. */ |
747 | 64.0k | stream_offset = (bitrate - channel_offset*nb_normal - lfe_offset*nb_lfe)/nb_normal/2; |
748 | 64.0k | stream_offset = IMAX(0, IMIN(20000, stream_offset)); |
749 | | |
750 | | /* Coupled streams get twice the mono rate after the offset is allocated. */ |
751 | 64.0k | coupled_ratio = 512; |
752 | | /* Should depend on the bitrate, for now we assume LFE gets 1/8 the bits of mono */ |
753 | 64.0k | lfe_ratio = 32; |
754 | | |
755 | 64.0k | total = (nb_uncoupled<<8) /* mono */ |
756 | 64.0k | + coupled_ratio*nb_coupled /* stereo */ |
757 | 64.0k | + nb_lfe*lfe_ratio; |
758 | 64.0k | channel_rate = 256*(opus_int64)(bitrate - lfe_offset*nb_lfe - stream_offset*(nb_coupled+nb_uncoupled) - channel_offset*nb_normal)/total; |
759 | | |
760 | 479k | for (i=0;i<st->layout.nb_streams;i++) |
761 | 415k | { |
762 | 415k | if (i<st->layout.nb_coupled_streams) |
763 | 161k | rate[i] = 2*channel_offset + IMAX(0, stream_offset+(channel_rate*coupled_ratio>>8)); |
764 | 254k | else if (i!=st->lfe_stream) |
765 | 253k | rate[i] = channel_offset + IMAX(0, stream_offset + channel_rate); |
766 | 915 | else |
767 | 915 | rate[i] = IMAX(0, lfe_offset+(channel_rate*lfe_ratio>>8)); |
768 | 415k | } |
769 | 64.0k | } |
770 | | |
771 | | static void ambisonics_rate_allocation( |
772 | | OpusMSEncoder *st, |
773 | | opus_int32 *rate, |
774 | | int frame_size, |
775 | | opus_int32 Fs |
776 | | ) |
777 | 3.61k | { |
778 | 3.61k | int i; |
779 | 3.61k | opus_int32 total_rate; |
780 | 3.61k | opus_int32 per_stream_rate; |
781 | | |
782 | 3.61k | const int nb_channels = st->layout.nb_streams + st->layout.nb_coupled_streams; |
783 | | |
784 | 3.61k | if (st->bitrate_bps==OPUS_AUTO) |
785 | 3.61k | { |
786 | 3.61k | total_rate = (st->layout.nb_coupled_streams + st->layout.nb_streams) * |
787 | 3.61k | (Fs+60*Fs/frame_size) + st->layout.nb_streams * (opus_int32)15000; |
788 | 3.61k | } else if (st->bitrate_bps==OPUS_BITRATE_MAX) |
789 | 0 | { |
790 | 0 | total_rate = nb_channels * 750000; |
791 | 0 | } else |
792 | 0 | { |
793 | 0 | total_rate = st->bitrate_bps; |
794 | 0 | } |
795 | | |
796 | | /* Allocate equal number of bits to Ambisonic (uncoupled) and non-diegetic |
797 | | * (coupled) streams */ |
798 | 3.61k | per_stream_rate = total_rate / st->layout.nb_streams; |
799 | 50.1k | for (i = 0; i < st->layout.nb_streams; i++) |
800 | 46.5k | { |
801 | 46.5k | rate[i] = per_stream_rate; |
802 | 46.5k | } |
803 | 3.61k | } |
804 | | |
805 | | static opus_int32 rate_allocation( |
806 | | OpusMSEncoder *st, |
807 | | opus_int32 *rate, |
808 | | int frame_size |
809 | | ) |
810 | 67.6k | { |
811 | 67.6k | int i; |
812 | 67.6k | opus_int32 rate_sum=0; |
813 | 67.6k | opus_int32 Fs; |
814 | 67.6k | char *ptr; |
815 | | |
816 | 67.6k | ptr = (char*)st + align(sizeof(OpusMSEncoder)); |
817 | 67.6k | opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs)); |
818 | | |
819 | 67.6k | if (st->mapping_type == MAPPING_TYPE_AMBISONICS) { |
820 | 3.61k | ambisonics_rate_allocation(st, rate, frame_size, Fs); |
821 | 3.61k | } else |
822 | 64.0k | { |
823 | 64.0k | surround_rate_allocation(st, rate, frame_size, Fs); |
824 | 64.0k | } |
825 | | |
826 | 529k | for (i=0;i<st->layout.nb_streams;i++) |
827 | 461k | { |
828 | 461k | rate[i] = IMAX(rate[i], 500); |
829 | 461k | rate_sum += rate[i]; |
830 | 461k | } |
831 | 67.6k | return rate_sum; |
832 | 67.6k | } |
833 | | |
834 | | /* Max size in case the encoder decides to return six frames (6 x 20 ms = 120 ms) */ |
835 | | #ifdef ENABLE_QEXT |
836 | | #define MS_FRAME_TMP (6*QEXT_PACKET_SIZE_CAP+12) |
837 | | #else |
838 | | #define MS_FRAME_TMP (6*1275+12) |
839 | | #endif |
840 | | |
841 | | int opus_multistream_encode_native |
842 | | ( |
843 | | OpusMSEncoder *st, |
844 | | opus_copy_channel_in_func copy_channel_in, |
845 | | const void *pcm, |
846 | | int analysis_frame_size, |
847 | | unsigned char *data, |
848 | | opus_int32 max_data_bytes, |
849 | | int lsb_depth, |
850 | | downmix_func downmix, |
851 | | int float_api, |
852 | | void *user_data |
853 | | ) |
854 | 67.6k | { |
855 | 67.6k | opus_int32 Fs; |
856 | 67.6k | int coupled_size; |
857 | 67.6k | int mono_size; |
858 | 67.6k | int s; |
859 | 67.6k | char *ptr; |
860 | 67.6k | int tot_size; |
861 | 67.6k | VARDECL(opus_res, buf); |
862 | 67.6k | VARDECL(celt_glog, bandSMR); |
863 | 67.6k | unsigned char tmp_data[MS_FRAME_TMP]; |
864 | 67.6k | OpusRepacketizer rp; |
865 | 67.6k | opus_int32 vbr; |
866 | 67.6k | const CELTMode *celt_mode=NULL; |
867 | 67.6k | opus_int32 bitrates[256]; |
868 | 67.6k | celt_glog bandLogE[42]; |
869 | 67.6k | opus_val32 *mem = NULL; |
870 | 67.6k | opus_val32 *preemph_mem=NULL; |
871 | 67.6k | int frame_size; |
872 | 67.6k | opus_int32 rate_sum; |
873 | 67.6k | opus_int32 smallest_packet; |
874 | 67.6k | ALLOC_STACK; |
875 | | |
876 | 67.6k | if (st->mapping_type == MAPPING_TYPE_SURROUND) |
877 | 2.44k | { |
878 | 2.44k | preemph_mem = ms_get_preemph_mem(st); |
879 | 2.44k | mem = ms_get_window_mem(st); |
880 | 2.44k | } |
881 | | |
882 | 67.6k | ptr = (char*)st + align(sizeof(OpusMSEncoder)); |
883 | 67.6k | opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs)); |
884 | 67.6k | opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_VBR(&vbr)); |
885 | 67.6k | if (st->application != OPUS_APPLICATION_RESTRICTED_SILK) |
886 | 67.6k | opus_encoder_ctl((OpusEncoder*)ptr, CELT_GET_MODE(&celt_mode)); |
887 | | |
888 | 67.6k | frame_size = frame_size_select(st->application, analysis_frame_size, st->variable_duration, Fs); |
889 | 67.6k | if (frame_size <= 0) |
890 | 0 | { |
891 | 0 | RESTORE_STACK; |
892 | 0 | return OPUS_BAD_ARG; |
893 | 0 | } |
894 | | |
895 | | /* Smallest packet the encoder can produce. */ |
896 | 67.6k | smallest_packet = st->layout.nb_streams*2-1; |
897 | | /* 100 ms needs an extra byte per stream for the ToC. */ |
898 | 67.6k | if (Fs/frame_size == 10) |
899 | 4.43k | smallest_packet += st->layout.nb_streams; |
900 | 67.6k | if (max_data_bytes < smallest_packet) |
901 | 0 | { |
902 | 0 | RESTORE_STACK; |
903 | 0 | return OPUS_BUFFER_TOO_SMALL; |
904 | 0 | } |
905 | 67.6k | ALLOC(buf, 2*frame_size, opus_res); |
906 | 67.6k | coupled_size = opus_encoder_init(NULL, st->Fs, 2, st->application); |
907 | 67.6k | mono_size = opus_encoder_init(NULL, st->Fs, 1, st->application); |
908 | | |
909 | 67.6k | ALLOC(bandSMR, 21*st->layout.nb_channels, celt_glog); |
910 | 67.6k | if (st->mapping_type == MAPPING_TYPE_SURROUND && st->application != OPUS_APPLICATION_RESTRICTED_SILK) |
911 | 2.44k | { |
912 | 2.44k | surround_analysis(celt_mode, pcm, bandSMR, mem, preemph_mem, frame_size, celt_mode->overlap, st->layout.nb_channels, Fs, copy_channel_in, st->arch); |
913 | 2.44k | } |
914 | | |
915 | | /* Compute bitrate allocation between streams (this could be a lot better) */ |
916 | 67.6k | rate_sum = rate_allocation(st, bitrates, frame_size); |
917 | | |
918 | 67.6k | if (!vbr) |
919 | 34.8k | { |
920 | 34.8k | if (st->bitrate_bps == OPUS_AUTO) |
921 | 34.8k | { |
922 | 34.8k | max_data_bytes = IMIN(max_data_bytes, (bitrate_to_bits(rate_sum, Fs, frame_size)+4)/8); |
923 | 34.8k | } else if (st->bitrate_bps != OPUS_BITRATE_MAX) |
924 | 0 | { |
925 | 0 | max_data_bytes = IMIN(max_data_bytes, IMAX(smallest_packet, |
926 | 0 | (bitrate_to_bits(st->bitrate_bps, Fs, frame_size)+4)/8)); |
927 | 0 | } |
928 | 34.8k | } |
929 | 67.6k | ptr = (char*)st + align(sizeof(OpusMSEncoder)); |
930 | 529k | for (s=0;s<st->layout.nb_streams;s++) |
931 | 461k | { |
932 | 461k | OpusEncoder *enc; |
933 | 461k | enc = (OpusEncoder*)ptr; |
934 | 461k | if (s < st->layout.nb_coupled_streams) |
935 | 161k | ptr += align(coupled_size); |
936 | 299k | else |
937 | 299k | ptr += align(mono_size); |
938 | 461k | opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrates[s])); |
939 | 461k | if (st->mapping_type == MAPPING_TYPE_SURROUND) |
940 | 7.15k | { |
941 | 7.15k | opus_int32 equiv_rate; |
942 | 7.15k | equiv_rate = st->bitrate_bps; |
943 | 7.15k | if (frame_size*50 < Fs) |
944 | 4.35k | equiv_rate -= 60*(Fs/frame_size - 50)*st->layout.nb_channels; |
945 | 7.15k | if (equiv_rate > 10000*st->layout.nb_channels) |
946 | 0 | opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND)); |
947 | 7.15k | else if (equiv_rate > 7000*st->layout.nb_channels) |
948 | 0 | opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_SUPERWIDEBAND)); |
949 | 7.15k | else if (equiv_rate > 5000*st->layout.nb_channels) |
950 | 0 | opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_WIDEBAND)); |
951 | 7.15k | else |
952 | 7.15k | opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND)); |
953 | 7.15k | if (s < st->layout.nb_coupled_streams) |
954 | 4.65k | { |
955 | | /* To preserve the spatial image, force stereo CELT on coupled streams */ |
956 | 4.65k | opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY)); |
957 | 4.65k | opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(2)); |
958 | 4.65k | } |
959 | 7.15k | } |
960 | 454k | else if (st->mapping_type == MAPPING_TYPE_AMBISONICS) { |
961 | 46.5k | opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY)); |
962 | 46.5k | } |
963 | 461k | } |
964 | | |
965 | 67.6k | ptr = (char*)st + align(sizeof(OpusMSEncoder)); |
966 | | /* Counting ToC */ |
967 | 67.6k | tot_size = 0; |
968 | 529k | for (s=0;s<st->layout.nb_streams;s++) |
969 | 461k | { |
970 | 461k | OpusEncoder *enc; |
971 | 461k | int len; |
972 | 461k | int curr_max; |
973 | 461k | int c1, c2; |
974 | 461k | int ret; |
975 | | |
976 | 461k | opus_repacketizer_init(&rp); |
977 | 461k | enc = (OpusEncoder*)ptr; |
978 | 461k | if (s < st->layout.nb_coupled_streams) |
979 | 161k | { |
980 | 161k | int i; |
981 | 161k | int left, right; |
982 | 161k | left = get_left_channel(&st->layout, s, -1); |
983 | 161k | right = get_right_channel(&st->layout, s, -1); |
984 | 161k | (*copy_channel_in)(buf, 2, |
985 | 161k | pcm, st->layout.nb_channels, left, frame_size, user_data); |
986 | 161k | (*copy_channel_in)(buf+1, 2, |
987 | 161k | pcm, st->layout.nb_channels, right, frame_size, user_data); |
988 | 161k | ptr += align(coupled_size); |
989 | 161k | if (st->mapping_type == MAPPING_TYPE_SURROUND && st->application != OPUS_APPLICATION_RESTRICTED_SILK) |
990 | 4.65k | { |
991 | 102k | for (i=0;i<21;i++) |
992 | 97.8k | { |
993 | 97.8k | bandLogE[i] = bandSMR[21*left+i]; |
994 | 97.8k | bandLogE[21+i] = bandSMR[21*right+i]; |
995 | 97.8k | } |
996 | 4.65k | } |
997 | 161k | c1 = left; |
998 | 161k | c2 = right; |
999 | 299k | } else { |
1000 | 299k | int i; |
1001 | 299k | int chan = get_mono_channel(&st->layout, s, -1); |
1002 | 299k | (*copy_channel_in)(buf, 1, |
1003 | 299k | pcm, st->layout.nb_channels, chan, frame_size, user_data); |
1004 | 299k | ptr += align(mono_size); |
1005 | 299k | if (st->mapping_type == MAPPING_TYPE_SURROUND && st->application != OPUS_APPLICATION_RESTRICTED_SILK) |
1006 | 2.49k | { |
1007 | 54.9k | for (i=0;i<21;i++) |
1008 | 52.4k | bandLogE[i] = bandSMR[21*chan+i]; |
1009 | 2.49k | } |
1010 | 299k | c1 = chan; |
1011 | 299k | c2 = -1; |
1012 | 299k | } |
1013 | 461k | if (st->mapping_type == MAPPING_TYPE_SURROUND && st->application != OPUS_APPLICATION_RESTRICTED_SILK) |
1014 | 7.15k | opus_encoder_ctl(enc, OPUS_SET_ENERGY_MASK(bandLogE)); |
1015 | | /* number of bytes left (+Toc) */ |
1016 | 461k | curr_max = max_data_bytes - tot_size; |
1017 | | /* Reserve one byte for the last stream and two for the others */ |
1018 | 461k | curr_max -= IMAX(0,2*(st->layout.nb_streams-s-1)-1); |
1019 | | /* For 100 ms, reserve an extra byte per stream for the ToC */ |
1020 | 461k | if (Fs/frame_size == 10) |
1021 | 26.5k | curr_max -= st->layout.nb_streams-s-1; |
1022 | 461k | curr_max = IMIN(curr_max,MS_FRAME_TMP); |
1023 | | /* Repacketizer will add one or two bytes for self-delimited frames */ |
1024 | 461k | if (s != st->layout.nb_streams-1) curr_max -= curr_max>253 ? 2 : 1; |
1025 | 461k | if (!vbr && s == st->layout.nb_streams-1) |
1026 | 34.8k | opus_encoder_ctl(enc, OPUS_SET_BITRATE(bits_to_bitrate(curr_max*8, Fs, frame_size))); |
1027 | 461k | len = opus_encode_native(enc, buf, frame_size, tmp_data, curr_max, lsb_depth, |
1028 | 461k | pcm, analysis_frame_size, c1, c2, st->layout.nb_channels, downmix, float_api); |
1029 | 461k | if (len<0) |
1030 | 0 | { |
1031 | 0 | RESTORE_STACK; |
1032 | 0 | return len; |
1033 | 0 | } |
1034 | | /* We need to use the repacketizer to add the self-delimiting lengths |
1035 | | while taking into account the fact that the encoder can now return |
1036 | | more than one frame at a time (e.g. 60 ms CELT-only) */ |
1037 | 461k | ret = opus_repacketizer_cat(&rp, tmp_data, len); |
1038 | | /* If the opus_repacketizer_cat() fails, then something's seriously wrong |
1039 | | with the encoder. */ |
1040 | 461k | if (ret != OPUS_OK) |
1041 | 0 | { |
1042 | 0 | RESTORE_STACK; |
1043 | 0 | return OPUS_INTERNAL_ERROR; |
1044 | 0 | } |
1045 | 461k | len = opus_repacketizer_out_range_impl(&rp, 0, opus_repacketizer_get_nb_frames(&rp), |
1046 | 461k | data, max_data_bytes-tot_size, s != st->layout.nb_streams-1, !vbr && s == st->layout.nb_streams-1, NULL, 0); |
1047 | 461k | data += len; |
1048 | 461k | tot_size += len; |
1049 | 461k | } |
1050 | | /*printf("\n");*/ |
1051 | 67.6k | RESTORE_STACK; |
1052 | 67.6k | return tot_size; |
1053 | 67.6k | } |
1054 | | |
1055 | | #if !defined(DISABLE_FLOAT_API) |
1056 | | static void opus_copy_channel_in_float( |
1057 | | opus_res *dst, |
1058 | | int dst_stride, |
1059 | | const void *src, |
1060 | | int src_stride, |
1061 | | int src_channel, |
1062 | | int frame_size, |
1063 | | void *user_data |
1064 | | ) |
1065 | 0 | { |
1066 | 0 | const float *float_src; |
1067 | 0 | opus_int32 i; |
1068 | 0 | (void)user_data; |
1069 | 0 | float_src = (const float *)src; |
1070 | 0 | for (i=0;i<frame_size;i++) |
1071 | 0 | dst[i*dst_stride] = FLOAT2RES(float_src[i*src_stride+src_channel]); |
1072 | 0 | } |
1073 | | #endif |
1074 | | |
1075 | | static void opus_copy_channel_in_short( |
1076 | | opus_res *dst, |
1077 | | int dst_stride, |
1078 | | const void *src, |
1079 | | int src_stride, |
1080 | | int src_channel, |
1081 | | int frame_size, |
1082 | | void *user_data |
1083 | | ) |
1084 | 722k | { |
1085 | 722k | const opus_int16 *short_src; |
1086 | 722k | opus_int32 i; |
1087 | 722k | (void)user_data; |
1088 | 722k | short_src = (const opus_int16 *)src; |
1089 | 222M | for (i=0;i<frame_size;i++) |
1090 | 221M | dst[i*dst_stride] = INT16TORES(short_src[i*src_stride+src_channel]); |
1091 | 722k | } opus_multistream_encoder.c:opus_copy_channel_in_short Line | Count | Source | 1084 | 361k | { | 1085 | 361k | const opus_int16 *short_src; | 1086 | 361k | opus_int32 i; | 1087 | 361k | (void)user_data; | 1088 | 361k | short_src = (const opus_int16 *)src; | 1089 | 111M | for (i=0;i<frame_size;i++) | 1090 | 110M | dst[i*dst_stride] = INT16TORES(short_src[i*src_stride+src_channel]); | 1091 | 361k | } |
opus_multistream_encoder.c:opus_copy_channel_in_short Line | Count | Source | 1084 | 361k | { | 1085 | 361k | const opus_int16 *short_src; | 1086 | 361k | opus_int32 i; | 1087 | 361k | (void)user_data; | 1088 | 361k | short_src = (const opus_int16 *)src; | 1089 | 111M | for (i=0;i<frame_size;i++) | 1090 | 110M | dst[i*dst_stride] = INT16TORES(short_src[i*src_stride+src_channel]); | 1091 | 361k | } |
|
1092 | | |
1093 | | static void opus_copy_channel_in_int24( |
1094 | | opus_res *dst, |
1095 | | int dst_stride, |
1096 | | const void *src, |
1097 | | int src_stride, |
1098 | | int src_channel, |
1099 | | int frame_size, |
1100 | | void *user_data |
1101 | | ) |
1102 | 0 | { |
1103 | 0 | const opus_int32 *short_src; |
1104 | 0 | opus_int32 i; |
1105 | 0 | (void)user_data; |
1106 | 0 | short_src = (const opus_int32 *)src; |
1107 | 0 | for (i=0;i<frame_size;i++) |
1108 | 0 | dst[i*dst_stride] = INT24TORES(short_src[i*src_stride+src_channel]); |
1109 | 0 | } |
1110 | | |
1111 | | int opus_multistream_encode( |
1112 | | OpusMSEncoder *st, |
1113 | | const opus_int16 *pcm, |
1114 | | int frame_size, |
1115 | | unsigned char *data, |
1116 | | opus_int32 max_data_bytes |
1117 | | ) |
1118 | 38.2k | { |
1119 | 38.2k | return opus_multistream_encode_native(st, opus_copy_channel_in_short, |
1120 | 38.2k | pcm, frame_size, data, max_data_bytes, 16, downmix_int, 0, NULL); |
1121 | 38.2k | } |
1122 | | |
1123 | | int opus_multistream_encode24( |
1124 | | OpusMSEncoder *st, |
1125 | | const opus_int32 *pcm, |
1126 | | int frame_size, |
1127 | | unsigned char *data, |
1128 | | opus_int32 max_data_bytes |
1129 | | ) |
1130 | 0 | { |
1131 | 0 | return opus_multistream_encode_native(st, opus_copy_channel_in_int24, |
1132 | 0 | pcm, frame_size, data, max_data_bytes, MAX_ENCODING_DEPTH, downmix_int24, 0, NULL); |
1133 | 0 | } |
1134 | | |
1135 | | #ifndef DISABLE_FLOAT_API |
1136 | | int opus_multistream_encode_float( |
1137 | | OpusMSEncoder *st, |
1138 | | const float *pcm, |
1139 | | int frame_size, |
1140 | | unsigned char *data, |
1141 | | opus_int32 max_data_bytes |
1142 | | ) |
1143 | 0 | { |
1144 | 0 | return opus_multistream_encode_native(st, opus_copy_channel_in_float, |
1145 | 0 | pcm, frame_size, data, max_data_bytes, MAX_ENCODING_DEPTH, downmix_float, 1, NULL); |
1146 | 0 | } |
1147 | | #endif |
1148 | | |
1149 | | int opus_multistream_encoder_ctl_va_list(OpusMSEncoder *st, int request, |
1150 | | va_list ap) |
1151 | 834k | { |
1152 | 834k | int coupled_size, mono_size; |
1153 | 834k | char *ptr; |
1154 | 834k | int ret = OPUS_OK; |
1155 | | |
1156 | 834k | coupled_size = opus_encoder_init(NULL, st->Fs, 2, st->application); |
1157 | 834k | mono_size = opus_encoder_init(NULL, st->Fs, 1, st->application); |
1158 | 834k | ptr = (char*)st + align(sizeof(OpusMSEncoder)); |
1159 | 834k | switch (request) |
1160 | 834k | { |
1161 | 0 | case OPUS_SET_BITRATE_REQUEST: |
1162 | 0 | { |
1163 | 0 | opus_int32 value = va_arg(ap, opus_int32); |
1164 | 0 | if (value != OPUS_AUTO && value != OPUS_BITRATE_MAX) |
1165 | 0 | { |
1166 | 0 | if (value <= 0) |
1167 | 0 | goto bad_arg; |
1168 | 0 | value = IMIN(750000*st->layout.nb_channels, IMAX(500*st->layout.nb_channels, value)); |
1169 | 0 | } |
1170 | 0 | st->bitrate_bps = value; |
1171 | 0 | } |
1172 | 0 | break; |
1173 | 0 | case OPUS_GET_BITRATE_REQUEST: |
1174 | 0 | { |
1175 | 0 | int s; |
1176 | 0 | opus_int32 *value = va_arg(ap, opus_int32*); |
1177 | 0 | if (!value) |
1178 | 0 | { |
1179 | 0 | goto bad_arg; |
1180 | 0 | } |
1181 | 0 | *value = 0; |
1182 | 0 | for (s=0;s<st->layout.nb_streams;s++) |
1183 | 0 | { |
1184 | 0 | opus_int32 rate; |
1185 | 0 | OpusEncoder *enc; |
1186 | 0 | enc = (OpusEncoder*)ptr; |
1187 | 0 | if (s < st->layout.nb_coupled_streams) |
1188 | 0 | ptr += align(coupled_size); |
1189 | 0 | else |
1190 | 0 | ptr += align(mono_size); |
1191 | 0 | opus_encoder_ctl(enc, request, &rate); |
1192 | 0 | *value += rate; |
1193 | 0 | } |
1194 | 0 | } |
1195 | 0 | break; |
1196 | 0 | case OPUS_GET_LSB_DEPTH_REQUEST: |
1197 | 0 | case OPUS_GET_VBR_REQUEST: |
1198 | 0 | case OPUS_GET_APPLICATION_REQUEST: |
1199 | 0 | case OPUS_GET_BANDWIDTH_REQUEST: |
1200 | 0 | case OPUS_GET_COMPLEXITY_REQUEST: |
1201 | 0 | case OPUS_GET_PACKET_LOSS_PERC_REQUEST: |
1202 | 0 | case OPUS_GET_DTX_REQUEST: |
1203 | 0 | case OPUS_GET_VOICE_RATIO_REQUEST: |
1204 | 0 | case OPUS_GET_VBR_CONSTRAINT_REQUEST: |
1205 | 0 | case OPUS_GET_SIGNAL_REQUEST: |
1206 | 0 | case OPUS_GET_LOOKAHEAD_REQUEST: |
1207 | 0 | case OPUS_GET_SAMPLE_RATE_REQUEST: |
1208 | 0 | case OPUS_GET_INBAND_FEC_REQUEST: |
1209 | 0 | case OPUS_GET_FORCE_CHANNELS_REQUEST: |
1210 | 0 | case OPUS_GET_PREDICTION_DISABLED_REQUEST: |
1211 | 0 | case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST: |
1212 | 0 | case OPUS_GET_QEXT_REQUEST: |
1213 | 0 | { |
1214 | 0 | OpusEncoder *enc; |
1215 | | /* For int32* GET params, just query the first stream */ |
1216 | 0 | opus_int32 *value = va_arg(ap, opus_int32*); |
1217 | 0 | enc = (OpusEncoder*)ptr; |
1218 | 0 | ret = opus_encoder_ctl(enc, request, value); |
1219 | 0 | } |
1220 | 0 | break; |
1221 | 0 | case OPUS_GET_FINAL_RANGE_REQUEST: |
1222 | 0 | { |
1223 | 0 | int s; |
1224 | 0 | opus_uint32 *value = va_arg(ap, opus_uint32*); |
1225 | 0 | opus_uint32 tmp; |
1226 | 0 | if (!value) |
1227 | 0 | { |
1228 | 0 | goto bad_arg; |
1229 | 0 | } |
1230 | 0 | *value=0; |
1231 | 0 | for (s=0;s<st->layout.nb_streams;s++) |
1232 | 0 | { |
1233 | 0 | OpusEncoder *enc; |
1234 | 0 | enc = (OpusEncoder*)ptr; |
1235 | 0 | if (s < st->layout.nb_coupled_streams) |
1236 | 0 | ptr += align(coupled_size); |
1237 | 0 | else |
1238 | 0 | ptr += align(mono_size); |
1239 | 0 | ret = opus_encoder_ctl(enc, request, &tmp); |
1240 | 0 | if (ret != OPUS_OK) break; |
1241 | 0 | *value ^= tmp; |
1242 | 0 | } |
1243 | 0 | } |
1244 | 0 | break; |
1245 | 69.5k | case OPUS_SET_LSB_DEPTH_REQUEST: |
1246 | 139k | case OPUS_SET_COMPLEXITY_REQUEST: |
1247 | 208k | case OPUS_SET_VBR_REQUEST: |
1248 | 278k | case OPUS_SET_VBR_CONSTRAINT_REQUEST: |
1249 | 347k | case OPUS_SET_MAX_BANDWIDTH_REQUEST: |
1250 | 347k | case OPUS_SET_BANDWIDTH_REQUEST: |
1251 | 417k | case OPUS_SET_SIGNAL_REQUEST: |
1252 | 417k | case OPUS_SET_APPLICATION_REQUEST: |
1253 | 487k | case OPUS_SET_INBAND_FEC_REQUEST: |
1254 | 556k | case OPUS_SET_PACKET_LOSS_PERC_REQUEST: |
1255 | 626k | case OPUS_SET_DTX_REQUEST: |
1256 | 626k | case OPUS_SET_FORCE_MODE_REQUEST: |
1257 | 695k | case OPUS_SET_FORCE_CHANNELS_REQUEST: |
1258 | 765k | case OPUS_SET_PREDICTION_DISABLED_REQUEST: |
1259 | 834k | case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST: |
1260 | 834k | case OPUS_SET_QEXT_REQUEST: |
1261 | 834k | { |
1262 | 834k | int s; |
1263 | | /* This works for int32 params */ |
1264 | 834k | opus_int32 value = va_arg(ap, opus_int32); |
1265 | 7.03M | for (s=0;s<st->layout.nb_streams;s++) |
1266 | 6.20M | { |
1267 | 6.20M | OpusEncoder *enc; |
1268 | | |
1269 | 6.20M | enc = (OpusEncoder*)ptr; |
1270 | 6.20M | if (s < st->layout.nb_coupled_streams) |
1271 | 2.00M | ptr += align(coupled_size); |
1272 | 4.20M | else |
1273 | 4.20M | ptr += align(mono_size); |
1274 | 6.20M | ret = opus_encoder_ctl(enc, request, value); |
1275 | 6.20M | if (ret != OPUS_OK) |
1276 | 7.47k | break; |
1277 | 6.20M | } |
1278 | 834k | } |
1279 | 834k | break; |
1280 | 0 | case OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST: |
1281 | 0 | { |
1282 | 0 | int s; |
1283 | 0 | opus_int32 stream_id; |
1284 | 0 | OpusEncoder **value; |
1285 | 0 | stream_id = va_arg(ap, opus_int32); |
1286 | 0 | if (stream_id<0 || stream_id >= st->layout.nb_streams) |
1287 | 0 | goto bad_arg; |
1288 | 0 | value = va_arg(ap, OpusEncoder**); |
1289 | 0 | if (!value) |
1290 | 0 | { |
1291 | 0 | goto bad_arg; |
1292 | 0 | } |
1293 | 0 | for (s=0;s<stream_id;s++) |
1294 | 0 | { |
1295 | 0 | if (s < st->layout.nb_coupled_streams) |
1296 | 0 | ptr += align(coupled_size); |
1297 | 0 | else |
1298 | 0 | ptr += align(mono_size); |
1299 | 0 | } |
1300 | 0 | *value = (OpusEncoder*)ptr; |
1301 | 0 | } |
1302 | 0 | break; |
1303 | 0 | case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST: |
1304 | 0 | { |
1305 | 0 | opus_int32 value = va_arg(ap, opus_int32); |
1306 | 0 | st->variable_duration = value; |
1307 | 0 | } |
1308 | 0 | break; |
1309 | 0 | case OPUS_GET_EXPERT_FRAME_DURATION_REQUEST: |
1310 | 0 | { |
1311 | 0 | opus_int32 *value = va_arg(ap, opus_int32*); |
1312 | 0 | if (!value) |
1313 | 0 | { |
1314 | 0 | goto bad_arg; |
1315 | 0 | } |
1316 | 0 | *value = st->variable_duration; |
1317 | 0 | } |
1318 | 0 | break; |
1319 | 0 | case OPUS_RESET_STATE: |
1320 | 0 | { |
1321 | 0 | int s; |
1322 | 0 | if (st->mapping_type == MAPPING_TYPE_SURROUND) |
1323 | 0 | { |
1324 | 0 | OPUS_CLEAR(ms_get_preemph_mem(st), st->layout.nb_channels); |
1325 | 0 | OPUS_CLEAR(ms_get_window_mem(st), st->layout.nb_channels*MAX_OVERLAP); |
1326 | 0 | } |
1327 | 0 | for (s=0;s<st->layout.nb_streams;s++) |
1328 | 0 | { |
1329 | 0 | OpusEncoder *enc; |
1330 | 0 | enc = (OpusEncoder*)ptr; |
1331 | 0 | if (s < st->layout.nb_coupled_streams) |
1332 | 0 | ptr += align(coupled_size); |
1333 | 0 | else |
1334 | 0 | ptr += align(mono_size); |
1335 | 0 | ret = opus_encoder_ctl(enc, OPUS_RESET_STATE); |
1336 | 0 | if (ret != OPUS_OK) |
1337 | 0 | break; |
1338 | 0 | } |
1339 | 0 | } |
1340 | 0 | break; |
1341 | 0 | default: |
1342 | 0 | ret = OPUS_UNIMPLEMENTED; |
1343 | 0 | break; |
1344 | 834k | } |
1345 | 834k | return ret; |
1346 | 0 | bad_arg: |
1347 | 0 | return OPUS_BAD_ARG; |
1348 | 834k | } |
1349 | | |
1350 | | int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...) |
1351 | 472k | { |
1352 | 472k | int ret; |
1353 | 472k | va_list ap; |
1354 | 472k | va_start(ap, request); |
1355 | 472k | ret = opus_multistream_encoder_ctl_va_list(st, request, ap); |
1356 | 472k | va_end(ap); |
1357 | 472k | return ret; |
1358 | 472k | } |
1359 | | |
1360 | | void opus_multistream_encoder_destroy(OpusMSEncoder *st) |
1361 | 40.2k | { |
1362 | 40.2k | opus_free(st); |
1363 | 40.2k | } |