• 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       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