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