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 
     40 typedef struct ChannelLayout {
     41    int nb_channels;
     42    int nb_streams;
     43    int nb_coupled_streams;
     44    unsigned char mapping[256];
     45 } ChannelLayout;
     46 
     47 struct OpusMSEncoder {
     48    ChannelLayout layout;
     49    int bitrate;
     50    /* Encoder states go here */
     51 };
     52 
     53 struct OpusMSDecoder {
     54    ChannelLayout layout;
     55    /* Decoder states go here */
     56 };
     57 
     58 #ifdef FIXED_POINT
     59 #define opus_encode_native opus_encode
     60 #else
     61 #define opus_encode_native opus_encode_float
     62 #endif
     63 
     64 static int validate_layout(const ChannelLayout *layout)
     65 {
     66    int i, max_channel;
     67 
     68    max_channel = layout->nb_streams+layout->nb_coupled_streams;
     69    if (max_channel>255)
     70       return 0;
     71    for (i=0;i<layout->nb_channels;i++)
     72    {
     73       if (layout->mapping[i] >= max_channel && layout->mapping[i] != 255)
     74          return 0;
     75    }
     76    return 1;
     77 }
     78 
     79 
     80 static int get_left_channel(const ChannelLayout *layout, int stream_id, int prev)
     81 {
     82    int i;
     83    i = (prev<0) ? 0 : prev+1;
     84    for (;i<layout->nb_channels;i++)
     85    {
     86       if (layout->mapping[i]==stream_id*2)
     87          return i;
     88    }
     89    return -1;
     90 }
     91 
     92 static int get_right_channel(const ChannelLayout *layout, int stream_id, int prev)
     93 {
     94    int i;
     95    i = (prev<0) ? 0 : prev+1;
     96    for (;i<layout->nb_channels;i++)
     97    {
     98       if (layout->mapping[i]==stream_id*2+1)
     99          return i;
    100    }
    101    return -1;
    102 }
    103 
    104 static int get_mono_channel(const ChannelLayout *layout, int stream_id, int prev)
    105 {
    106    int i;
    107    i = (prev<0) ? 0 : prev+1;
    108    for (;i<layout->nb_channels;i++)
    109    {
    110       if (layout->mapping[i]==stream_id+layout->nb_coupled_streams)
    111          return i;
    112    }
    113    return -1;
    114 }
    115 
    116 static int validate_encoder_layout(const ChannelLayout *layout)
    117 {
    118    int s;
    119    for (s=0;s<layout->nb_streams;s++)
    120    {
    121       if (s < layout->nb_coupled_streams)
    122       {
    123          if (get_left_channel(layout, s, -1)==-1)
    124             return 0;
    125          if (get_right_channel(layout, s, -1)==-1)
    126             return 0;
    127       } else {
    128          if (get_mono_channel(layout, s, -1)==-1)
    129             return 0;
    130       }
    131    }
    132    return 1;
    133 }
    134 
    135 opus_int32 opus_multistream_encoder_get_size(int nb_streams, int nb_coupled_streams)
    136 {
    137    int coupled_size;
    138    int mono_size;
    139 
    140    if(nb_streams<1||nb_coupled_streams>nb_streams||nb_coupled_streams<0)return 0;
    141    coupled_size = opus_encoder_get_size(2);
    142    mono_size = opus_encoder_get_size(1);
    143    return align(sizeof(OpusMSEncoder))
    144         + nb_coupled_streams * align(coupled_size)
    145         + (nb_streams-nb_coupled_streams) * align(mono_size);
    146 }
    147 
    148 
    149 
    150 int opus_multistream_encoder_init(
    151       OpusMSEncoder *st,
    152       opus_int32 Fs,
    153       int channels,
    154       int streams,
    155       int coupled_streams,
    156       const unsigned char *mapping,
    157       int application
    158 )
    159 {
    160    int coupled_size;
    161    int mono_size;
    162    int i, ret;
    163    char *ptr;
    164 
    165    if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
    166        (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0))
    167       return OPUS_BAD_ARG;
    168 
    169    st->layout.nb_channels = channels;
    170    st->layout.nb_streams = streams;
    171    st->layout.nb_coupled_streams = coupled_streams;
    172 
    173    for (i=0;i<st->layout.nb_channels;i++)
    174       st->layout.mapping[i] = mapping[i];
    175    if (!validate_layout(&st->layout) || !validate_encoder_layout(&st->layout))
    176       return OPUS_BAD_ARG;
    177    ptr = (char*)st + align(sizeof(OpusMSEncoder));
    178    coupled_size = opus_encoder_get_size(2);
    179    mono_size = opus_encoder_get_size(1);
    180 
    181    for (i=0;i<st->layout.nb_coupled_streams;i++)
    182    {
    183       ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 2, application);
    184       if(ret!=OPUS_OK)return ret;
    185       ptr += align(coupled_size);
    186    }
    187    for (;i<st->layout.nb_streams;i++)
    188    {
    189       ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 1, application);
    190       if(ret!=OPUS_OK)return ret;
    191       ptr += align(mono_size);
    192    }
    193    return OPUS_OK;
    194 }
    195 
    196 OpusMSEncoder *opus_multistream_encoder_create(
    197       opus_int32 Fs,
    198       int channels,
    199       int streams,
    200       int coupled_streams,
    201       const unsigned char *mapping,
    202       int application,
    203       int *error
    204 )
    205 {
    206    int ret;
    207    OpusMSEncoder *st;
    208    if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
    209        (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0))
    210    {
    211       if (error)
    212          *error = OPUS_BAD_ARG;
    213       return NULL;
    214    }
    215    st = (OpusMSEncoder *)opus_alloc(opus_multistream_encoder_get_size(streams, coupled_streams));
    216    if (st==NULL)
    217    {
    218       if (error)
    219          *error = OPUS_ALLOC_FAIL;
    220       return NULL;
    221    }
    222    ret = opus_multistream_encoder_init(st, Fs, channels, streams, coupled_streams, mapping, application);
    223    if (ret != OPUS_OK)
    224    {
    225       opus_free(st);
    226       st = NULL;
    227    }
    228    if (error)
    229       *error = ret;
    230    return st;
    231 }
    232 
    233 typedef void (*opus_copy_channel_in_func)(
    234   opus_val16 *dst,
    235   int dst_stride,
    236   const void *src,
    237   int src_stride,
    238   int src_channel,
    239   int frame_size
    240 );
    241 
    242 /* Max size in case the encoder decides to return three frames */
    243 #define MS_FRAME_TMP (3*1275+7)
    244 static int opus_multistream_encode_native
    245 (
    246     OpusMSEncoder *st,
    247     opus_copy_channel_in_func copy_channel_in,
    248     const void *pcm,
    249     int frame_size,
    250     unsigned char *data,
    251     opus_int32 max_data_bytes
    252 )
    253 {
    254    opus_int32 Fs;
    255    int coupled_size;
    256    int mono_size;
    257    int s;
    258    char *ptr;
    259    int tot_size;
    260    VARDECL(opus_val16, buf);
    261    unsigned char tmp_data[MS_FRAME_TMP];
    262    OpusRepacketizer rp;
    263    ALLOC_STACK;
    264 
    265    ptr = (char*)st + align(sizeof(OpusMSEncoder));
    266    opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
    267    /* Validate frame_size before using it to allocate stack space.
    268       This mirrors the checks in opus_encode[_float](). */
    269    if (400*frame_size != Fs && 200*frame_size != Fs &&
    270        100*frame_size != Fs &&  50*frame_size != Fs &&
    271         25*frame_size != Fs &&  50*frame_size != 3*Fs)
    272    {
    273       RESTORE_STACK;
    274       return OPUS_BAD_ARG;
    275    }
    276    ALLOC(buf, 2*frame_size, opus_val16);
    277    coupled_size = opus_encoder_get_size(2);
    278    mono_size = opus_encoder_get_size(1);
    279 
    280    if (max_data_bytes < 4*st->layout.nb_streams-1)
    281    {
    282       RESTORE_STACK;
    283       return OPUS_BUFFER_TOO_SMALL;
    284    }
    285    /* Counting ToC */
    286    tot_size = 0;
    287    for (s=0;s<st->layout.nb_streams;s++)
    288    {
    289       OpusEncoder *enc;
    290       int len;
    291       int curr_max;
    292 
    293       opus_repacketizer_init(&rp);
    294       enc = (OpusEncoder*)ptr;
    295       if (s < st->layout.nb_coupled_streams)
    296       {
    297          int left, right;
    298          left = get_left_channel(&st->layout, s, -1);
    299          right = get_right_channel(&st->layout, s, -1);
    300          (*copy_channel_in)(buf, 2,
    301             pcm, st->layout.nb_channels, left, frame_size);
    302          (*copy_channel_in)(buf+1, 2,
    303             pcm, st->layout.nb_channels, right, frame_size);
    304          ptr += align(coupled_size);
    305       } else {
    306          int chan = get_mono_channel(&st->layout, s, -1);
    307          (*copy_channel_in)(buf, 1,
    308             pcm, st->layout.nb_channels, chan, frame_size);
    309          ptr += align(mono_size);
    310       }
    311       /* number of bytes left (+Toc) */
    312       curr_max = max_data_bytes - tot_size;
    313       /* Reserve three bytes for the last stream and four for the others */
    314       curr_max -= IMAX(0,4*(st->layout.nb_streams-s-1)-1);
    315       curr_max = IMIN(curr_max,MS_FRAME_TMP);
    316       len = opus_encode_native(enc, buf, frame_size, tmp_data, curr_max);
    317       if (len<0)
    318       {
    319          RESTORE_STACK;
    320          return len;
    321       }
    322       /* We need to use the repacketizer to add the self-delimiting lengths
    323          while taking into account the fact that the encoder can now return
    324          more than one frame at a time (e.g. 60 ms CELT-only) */
    325       opus_repacketizer_cat(&rp, tmp_data, len);
    326       len = opus_repacketizer_out_range_impl(&rp, 0, opus_repacketizer_get_nb_frames(&rp), data, max_data_bytes-tot_size, s != st->layout.nb_streams-1);
    327       data += len;
    328       tot_size += len;
    329    }
    330    RESTORE_STACK;
    331    return tot_size;
    332 
    333 }
    334 
    335 #if !defined(DISABLE_FLOAT_API)
    336 static void opus_copy_channel_in_float(
    337   opus_val16 *dst,
    338   int dst_stride,
    339   const void *src,
    340   int src_stride,
    341   int src_channel,
    342   int frame_size
    343 )
    344 {
    345    const float *float_src;
    346    int i;
    347    float_src = (const float *)src;
    348    for (i=0;i<frame_size;i++)
    349 #if defined(FIXED_POINT)
    350       dst[i*dst_stride] = FLOAT2INT16(float_src[i*src_stride+src_channel]);
    351 #else
    352       dst[i*dst_stride] = float_src[i*src_stride+src_channel];
    353 #endif
    354 }
    355 #endif
    356 
    357 static void opus_copy_channel_in_short(
    358   opus_val16 *dst,
    359   int dst_stride,
    360   const void *src,
    361   int src_stride,
    362   int src_channel,
    363   int frame_size
    364 )
    365 {
    366    const opus_int16 *short_src;
    367    int i;
    368    short_src = (const opus_int16 *)src;
    369    for (i=0;i<frame_size;i++)
    370 #if defined(FIXED_POINT)
    371       dst[i*dst_stride] = short_src[i*src_stride+src_channel];
    372 #else
    373       dst[i*dst_stride] = (1/32768.f)*short_src[i*src_stride+src_channel];
    374 #endif
    375 }
    376 
    377 #ifdef FIXED_POINT
    378 int opus_multistream_encode(
    379     OpusMSEncoder *st,
    380     const opus_val16 *pcm,
    381     int frame_size,
    382     unsigned char *data,
    383     opus_int32 max_data_bytes
    384 )
    385 {
    386    return opus_multistream_encode_native(st, opus_copy_channel_in_short,
    387       pcm, frame_size, data, max_data_bytes);
    388 }
    389 
    390 #ifndef DISABLE_FLOAT_API
    391 int opus_multistream_encode_float(
    392     OpusMSEncoder *st,
    393     const float *pcm,
    394     int frame_size,
    395     unsigned char *data,
    396     opus_int32 max_data_bytes
    397 )
    398 {
    399    return opus_multistream_encode_native(st, opus_copy_channel_in_float,
    400       pcm, frame_size, data, max_data_bytes);
    401 }
    402 #endif
    403 
    404 #else
    405 
    406 int opus_multistream_encode_float
    407 (
    408     OpusMSEncoder *st,
    409     const opus_val16 *pcm,
    410     int frame_size,
    411     unsigned char *data,
    412     opus_int32 max_data_bytes
    413 )
    414 {
    415    return opus_multistream_encode_native(st, opus_copy_channel_in_float,
    416       pcm, frame_size, data, max_data_bytes);
    417 }
    418 
    419 int opus_multistream_encode(
    420     OpusMSEncoder *st,
    421     const opus_int16 *pcm,
    422     int frame_size,
    423     unsigned char *data,
    424     opus_int32 max_data_bytes
    425 )
    426 {
    427    return opus_multistream_encode_native(st, opus_copy_channel_in_short,
    428       pcm, frame_size, data, max_data_bytes);
    429 }
    430 #endif
    431 
    432 int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
    433 {
    434    va_list ap;
    435    int coupled_size, mono_size;
    436    char *ptr;
    437    int ret = OPUS_OK;
    438 
    439    va_start(ap, request);
    440 
    441    coupled_size = opus_encoder_get_size(2);
    442    mono_size = opus_encoder_get_size(1);
    443    ptr = (char*)st + align(sizeof(OpusMSEncoder));
    444    switch (request)
    445    {
    446    case OPUS_SET_BITRATE_REQUEST:
    447    {
    448       int chan, s;
    449       opus_int32 value = va_arg(ap, opus_int32);
    450       chan = st->layout.nb_streams + st->layout.nb_coupled_streams;
    451       value /= chan;
    452       for (s=0;s<st->layout.nb_streams;s++)
    453       {
    454          OpusEncoder *enc;
    455          enc = (OpusEncoder*)ptr;
    456          if (s < st->layout.nb_coupled_streams)
    457             ptr += align(coupled_size);
    458          else
    459             ptr += align(mono_size);
    460          opus_encoder_ctl(enc, request, value * (s < st->layout.nb_coupled_streams ? 2 : 1));
    461       }
    462    }
    463    break;
    464    case OPUS_GET_BITRATE_REQUEST:
    465    {
    466       int s;
    467       opus_int32 *value = va_arg(ap, opus_int32*);
    468       *value = 0;
    469       for (s=0;s<st->layout.nb_streams;s++)
    470       {
    471          opus_int32 rate;
    472          OpusEncoder *enc;
    473          enc = (OpusEncoder*)ptr;
    474          if (s < st->layout.nb_coupled_streams)
    475             ptr += align(coupled_size);
    476          else
    477             ptr += align(mono_size);
    478          opus_encoder_ctl(enc, request, &rate);
    479          *value += rate;
    480       }
    481    }
    482    break;
    483    case OPUS_GET_LSB_DEPTH_REQUEST:
    484    case OPUS_GET_VBR_REQUEST:
    485    case OPUS_GET_APPLICATION_REQUEST:
    486    case OPUS_GET_BANDWIDTH_REQUEST:
    487    case OPUS_GET_COMPLEXITY_REQUEST:
    488    case OPUS_GET_PACKET_LOSS_PERC_REQUEST:
    489    case OPUS_GET_DTX_REQUEST:
    490    case OPUS_GET_VOICE_RATIO_REQUEST:
    491    case OPUS_GET_VBR_CONSTRAINT_REQUEST:
    492    case OPUS_GET_SIGNAL_REQUEST:
    493    case OPUS_GET_LOOKAHEAD_REQUEST:
    494    case OPUS_GET_SAMPLE_RATE_REQUEST:
    495    case OPUS_GET_INBAND_FEC_REQUEST:
    496    {
    497       OpusEncoder *enc;
    498       /* For int32* GET params, just query the first stream */
    499       opus_int32 *value = va_arg(ap, opus_int32*);
    500       enc = (OpusEncoder*)ptr;
    501       ret = opus_encoder_ctl(enc, request, value);
    502    }
    503    break;
    504    case OPUS_GET_FINAL_RANGE_REQUEST:
    505    {
    506       int s;
    507       opus_uint32 *value = va_arg(ap, opus_uint32*);
    508       opus_uint32 tmp;
    509       *value=0;
    510       for (s=0;s<st->layout.nb_streams;s++)
    511       {
    512          OpusEncoder *enc;
    513          enc = (OpusEncoder*)ptr;
    514          if (s < st->layout.nb_coupled_streams)
    515             ptr += align(coupled_size);
    516          else
    517             ptr += align(mono_size);
    518          ret = opus_encoder_ctl(enc, request, &tmp);
    519          if (ret != OPUS_OK) break;
    520          *value ^= tmp;
    521       }
    522    }
    523    break;
    524    case OPUS_SET_LSB_DEPTH_REQUEST:
    525    case OPUS_SET_COMPLEXITY_REQUEST:
    526    case OPUS_SET_VBR_REQUEST:
    527    case OPUS_SET_VBR_CONSTRAINT_REQUEST:
    528    case OPUS_SET_BANDWIDTH_REQUEST:
    529    case OPUS_SET_SIGNAL_REQUEST:
    530    case OPUS_SET_APPLICATION_REQUEST:
    531    case OPUS_SET_INBAND_FEC_REQUEST:
    532    case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
    533    case OPUS_SET_DTX_REQUEST:
    534    case OPUS_SET_FORCE_MODE_REQUEST:
    535    {
    536       int s;
    537       /* This works for int32 params */
    538       opus_int32 value = va_arg(ap, opus_int32);
    539       for (s=0;s<st->layout.nb_streams;s++)
    540       {
    541          OpusEncoder *enc;
    542 
    543          enc = (OpusEncoder*)ptr;
    544          if (s < st->layout.nb_coupled_streams)
    545             ptr += align(coupled_size);
    546          else
    547             ptr += align(mono_size);
    548          ret = opus_encoder_ctl(enc, request, value);
    549          if (ret != OPUS_OK)
    550             break;
    551       }
    552    }
    553    break;
    554    case OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST:
    555    {
    556       int s;
    557       opus_int32 stream_id;
    558       OpusEncoder **value;
    559       stream_id = va_arg(ap, opus_int32);
    560       if (stream_id<0 || stream_id >= st->layout.nb_streams)
    561          ret = OPUS_BAD_ARG;
    562       value = va_arg(ap, OpusEncoder**);
    563       for (s=0;s<stream_id;s++)
    564       {
    565          if (s < st->layout.nb_coupled_streams)
    566             ptr += align(coupled_size);
    567          else
    568             ptr += align(mono_size);
    569       }
    570       *value = (OpusEncoder*)ptr;
    571    }
    572       break;
    573    default:
    574       ret = OPUS_UNIMPLEMENTED;
    575       break;
    576    }
    577 
    578    va_end(ap);
    579    return ret;
    580 }
    581 
    582 void opus_multistream_encoder_destroy(OpusMSEncoder *st)
    583 {
    584     opus_free(st);
    585 }
    586 
    587 
    588 /* DECODER */
    589 
    590 opus_int32 opus_multistream_decoder_get_size(int nb_streams, int nb_coupled_streams)
    591 {
    592    int coupled_size;
    593    int mono_size;
    594 
    595    if(nb_streams<1||nb_coupled_streams>nb_streams||nb_coupled_streams<0)return 0;
    596    coupled_size = opus_decoder_get_size(2);
    597    mono_size = opus_decoder_get_size(1);
    598    return align(sizeof(OpusMSDecoder))
    599          + nb_coupled_streams * align(coupled_size)
    600          + (nb_streams-nb_coupled_streams) * align(mono_size);
    601 }
    602 
    603 int opus_multistream_decoder_init(
    604       OpusMSDecoder *st,
    605       opus_int32 Fs,
    606       int channels,
    607       int streams,
    608       int coupled_streams,
    609       const unsigned char *mapping
    610 )
    611 {
    612    int coupled_size;
    613    int mono_size;
    614    int i, ret;
    615    char *ptr;
    616 
    617    if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
    618        (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0))
    619       return OPUS_BAD_ARG;
    620 
    621    st->layout.nb_channels = channels;
    622    st->layout.nb_streams = streams;
    623    st->layout.nb_coupled_streams = coupled_streams;
    624 
    625    for (i=0;i<st->layout.nb_channels;i++)
    626       st->layout.mapping[i] = mapping[i];
    627    if (!validate_layout(&st->layout))
    628       return OPUS_BAD_ARG;
    629 
    630    ptr = (char*)st + align(sizeof(OpusMSDecoder));
    631    coupled_size = opus_decoder_get_size(2);
    632    mono_size = opus_decoder_get_size(1);
    633 
    634    for (i=0;i<st->layout.nb_coupled_streams;i++)
    635    {
    636       ret=opus_decoder_init((OpusDecoder*)ptr, Fs, 2);
    637       if(ret!=OPUS_OK)return ret;
    638       ptr += align(coupled_size);
    639    }
    640    for (;i<st->layout.nb_streams;i++)
    641    {
    642       ret=opus_decoder_init((OpusDecoder*)ptr, Fs, 1);
    643       if(ret!=OPUS_OK)return ret;
    644       ptr += align(mono_size);
    645    }
    646    return OPUS_OK;
    647 }
    648 
    649 
    650 OpusMSDecoder *opus_multistream_decoder_create(
    651       opus_int32 Fs,
    652       int channels,
    653       int streams,
    654       int coupled_streams,
    655       const unsigned char *mapping,
    656       int *error
    657 )
    658 {
    659    int ret;
    660    OpusMSDecoder *st;
    661    if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
    662        (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0))
    663    {
    664       if (error)
    665          *error = OPUS_BAD_ARG;
    666       return NULL;
    667    }
    668    st = (OpusMSDecoder *)opus_alloc(opus_multistream_decoder_get_size(streams, coupled_streams));
    669    if (st==NULL)
    670    {
    671       if (error)
    672          *error = OPUS_ALLOC_FAIL;
    673       return NULL;
    674    }
    675    ret = opus_multistream_decoder_init(st, Fs, channels, streams, coupled_streams, mapping);
    676    if (error)
    677       *error = ret;
    678    if (ret != OPUS_OK)
    679    {
    680       opus_free(st);
    681       st = NULL;
    682    }
    683    return st;
    684 }
    685 
    686 typedef void (*opus_copy_channel_out_func)(
    687   void *dst,
    688   int dst_stride,
    689   int dst_channel,
    690   const opus_val16 *src,
    691   int src_stride,
    692   int frame_size
    693 );
    694 
    695 static int opus_multistream_decode_native(
    696       OpusMSDecoder *st,
    697       const unsigned char *data,
    698       opus_int32 len,
    699       void *pcm,
    700       opus_copy_channel_out_func copy_channel_out,
    701       int frame_size,
    702       int decode_fec
    703 )
    704 {
    705    opus_int32 Fs;
    706    int coupled_size;
    707    int mono_size;
    708    int s, c;
    709    char *ptr;
    710    int do_plc=0;
    711    VARDECL(opus_val16, buf);
    712    ALLOC_STACK;
    713 
    714    /* Limit frame_size to avoid excessive stack allocations. */
    715    opus_multistream_decoder_ctl(st, OPUS_GET_SAMPLE_RATE(&Fs));
    716    frame_size = IMIN(frame_size, Fs/25*3);
    717    ALLOC(buf, 2*frame_size, opus_val16);
    718    ptr = (char*)st + align(sizeof(OpusMSDecoder));
    719    coupled_size = opus_decoder_get_size(2);
    720    mono_size = opus_decoder_get_size(1);
    721 
    722    if (len==0)
    723       do_plc = 1;
    724    if (len < 0)
    725       return OPUS_BAD_ARG;
    726    if (!do_plc && len < 2*st->layout.nb_streams-1)
    727       return OPUS_INVALID_PACKET;
    728    for (s=0;s<st->layout.nb_streams;s++)
    729    {
    730       OpusDecoder *dec;
    731       int packet_offset, ret;
    732 
    733       dec = (OpusDecoder*)ptr;
    734       ptr += (s < st->layout.nb_coupled_streams) ? align(coupled_size) : align(mono_size);
    735 
    736       if (!do_plc && len<=0)
    737       {
    738          RESTORE_STACK;
    739          return OPUS_INVALID_PACKET;
    740       }
    741       packet_offset = 0;
    742       ret = opus_decode_native(dec, data, len, buf, frame_size, decode_fec, s!=st->layout.nb_streams-1, &packet_offset);
    743       data += packet_offset;
    744       len -= packet_offset;
    745       if (ret > frame_size)
    746       {
    747          RESTORE_STACK;
    748          return OPUS_BUFFER_TOO_SMALL;
    749       }
    750       if (s>0 && ret != frame_size)
    751       {
    752          RESTORE_STACK;
    753          return OPUS_INVALID_PACKET;
    754       }
    755       if (ret <= 0)
    756       {
    757          RESTORE_STACK;
    758          return ret;
    759       }
    760       frame_size = ret;
    761       if (s < st->layout.nb_coupled_streams)
    762       {
    763          int chan, prev;
    764          prev = -1;
    765          /* Copy "left" audio to the channel(s) where it belongs */
    766          while ( (chan = get_left_channel(&st->layout, s, prev)) != -1)
    767          {
    768             (*copy_channel_out)(pcm, st->layout.nb_channels, chan,
    769                buf, 2, frame_size);
    770             prev = chan;
    771          }
    772          prev = -1;
    773          /* Copy "right" audio to the channel(s) where it belongs */
    774          while ( (chan = get_right_channel(&st->layout, s, prev)) != -1)
    775          {
    776             (*copy_channel_out)(pcm, st->layout.nb_channels, chan,
    777                buf+1, 2, frame_size);
    778             prev = chan;
    779          }
    780       } else {
    781          int chan, prev;
    782          prev = -1;
    783          /* Copy audio to the channel(s) where it belongs */
    784          while ( (chan = get_mono_channel(&st->layout, s, prev)) != -1)
    785          {
    786             (*copy_channel_out)(pcm, st->layout.nb_channels, chan,
    787                buf, 1, frame_size);
    788             prev = chan;
    789          }
    790       }
    791    }
    792    /* Handle muted channels */
    793    for (c=0;c<st->layout.nb_channels;c++)
    794    {
    795       if (st->layout.mapping[c] == 255)
    796       {
    797          (*copy_channel_out)(pcm, st->layout.nb_channels, c,
    798             NULL, 0, frame_size);
    799       }
    800    }
    801    RESTORE_STACK;
    802    return frame_size;
    803 }
    804 
    805 #if !defined(DISABLE_FLOAT_API)
    806 static void opus_copy_channel_out_float(
    807   void *dst,
    808   int dst_stride,
    809   int dst_channel,
    810   const opus_val16 *src,
    811   int src_stride,
    812   int frame_size
    813 )
    814 {
    815    float *float_dst;
    816    int i;
    817    float_dst = (float*)dst;
    818    if (src != NULL)
    819    {
    820       for (i=0;i<frame_size;i++)
    821 #if defined(FIXED_POINT)
    822          float_dst[i*dst_stride+dst_channel] = (1/32768.f)*src[i*src_stride];
    823 #else
    824          float_dst[i*dst_stride+dst_channel] = src[i*src_stride];
    825 #endif
    826    }
    827    else
    828    {
    829       for (i=0;i<frame_size;i++)
    830          float_dst[i*dst_stride+dst_channel] = 0;
    831    }
    832 }
    833 #endif
    834 
    835 static void opus_copy_channel_out_short(
    836   void *dst,
    837   int dst_stride,
    838   int dst_channel,
    839   const opus_val16 *src,
    840   int src_stride,
    841   int frame_size
    842 )
    843 {
    844    opus_int16 *short_dst;
    845    int i;
    846    short_dst = (opus_int16*)dst;
    847    if (src != NULL)
    848    {
    849       for (i=0;i<frame_size;i++)
    850 #if defined(FIXED_POINT)
    851          short_dst[i*dst_stride+dst_channel] = src[i*src_stride];
    852 #else
    853          short_dst[i*dst_stride+dst_channel] = FLOAT2INT16(src[i*src_stride]);
    854 #endif
    855    }
    856    else
    857    {
    858       for (i=0;i<frame_size;i++)
    859          short_dst[i*dst_stride+dst_channel] = 0;
    860    }
    861 }
    862 
    863 
    864 
    865 #ifdef FIXED_POINT
    866 int opus_multistream_decode(
    867       OpusMSDecoder *st,
    868       const unsigned char *data,
    869       opus_int32 len,
    870       opus_int16 *pcm,
    871       int frame_size,
    872       int decode_fec
    873 )
    874 {
    875    return opus_multistream_decode_native(st, data, len,
    876        pcm, opus_copy_channel_out_short, frame_size, decode_fec);
    877 }
    878 
    879 #ifndef DISABLE_FLOAT_API
    880 int opus_multistream_decode_float(OpusMSDecoder *st, const unsigned char *data,
    881       opus_int32 len, float *pcm, int frame_size, int decode_fec)
    882 {
    883    return opus_multistream_decode_native(st, data, len,
    884        pcm, opus_copy_channel_out_float, frame_size, decode_fec);
    885 }
    886 #endif
    887 
    888 #else
    889 
    890 int opus_multistream_decode(OpusMSDecoder *st, const unsigned char *data,
    891       opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec)
    892 {
    893    return opus_multistream_decode_native(st, data, len,
    894        pcm, opus_copy_channel_out_short, frame_size, decode_fec);
    895 }
    896 
    897 int opus_multistream_decode_float(
    898       OpusMSDecoder *st,
    899       const unsigned char *data,
    900       opus_int32 len,
    901       float *pcm,
    902       int frame_size,
    903       int decode_fec
    904 )
    905 {
    906    return opus_multistream_decode_native(st, data, len,
    907        pcm, opus_copy_channel_out_float, frame_size, decode_fec);
    908 }
    909 #endif
    910 
    911 int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...)
    912 {
    913    va_list ap;
    914    int coupled_size, mono_size;
    915    char *ptr;
    916    int ret = OPUS_OK;
    917 
    918    va_start(ap, request);
    919 
    920    coupled_size = opus_decoder_get_size(2);
    921    mono_size = opus_decoder_get_size(1);
    922    ptr = (char*)st + align(sizeof(OpusMSDecoder));
    923    switch (request)
    924    {
    925        case OPUS_GET_BANDWIDTH_REQUEST:
    926        case OPUS_GET_SAMPLE_RATE_REQUEST:
    927        case OPUS_GET_GAIN_REQUEST:
    928        case OPUS_GET_LAST_PACKET_DURATION_REQUEST:
    929        {
    930           OpusDecoder *dec;
    931           /* For int32* GET params, just query the first stream */
    932           opus_int32 *value = va_arg(ap, opus_int32*);
    933           dec = (OpusDecoder*)ptr;
    934           ret = opus_decoder_ctl(dec, request, value);
    935        }
    936        break;
    937        case OPUS_GET_FINAL_RANGE_REQUEST:
    938        {
    939           int s;
    940           opus_uint32 *value = va_arg(ap, opus_uint32*);
    941           opus_uint32 tmp;
    942           *value = 0;
    943           for (s=0;s<st->layout.nb_streams;s++)
    944           {
    945              OpusDecoder *dec;
    946              dec = (OpusDecoder*)ptr;
    947              if (s < st->layout.nb_coupled_streams)
    948                 ptr += align(coupled_size);
    949              else
    950                 ptr += align(mono_size);
    951              ret = opus_decoder_ctl(dec, request, &tmp);
    952              if (ret != OPUS_OK) break;
    953              *value ^= tmp;
    954           }
    955        }
    956        break;
    957        case OPUS_RESET_STATE:
    958        {
    959           int s;
    960           for (s=0;s<st->layout.nb_streams;s++)
    961           {
    962              OpusDecoder *dec;
    963 
    964              dec = (OpusDecoder*)ptr;
    965              if (s < st->layout.nb_coupled_streams)
    966                 ptr += align(coupled_size);
    967              else
    968                 ptr += align(mono_size);
    969              ret = opus_decoder_ctl(dec, OPUS_RESET_STATE);
    970              if (ret != OPUS_OK)
    971                 break;
    972           }
    973        }
    974        break;
    975        case OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST:
    976        {
    977           int s;
    978           opus_int32 stream_id;
    979           OpusDecoder **value;
    980           stream_id = va_arg(ap, opus_int32);
    981           if (stream_id<0 || stream_id >= st->layout.nb_streams)
    982              ret = OPUS_BAD_ARG;
    983           value = va_arg(ap, OpusDecoder**);
    984           for (s=0;s<stream_id;s++)
    985           {
    986              if (s < st->layout.nb_coupled_streams)
    987                 ptr += align(coupled_size);
    988              else
    989                 ptr += align(mono_size);
    990           }
    991           *value = (OpusDecoder*)ptr;
    992        }
    993        break;
    994        case OPUS_SET_GAIN_REQUEST:
    995        {
    996           int s;
    997           /* This works for int32 params */
    998           opus_int32 value = va_arg(ap, opus_int32);
    999           for (s=0;s<st->layout.nb_streams;s++)
   1000           {
   1001              OpusDecoder *dec;
   1002 
   1003              dec = (OpusDecoder*)ptr;
   1004              if (s < st->layout.nb_coupled_streams)
   1005                 ptr += align(coupled_size);
   1006              else
   1007                 ptr += align(mono_size);
   1008              ret = opus_decoder_ctl(dec, request, value);
   1009              if (ret != OPUS_OK)
   1010                 break;
   1011           }
   1012        }
   1013        break;
   1014        default:
   1015           ret = OPUS_UNIMPLEMENTED;
   1016        break;
   1017    }
   1018 
   1019    va_end(ap);
   1020    return ret;
   1021 }
   1022 
   1023 
   1024 void opus_multistream_decoder_destroy(OpusMSDecoder *st)
   1025 {
   1026     opus_free(st);
   1027 }
   1028