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