• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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        (streams+coupled_streams>channels))
448       return OPUS_BAD_ARG;
449 
450    st->arch = opus_select_arch();
451    st->layout.nb_channels = channels;
452    st->layout.nb_streams = streams;
453    st->layout.nb_coupled_streams = coupled_streams;
454    if (mapping_type != MAPPING_TYPE_SURROUND)
455       st->lfe_stream = -1;
456    st->bitrate_bps = OPUS_AUTO;
457    st->application = application;
458    st->variable_duration = OPUS_FRAMESIZE_ARG;
459    for (i=0;i<st->layout.nb_channels;i++)
460       st->layout.mapping[i] = mapping[i];
461    if (!validate_layout(&st->layout))
462       return OPUS_BAD_ARG;
463    if (!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        (streams+coupled_streams>channels))
600    {
601       if (error)
602          *error = OPUS_BAD_ARG;
603       return NULL;
604    }
605    st = (OpusMSEncoder *)opus_alloc(opus_multistream_encoder_get_size(streams, coupled_streams));
606    if (st==NULL)
607    {
608       if (error)
609          *error = OPUS_ALLOC_FAIL;
610       return NULL;
611    }
612    ret = opus_multistream_encoder_init(st, Fs, channels, streams, coupled_streams, mapping, application);
613    if (ret != OPUS_OK)
614    {
615       opus_free(st);
616       st = NULL;
617    }
618    if (error)
619       *error = ret;
620    return st;
621 }
622 
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)623 OpusMSEncoder *opus_multistream_surround_encoder_create(
624       opus_int32 Fs,
625       int channels,
626       int mapping_family,
627       int *streams,
628       int *coupled_streams,
629       unsigned char *mapping,
630       int application,
631       int *error
632 )
633 {
634    int ret;
635    opus_int32 size;
636    OpusMSEncoder *st;
637    if ((channels>255) || (channels<1))
638    {
639       if (error)
640          *error = OPUS_BAD_ARG;
641       return NULL;
642    }
643    size = opus_multistream_surround_encoder_get_size(channels, mapping_family);
644    if (!size)
645    {
646       if (error)
647          *error = OPUS_UNIMPLEMENTED;
648       return NULL;
649    }
650    st = (OpusMSEncoder *)opus_alloc(size);
651    if (st==NULL)
652    {
653       if (error)
654          *error = OPUS_ALLOC_FAIL;
655       return NULL;
656    }
657    ret = opus_multistream_surround_encoder_init(st, Fs, channels, mapping_family, streams, coupled_streams, mapping, application);
658    if (ret != OPUS_OK)
659    {
660       opus_free(st);
661       st = NULL;
662    }
663    if (error)
664       *error = ret;
665    return st;
666 }
667 
surround_rate_allocation(OpusMSEncoder * st,opus_int32 * rate,int frame_size,opus_int32 Fs)668 static void surround_rate_allocation(
669       OpusMSEncoder *st,
670       opus_int32 *rate,
671       int frame_size,
672       opus_int32 Fs
673       )
674 {
675    int i;
676    opus_int32 channel_rate;
677    int stream_offset;
678    int lfe_offset;
679    int coupled_ratio; /* Q8 */
680    int lfe_ratio;     /* Q8 */
681    int nb_lfe;
682    int nb_uncoupled;
683    int nb_coupled;
684    int nb_normal;
685    opus_int32 channel_offset;
686    opus_int32 bitrate;
687    int total;
688 
689    nb_lfe = (st->lfe_stream!=-1);
690    nb_coupled = st->layout.nb_coupled_streams;
691    nb_uncoupled = st->layout.nb_streams-nb_coupled-nb_lfe;
692    nb_normal = 2*nb_coupled + nb_uncoupled;
693 
694    /* Give each non-LFE channel enough bits per channel for coding band energy. */
695    channel_offset = 40*IMAX(50, Fs/frame_size);
696 
697    if (st->bitrate_bps==OPUS_AUTO)
698    {
699       bitrate = nb_normal*(channel_offset + Fs + 10000) + 8000*nb_lfe;
700    } else if (st->bitrate_bps==OPUS_BITRATE_MAX)
701    {
702       bitrate = nb_normal*300000 + nb_lfe*128000;
703    } else {
704       bitrate = st->bitrate_bps;
705    }
706 
707    /* Give LFE some basic stream_channel allocation but never exceed 1/20 of the
708       total rate for the non-energy part to avoid problems at really low rate. */
709    lfe_offset = IMIN(bitrate/20, 3000) + 15*IMAX(50, Fs/frame_size);
710 
711    /* We give each stream (coupled or uncoupled) a starting bitrate.
712       This models the main saving of coupled channels over uncoupled. */
713    stream_offset = (bitrate - channel_offset*nb_normal - lfe_offset*nb_lfe)/nb_normal/2;
714    stream_offset = IMAX(0, IMIN(20000, stream_offset));
715 
716    /* Coupled streams get twice the mono rate after the offset is allocated. */
717    coupled_ratio = 512;
718    /* Should depend on the bitrate, for now we assume LFE gets 1/8 the bits of mono */
719    lfe_ratio = 32;
720 
721    total = (nb_uncoupled<<8)         /* mono */
722          + coupled_ratio*nb_coupled /* stereo */
723          + nb_lfe*lfe_ratio;
724    channel_rate = 256*(opus_int64)(bitrate - lfe_offset*nb_lfe - stream_offset*(nb_coupled+nb_uncoupled) - channel_offset*nb_normal)/total;
725 
726    for (i=0;i<st->layout.nb_streams;i++)
727    {
728       if (i<st->layout.nb_coupled_streams)
729          rate[i] = 2*channel_offset + IMAX(0, stream_offset+(channel_rate*coupled_ratio>>8));
730       else if (i!=st->lfe_stream)
731          rate[i] = channel_offset + IMAX(0, stream_offset + channel_rate);
732       else
733          rate[i] = IMAX(0, lfe_offset+(channel_rate*lfe_ratio>>8));
734    }
735 }
736 
ambisonics_rate_allocation(OpusMSEncoder * st,opus_int32 * rate,int frame_size,opus_int32 Fs)737 static void ambisonics_rate_allocation(
738       OpusMSEncoder *st,
739       opus_int32 *rate,
740       int frame_size,
741       opus_int32 Fs
742       )
743 {
744    int i;
745    opus_int32 total_rate;
746    opus_int32 per_stream_rate;
747 
748    const int nb_channels = st->layout.nb_streams + st->layout.nb_coupled_streams;
749 
750    if (st->bitrate_bps==OPUS_AUTO)
751    {
752       total_rate = (st->layout.nb_coupled_streams + st->layout.nb_streams) *
753          (Fs+60*Fs/frame_size) + st->layout.nb_streams * (opus_int32)15000;
754    } else if (st->bitrate_bps==OPUS_BITRATE_MAX)
755    {
756       total_rate = nb_channels * 320000;
757    } else
758    {
759       total_rate = st->bitrate_bps;
760    }
761 
762    /* Allocate equal number of bits to Ambisonic (uncoupled) and non-diegetic
763     * (coupled) streams */
764    per_stream_rate = total_rate / st->layout.nb_streams;
765    for (i = 0; i < st->layout.nb_streams; i++)
766    {
767      rate[i] = per_stream_rate;
768    }
769 }
770 
rate_allocation(OpusMSEncoder * st,opus_int32 * rate,int frame_size)771 static opus_int32 rate_allocation(
772       OpusMSEncoder *st,
773       opus_int32 *rate,
774       int frame_size
775       )
776 {
777    int i;
778    opus_int32 rate_sum=0;
779    opus_int32 Fs;
780    char *ptr;
781 
782    ptr = (char*)st + align(sizeof(OpusMSEncoder));
783    opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
784 
785    if (st->mapping_type == MAPPING_TYPE_AMBISONICS) {
786      ambisonics_rate_allocation(st, rate, frame_size, Fs);
787    } else
788    {
789      surround_rate_allocation(st, rate, frame_size, Fs);
790    }
791 
792    for (i=0;i<st->layout.nb_streams;i++)
793    {
794       rate[i] = IMAX(rate[i], 500);
795       rate_sum += rate[i];
796    }
797    return rate_sum;
798 }
799 
800 /* Max size in case the encoder decides to return six frames (6 x 20 ms = 120 ms) */
801 #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)802 int opus_multistream_encode_native
803 (
804     OpusMSEncoder *st,
805     opus_copy_channel_in_func copy_channel_in,
806     const void *pcm,
807     int analysis_frame_size,
808     unsigned char *data,
809     opus_int32 max_data_bytes,
810     int lsb_depth,
811     downmix_func downmix,
812     int float_api,
813     void *user_data
814 )
815 {
816    opus_int32 Fs;
817    int coupled_size;
818    int mono_size;
819    int s;
820    char *ptr;
821    int tot_size;
822    VARDECL(opus_val16, buf);
823    VARDECL(opus_val16, bandSMR);
824    unsigned char tmp_data[MS_FRAME_TMP];
825    OpusRepacketizer rp;
826    opus_int32 vbr;
827    const CELTMode *celt_mode;
828    opus_int32 bitrates[256];
829    opus_val16 bandLogE[42];
830    opus_val32 *mem = NULL;
831    opus_val32 *preemph_mem=NULL;
832    int frame_size;
833    opus_int32 rate_sum;
834    opus_int32 smallest_packet;
835    ALLOC_STACK;
836 
837    if (st->mapping_type == MAPPING_TYPE_SURROUND)
838    {
839       preemph_mem = ms_get_preemph_mem(st);
840       mem = ms_get_window_mem(st);
841    }
842 
843    ptr = (char*)st + align(sizeof(OpusMSEncoder));
844    opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
845    opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_VBR(&vbr));
846    opus_encoder_ctl((OpusEncoder*)ptr, CELT_GET_MODE(&celt_mode));
847 
848    frame_size = frame_size_select(analysis_frame_size, st->variable_duration, Fs);
849    if (frame_size <= 0)
850    {
851       RESTORE_STACK;
852       return OPUS_BAD_ARG;
853    }
854 
855    /* Smallest packet the encoder can produce. */
856    smallest_packet = st->layout.nb_streams*2-1;
857    /* 100 ms needs an extra byte per stream for the ToC. */
858    if (Fs/frame_size == 10)
859      smallest_packet += st->layout.nb_streams;
860    if (max_data_bytes < smallest_packet)
861    {
862       RESTORE_STACK;
863       return OPUS_BUFFER_TOO_SMALL;
864    }
865    ALLOC(buf, 2*frame_size, opus_val16);
866    coupled_size = opus_encoder_get_size(2);
867    mono_size = opus_encoder_get_size(1);
868 
869    ALLOC(bandSMR, 21*st->layout.nb_channels, opus_val16);
870    if (st->mapping_type == MAPPING_TYPE_SURROUND)
871    {
872       surround_analysis(celt_mode, pcm, bandSMR, mem, preemph_mem, frame_size, 120, st->layout.nb_channels, Fs, copy_channel_in, st->arch);
873    }
874 
875    /* Compute bitrate allocation between streams (this could be a lot better) */
876    rate_sum = rate_allocation(st, bitrates, frame_size);
877 
878    if (!vbr)
879    {
880       if (st->bitrate_bps == OPUS_AUTO)
881       {
882          max_data_bytes = IMIN(max_data_bytes, 3*rate_sum/(3*8*Fs/frame_size));
883       } else if (st->bitrate_bps != OPUS_BITRATE_MAX)
884       {
885          max_data_bytes = IMIN(max_data_bytes, IMAX(smallest_packet,
886                           3*st->bitrate_bps/(3*8*Fs/frame_size)));
887       }
888    }
889    ptr = (char*)st + align(sizeof(OpusMSEncoder));
890    for (s=0;s<st->layout.nb_streams;s++)
891    {
892       OpusEncoder *enc;
893       enc = (OpusEncoder*)ptr;
894       if (s < st->layout.nb_coupled_streams)
895          ptr += align(coupled_size);
896       else
897          ptr += align(mono_size);
898       opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrates[s]));
899       if (st->mapping_type == MAPPING_TYPE_SURROUND)
900       {
901          opus_int32 equiv_rate;
902          equiv_rate = st->bitrate_bps;
903          if (frame_size*50 < Fs)
904             equiv_rate -= 60*(Fs/frame_size - 50)*st->layout.nb_channels;
905          if (equiv_rate > 10000*st->layout.nb_channels)
906             opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
907          else if (equiv_rate > 7000*st->layout.nb_channels)
908             opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_SUPERWIDEBAND));
909          else if (equiv_rate > 5000*st->layout.nb_channels)
910             opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_WIDEBAND));
911          else
912             opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND));
913          if (s < st->layout.nb_coupled_streams)
914          {
915             /* To preserve the spatial image, force stereo CELT on coupled streams */
916             opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY));
917             opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(2));
918          }
919       }
920       else if (st->mapping_type == MAPPING_TYPE_AMBISONICS) {
921         opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY));
922       }
923    }
924 
925    ptr = (char*)st + align(sizeof(OpusMSEncoder));
926    /* Counting ToC */
927    tot_size = 0;
928    for (s=0;s<st->layout.nb_streams;s++)
929    {
930       OpusEncoder *enc;
931       int len;
932       int curr_max;
933       int c1, c2;
934       int ret;
935 
936       opus_repacketizer_init(&rp);
937       enc = (OpusEncoder*)ptr;
938       if (s < st->layout.nb_coupled_streams)
939       {
940          int i;
941          int left, right;
942          left = get_left_channel(&st->layout, s, -1);
943          right = get_right_channel(&st->layout, s, -1);
944          (*copy_channel_in)(buf, 2,
945             pcm, st->layout.nb_channels, left, frame_size, user_data);
946          (*copy_channel_in)(buf+1, 2,
947             pcm, st->layout.nb_channels, right, frame_size, user_data);
948          ptr += align(coupled_size);
949          if (st->mapping_type == MAPPING_TYPE_SURROUND)
950          {
951             for (i=0;i<21;i++)
952             {
953                bandLogE[i] = bandSMR[21*left+i];
954                bandLogE[21+i] = bandSMR[21*right+i];
955             }
956          }
957          c1 = left;
958          c2 = right;
959       } else {
960          int i;
961          int chan = get_mono_channel(&st->layout, s, -1);
962          (*copy_channel_in)(buf, 1,
963             pcm, st->layout.nb_channels, chan, frame_size, user_data);
964          ptr += align(mono_size);
965          if (st->mapping_type == MAPPING_TYPE_SURROUND)
966          {
967             for (i=0;i<21;i++)
968                bandLogE[i] = bandSMR[21*chan+i];
969          }
970          c1 = chan;
971          c2 = -1;
972       }
973       if (st->mapping_type == MAPPING_TYPE_SURROUND)
974          opus_encoder_ctl(enc, OPUS_SET_ENERGY_MASK(bandLogE));
975       /* number of bytes left (+Toc) */
976       curr_max = max_data_bytes - tot_size;
977       /* Reserve one byte for the last stream and two for the others */
978       curr_max -= IMAX(0,2*(st->layout.nb_streams-s-1)-1);
979       /* For 100 ms, reserve an extra byte per stream for the ToC */
980       if (Fs/frame_size == 10)
981         curr_max -= st->layout.nb_streams-s-1;
982       curr_max = IMIN(curr_max,MS_FRAME_TMP);
983       /* Repacketizer will add one or two bytes for self-delimited frames */
984       if (s != st->layout.nb_streams-1) curr_max -=  curr_max>253 ? 2 : 1;
985       if (!vbr && s == st->layout.nb_streams-1)
986          opus_encoder_ctl(enc, OPUS_SET_BITRATE(curr_max*(8*Fs/frame_size)));
987       len = opus_encode_native(enc, buf, frame_size, tmp_data, curr_max, lsb_depth,
988             pcm, analysis_frame_size, c1, c2, st->layout.nb_channels, downmix, float_api);
989       if (len<0)
990       {
991          RESTORE_STACK;
992          return len;
993       }
994       /* We need to use the repacketizer to add the self-delimiting lengths
995          while taking into account the fact that the encoder can now return
996          more than one frame at a time (e.g. 60 ms CELT-only) */
997       ret = opus_repacketizer_cat(&rp, tmp_data, len);
998       /* If the opus_repacketizer_cat() fails, then something's seriously wrong
999          with the encoder. */
1000       if (ret != OPUS_OK)
1001       {
1002          RESTORE_STACK;
1003          return OPUS_INTERNAL_ERROR;
1004       }
1005       len = opus_repacketizer_out_range_impl(&rp, 0, opus_repacketizer_get_nb_frames(&rp),
1006             data, max_data_bytes-tot_size, s != st->layout.nb_streams-1, !vbr && s == st->layout.nb_streams-1);
1007       data += len;
1008       tot_size += len;
1009    }
1010    /*printf("\n");*/
1011    RESTORE_STACK;
1012    return tot_size;
1013 }
1014 
1015 #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)1016 static void opus_copy_channel_in_float(
1017   opus_val16 *dst,
1018   int dst_stride,
1019   const void *src,
1020   int src_stride,
1021   int src_channel,
1022   int frame_size,
1023   void *user_data
1024 )
1025 {
1026    const float *float_src;
1027    opus_int32 i;
1028    (void)user_data;
1029    float_src = (const float *)src;
1030    for (i=0;i<frame_size;i++)
1031 #if defined(FIXED_POINT)
1032       dst[i*dst_stride] = FLOAT2INT16(float_src[i*src_stride+src_channel]);
1033 #else
1034       dst[i*dst_stride] = float_src[i*src_stride+src_channel];
1035 #endif
1036 }
1037 #endif
1038 
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)1039 static void opus_copy_channel_in_short(
1040   opus_val16 *dst,
1041   int dst_stride,
1042   const void *src,
1043   int src_stride,
1044   int src_channel,
1045   int frame_size,
1046   void *user_data
1047 )
1048 {
1049    const opus_int16 *short_src;
1050    opus_int32 i;
1051    (void)user_data;
1052    short_src = (const opus_int16 *)src;
1053    for (i=0;i<frame_size;i++)
1054 #if defined(FIXED_POINT)
1055       dst[i*dst_stride] = short_src[i*src_stride+src_channel];
1056 #else
1057       dst[i*dst_stride] = (1/32768.f)*short_src[i*src_stride+src_channel];
1058 #endif
1059 }
1060 
1061 
1062 #ifdef FIXED_POINT
opus_multistream_encode(OpusMSEncoder * st,const opus_val16 * pcm,int frame_size,unsigned char * data,opus_int32 max_data_bytes)1063 int opus_multistream_encode(
1064     OpusMSEncoder *st,
1065     const opus_val16 *pcm,
1066     int frame_size,
1067     unsigned char *data,
1068     opus_int32 max_data_bytes
1069 )
1070 {
1071    return opus_multistream_encode_native(st, opus_copy_channel_in_short,
1072       pcm, frame_size, data, max_data_bytes, 16, downmix_int, 0, NULL);
1073 }
1074 
1075 #ifndef DISABLE_FLOAT_API
opus_multistream_encode_float(OpusMSEncoder * st,const float * pcm,int frame_size,unsigned char * data,opus_int32 max_data_bytes)1076 int opus_multistream_encode_float(
1077     OpusMSEncoder *st,
1078     const float *pcm,
1079     int frame_size,
1080     unsigned char *data,
1081     opus_int32 max_data_bytes
1082 )
1083 {
1084    return opus_multistream_encode_native(st, opus_copy_channel_in_float,
1085       pcm, frame_size, data, max_data_bytes, 16, downmix_float, 1, NULL);
1086 }
1087 #endif
1088 
1089 #else
1090 
opus_multistream_encode_float(OpusMSEncoder * st,const opus_val16 * pcm,int frame_size,unsigned char * data,opus_int32 max_data_bytes)1091 int opus_multistream_encode_float
1092 (
1093     OpusMSEncoder *st,
1094     const opus_val16 *pcm,
1095     int frame_size,
1096     unsigned char *data,
1097     opus_int32 max_data_bytes
1098 )
1099 {
1100    return opus_multistream_encode_native(st, opus_copy_channel_in_float,
1101       pcm, frame_size, data, max_data_bytes, 24, downmix_float, 1, NULL);
1102 }
1103 
opus_multistream_encode(OpusMSEncoder * st,const opus_int16 * pcm,int frame_size,unsigned char * data,opus_int32 max_data_bytes)1104 int opus_multistream_encode(
1105     OpusMSEncoder *st,
1106     const opus_int16 *pcm,
1107     int frame_size,
1108     unsigned char *data,
1109     opus_int32 max_data_bytes
1110 )
1111 {
1112    return opus_multistream_encode_native(st, opus_copy_channel_in_short,
1113       pcm, frame_size, data, max_data_bytes, 16, downmix_int, 0, NULL);
1114 }
1115 #endif
1116 
opus_multistream_encoder_ctl_va_list(OpusMSEncoder * st,int request,va_list ap)1117 int opus_multistream_encoder_ctl_va_list(OpusMSEncoder *st, int request,
1118                                          va_list ap)
1119 {
1120    int coupled_size, mono_size;
1121    char *ptr;
1122    int ret = OPUS_OK;
1123 
1124    coupled_size = opus_encoder_get_size(2);
1125    mono_size = opus_encoder_get_size(1);
1126    ptr = (char*)st + align(sizeof(OpusMSEncoder));
1127    switch (request)
1128    {
1129    case OPUS_SET_BITRATE_REQUEST:
1130    {
1131       opus_int32 value = va_arg(ap, opus_int32);
1132       if (value != OPUS_AUTO && value != OPUS_BITRATE_MAX)
1133       {
1134          if (value <= 0)
1135             goto bad_arg;
1136          value = IMIN(300000*st->layout.nb_channels, IMAX(500*st->layout.nb_channels, value));
1137       }
1138       st->bitrate_bps = value;
1139    }
1140    break;
1141    case OPUS_GET_BITRATE_REQUEST:
1142    {
1143       int s;
1144       opus_int32 *value = va_arg(ap, opus_int32*);
1145       if (!value)
1146       {
1147          goto bad_arg;
1148       }
1149       *value = 0;
1150       for (s=0;s<st->layout.nb_streams;s++)
1151       {
1152          opus_int32 rate;
1153          OpusEncoder *enc;
1154          enc = (OpusEncoder*)ptr;
1155          if (s < st->layout.nb_coupled_streams)
1156             ptr += align(coupled_size);
1157          else
1158             ptr += align(mono_size);
1159          opus_encoder_ctl(enc, request, &rate);
1160          *value += rate;
1161       }
1162    }
1163    break;
1164    case OPUS_GET_LSB_DEPTH_REQUEST:
1165    case OPUS_GET_VBR_REQUEST:
1166    case OPUS_GET_APPLICATION_REQUEST:
1167    case OPUS_GET_BANDWIDTH_REQUEST:
1168    case OPUS_GET_COMPLEXITY_REQUEST:
1169    case OPUS_GET_PACKET_LOSS_PERC_REQUEST:
1170    case OPUS_GET_DTX_REQUEST:
1171    case OPUS_GET_VOICE_RATIO_REQUEST:
1172    case OPUS_GET_VBR_CONSTRAINT_REQUEST:
1173    case OPUS_GET_SIGNAL_REQUEST:
1174    case OPUS_GET_LOOKAHEAD_REQUEST:
1175    case OPUS_GET_SAMPLE_RATE_REQUEST:
1176    case OPUS_GET_INBAND_FEC_REQUEST:
1177    case OPUS_GET_FORCE_CHANNELS_REQUEST:
1178    case OPUS_GET_PREDICTION_DISABLED_REQUEST:
1179    case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST:
1180    {
1181       OpusEncoder *enc;
1182       /* For int32* GET params, just query the first stream */
1183       opus_int32 *value = va_arg(ap, opus_int32*);
1184       enc = (OpusEncoder*)ptr;
1185       ret = opus_encoder_ctl(enc, request, value);
1186    }
1187    break;
1188    case OPUS_GET_FINAL_RANGE_REQUEST:
1189    {
1190       int s;
1191       opus_uint32 *value = va_arg(ap, opus_uint32*);
1192       opus_uint32 tmp;
1193       if (!value)
1194       {
1195          goto bad_arg;
1196       }
1197       *value=0;
1198       for (s=0;s<st->layout.nb_streams;s++)
1199       {
1200          OpusEncoder *enc;
1201          enc = (OpusEncoder*)ptr;
1202          if (s < st->layout.nb_coupled_streams)
1203             ptr += align(coupled_size);
1204          else
1205             ptr += align(mono_size);
1206          ret = opus_encoder_ctl(enc, request, &tmp);
1207          if (ret != OPUS_OK) break;
1208          *value ^= tmp;
1209       }
1210    }
1211    break;
1212    case OPUS_SET_LSB_DEPTH_REQUEST:
1213    case OPUS_SET_COMPLEXITY_REQUEST:
1214    case OPUS_SET_VBR_REQUEST:
1215    case OPUS_SET_VBR_CONSTRAINT_REQUEST:
1216    case OPUS_SET_MAX_BANDWIDTH_REQUEST:
1217    case OPUS_SET_BANDWIDTH_REQUEST:
1218    case OPUS_SET_SIGNAL_REQUEST:
1219    case OPUS_SET_APPLICATION_REQUEST:
1220    case OPUS_SET_INBAND_FEC_REQUEST:
1221    case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
1222    case OPUS_SET_DTX_REQUEST:
1223    case OPUS_SET_FORCE_MODE_REQUEST:
1224    case OPUS_SET_FORCE_CHANNELS_REQUEST:
1225    case OPUS_SET_PREDICTION_DISABLED_REQUEST:
1226    case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST:
1227    {
1228       int s;
1229       /* This works for int32 params */
1230       opus_int32 value = va_arg(ap, opus_int32);
1231       for (s=0;s<st->layout.nb_streams;s++)
1232       {
1233          OpusEncoder *enc;
1234 
1235          enc = (OpusEncoder*)ptr;
1236          if (s < st->layout.nb_coupled_streams)
1237             ptr += align(coupled_size);
1238          else
1239             ptr += align(mono_size);
1240          ret = opus_encoder_ctl(enc, request, value);
1241          if (ret != OPUS_OK)
1242             break;
1243       }
1244    }
1245    break;
1246    case OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST:
1247    {
1248       int s;
1249       opus_int32 stream_id;
1250       OpusEncoder **value;
1251       stream_id = va_arg(ap, opus_int32);
1252       if (stream_id<0 || stream_id >= st->layout.nb_streams)
1253          goto bad_arg;
1254       value = va_arg(ap, OpusEncoder**);
1255       if (!value)
1256       {
1257          goto bad_arg;
1258       }
1259       for (s=0;s<stream_id;s++)
1260       {
1261          if (s < st->layout.nb_coupled_streams)
1262             ptr += align(coupled_size);
1263          else
1264             ptr += align(mono_size);
1265       }
1266       *value = (OpusEncoder*)ptr;
1267    }
1268    break;
1269    case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST:
1270    {
1271        opus_int32 value = va_arg(ap, opus_int32);
1272        st->variable_duration = value;
1273    }
1274    break;
1275    case OPUS_GET_EXPERT_FRAME_DURATION_REQUEST:
1276    {
1277        opus_int32 *value = va_arg(ap, opus_int32*);
1278        if (!value)
1279        {
1280           goto bad_arg;
1281        }
1282        *value = st->variable_duration;
1283    }
1284    break;
1285    case OPUS_RESET_STATE:
1286    {
1287       int s;
1288       if (st->mapping_type == MAPPING_TYPE_SURROUND)
1289       {
1290          OPUS_CLEAR(ms_get_preemph_mem(st), st->layout.nb_channels);
1291          OPUS_CLEAR(ms_get_window_mem(st), st->layout.nb_channels*120);
1292       }
1293       for (s=0;s<st->layout.nb_streams;s++)
1294       {
1295          OpusEncoder *enc;
1296          enc = (OpusEncoder*)ptr;
1297          if (s < st->layout.nb_coupled_streams)
1298             ptr += align(coupled_size);
1299          else
1300             ptr += align(mono_size);
1301          ret = opus_encoder_ctl(enc, OPUS_RESET_STATE);
1302          if (ret != OPUS_OK)
1303             break;
1304       }
1305    }
1306    break;
1307    default:
1308       ret = OPUS_UNIMPLEMENTED;
1309       break;
1310    }
1311    return ret;
1312 bad_arg:
1313    return OPUS_BAD_ARG;
1314 }
1315 
opus_multistream_encoder_ctl(OpusMSEncoder * st,int request,...)1316 int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
1317 {
1318    int ret;
1319    va_list ap;
1320    va_start(ap, request);
1321    ret = opus_multistream_encoder_ctl_va_list(st, request, ap);
1322    va_end(ap);
1323    return ret;
1324 }
1325 
opus_multistream_encoder_destroy(OpusMSEncoder * st)1326 void opus_multistream_encoder_destroy(OpusMSEncoder *st)
1327 {
1328     opus_free(st);
1329 }
1330