tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

opus_multistream_encoder.c (39853B)


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