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
ms_get_preemph_mem(OpusMSEncoder * st)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
ms_get_window_mem(OpusMSEncoder * st)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
validate_ambisonics(int nb_channels,int * nb_streams,int * nb_coupled_streams)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
validate_encoder_layout(const ChannelLayout * layout)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
channel_pos(int channels,int pos[8])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) */
logSum(opus_val16 a,opus_val16 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
logSum(opus_val16 a,opus_val16 b)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
surround_analysis(const CELTMode * celt_mode,const void * pcm,opus_val16 * bandLogE,opus_val32 * mem,opus_val32 * preemph_mem,int len,int overlap,int channels,int rate,opus_copy_channel_in_func copy_channel_in,int arch)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
opus_multistream_encoder_get_size(int nb_streams,int nb_coupled_streams)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
opus_multistream_surround_encoder_get_size(int channels,int mapping_family)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
opus_multistream_encoder_init_impl(OpusMSEncoder * st,opus_int32 Fs,int channels,int streams,int coupled_streams,const unsigned char * mapping,int application,MappingType mapping_type)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
opus_multistream_encoder_init(OpusMSEncoder * st,opus_int32 Fs,int channels,int streams,int coupled_streams,const unsigned char * mapping,int application)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
opus_multistream_surround_encoder_init(OpusMSEncoder * st,opus_int32 Fs,int channels,int mapping_family,int * streams,int * coupled_streams,unsigned char * mapping,int application)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
opus_multistream_encoder_create(opus_int32 Fs,int channels,int streams,int coupled_streams,const unsigned char * mapping,int application,int * error)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
opus_multistream_surround_encoder_create(opus_int32 Fs,int channels,int mapping_family,int * streams,int * coupled_streams,unsigned char * mapping,int application,int * error)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
surround_rate_allocation(OpusMSEncoder * st,opus_int32 * rate,int frame_size,opus_int32 Fs)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
ambisonics_rate_allocation(OpusMSEncoder * st,opus_int32 * rate,int frame_size,opus_int32 Fs)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
rate_allocation(OpusMSEncoder * st,opus_int32 * rate,int frame_size)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)
opus_multistream_encode_native(OpusMSEncoder * st,opus_copy_channel_in_func copy_channel_in,const void * pcm,int analysis_frame_size,unsigned char * data,opus_int32 max_data_bytes,int lsb_depth,downmix_func downmix,int float_api,void * user_data)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)
opus_copy_channel_in_float(opus_val16 * dst,int dst_stride,const void * src,int src_stride,int src_channel,int frame_size,void * user_data)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
opus_copy_channel_in_short(opus_val16 * dst,int dst_stride,const void * src,int src_stride,int src_channel,int frame_size,void * user_data)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
opus_multistream_encode(OpusMSEncoder * st,const opus_val16 * pcm,int frame_size,unsigned char * data,opus_int32 max_data_bytes)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
opus_multistream_encode_float(OpusMSEncoder * st,const float * pcm,int frame_size,unsigned char * data,opus_int32 max_data_bytes)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
opus_multistream_encode_float(OpusMSEncoder * st,const opus_val16 * pcm,int frame_size,unsigned char * data,opus_int32 max_data_bytes)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
opus_multistream_encode(OpusMSEncoder * st,const opus_int16 * pcm,int frame_size,unsigned char * data,opus_int32 max_data_bytes)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
opus_multistream_encoder_ctl_va_list(OpusMSEncoder * st,int request,va_list ap)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 goto 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
opus_multistream_encoder_ctl(OpusMSEncoder * st,int request,...)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
opus_multistream_encoder_destroy(OpusMSEncoder * st)1325 void opus_multistream_encoder_destroy(OpusMSEncoder *st)
1326 {
1327 opus_free(st);
1328 }
1329