Making the sampling rate an int32 in the multi-stream API
[opus.git] / src / opus_multistream.c
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 FOUNDATION OR
19    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
59 #ifdef FIXED_POINT
60 #define opus_encode_native opus_encode
61 #else
62 #define opus_encode_native opus_encode_float
63 #endif
64
65 static int validate_layout(const ChannelLayout *layout)
66 {
67    int i, max_channel;
68
69    max_channel = layout->nb_streams+layout->nb_coupled_streams;
70    if (max_channel>255)
71       return 0;
72    for (i=0;i<layout->nb_channels;i++)
73    {
74       if (layout->mapping[i] >= max_channel && layout->mapping[i] != 255)
75          return 0;
76    }
77    return 1;
78 }
79
80
81 static int get_left_channel(const ChannelLayout *layout, int stream_id, int prev)
82 {
83    int i;
84    i = (prev<0) ? 0 : prev+1;
85    for (;i<layout->nb_channels;i++)
86    {
87       if (layout->mapping[i]==stream_id*2)
88          return i;
89    }
90    return -1;
91 }
92
93 static int get_right_channel(const ChannelLayout *layout, int stream_id, int prev)
94 {
95    int i;
96    i = (prev<0) ? 0 : prev+1;
97    for (;i<layout->nb_channels;i++)
98    {
99       if (layout->mapping[i]==stream_id*2+1)
100          return i;
101    }
102    return -1;
103 }
104
105 static int get_mono_channel(const ChannelLayout *layout, int stream_id, int prev)
106 {
107    int i;
108    i = (prev<0) ? 0 : prev+1;
109    for (;i<layout->nb_channels;i++)
110    {
111       if (layout->mapping[i]==2*layout->nb_coupled_streams+stream_id)
112          return i;
113    }
114    return -1;
115 }
116
117 static int validate_encoder_layout(const ChannelLayout *layout)
118 {
119    int s;
120    for (s=0;s<layout->nb_streams;s++)
121    {
122       if (s < layout->nb_coupled_streams)
123       {
124          if (get_left_channel(layout, s, -1)==-1)
125             return 0;
126          if (get_right_channel(layout, s, -1)==-1)
127             return 0;
128       } else {
129          if (get_mono_channel(layout, s, -1)==-1)
130             return 0;
131       }
132    }
133    return 1;
134 }
135
136 int opus_multistream_encoder_get_size(int nb_streams, int nb_coupled_streams)
137 {
138         int coupled_size;
139         int mono_size;
140
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,            /* Encoder state */
152       opus_int32 Fs,                     /* Sampling rate of input signal (Hz) */
153       int channels,               /* Number of channels (1/2) in input signal */
154       int streams,
155       int coupled_streams,
156       unsigned char *mapping,
157       int application             /* Coding mode (OPUS_APPLICATION_VOIP/OPUS_APPLICATION_AUDIO) */
158 )
159 {
160    int coupled_size;
161    int mono_size;
162    int i;
163    char *ptr;
164
165    st->layout.nb_channels = channels;
166    st->layout.nb_streams = streams;
167    st->layout.nb_coupled_streams = coupled_streams;
168
169    for (i=0;i<st->layout.nb_channels;i++)
170       st->layout.mapping[i] = mapping[i];
171    if (!validate_layout(&st->layout) || !validate_encoder_layout(&st->layout))
172       return OPUS_BAD_ARG;
173    ptr = (char*)st + align(sizeof(OpusMSEncoder));
174    coupled_size = opus_encoder_get_size(2);
175    mono_size = opus_encoder_get_size(1);
176
177    for (i=0;i<st->layout.nb_coupled_streams;i++)
178    {
179       opus_encoder_init((OpusEncoder*)ptr, Fs, 2, application);
180       ptr += align(coupled_size);
181    }
182    for (;i<st->layout.nb_streams;i++)
183    {
184       opus_encoder_init((OpusEncoder*)ptr, Fs, 1, application);
185       ptr += align(mono_size);
186    }
187    return OPUS_OK;
188 }
189
190 OpusMSEncoder *opus_multistream_encoder_create(
191       opus_int32 Fs,                     /* Sampling rate of input signal (Hz) */
192       int channels,               /* Number of channels (1/2) in input signal */
193       int streams,
194       int coupled_streams,
195       unsigned char *mapping,
196       int application,            /* Coding mode (OPUS_APPLICATION_VOIP/OPUS_APPLICATION_AUDIO) */
197       int *error                  /* Error code */
198 )
199 {
200    int ret;
201    OpusMSEncoder *st = (OpusMSEncoder *)opus_alloc(opus_multistream_encoder_get_size(streams, coupled_streams));
202    if (st==NULL)
203    {
204       if (error)
205          *error = OPUS_ALLOC_FAIL;
206       return NULL;
207    }
208    ret = opus_multistream_encoder_init(st, Fs, channels, streams, coupled_streams, mapping, application);
209    if (ret != OPUS_OK)
210    {
211       opus_free(st);
212       st = NULL;
213    }
214    if (error)
215       *error = ret;
216    return st;
217 }
218
219
220 #ifdef FIXED_POINT
221 int opus_multistream_encode(
222 #else
223 int opus_multistream_encode_float(
224 #endif
225     OpusMSEncoder *st,            /* Encoder state */
226     const opus_val16 *pcm,      /* Input signal (interleaved if 2 channels). length is frame_size*channels */
227     int frame_size,             /* Number of samples per frame of input signal */
228     unsigned char *data,        /* Output payload (no more than max_data_bytes long) */
229     int max_data_bytes          /* Allocated memory for payload; don't use for controlling bitrate */
230 )
231 {
232    int coupled_size;
233    int mono_size;
234    int s, i;
235    char *ptr;
236    int tot_size;
237    VARDECL(opus_val16, buf);
238    unsigned char tmp_data[1276];
239    ALLOC_STACK;
240
241    ALLOC(buf, 2*frame_size, opus_val16);
242    ptr = (char*)st + align(sizeof(OpusMSEncoder));
243    coupled_size = opus_encoder_get_size(2);
244    mono_size = opus_encoder_get_size(1);
245
246    if (max_data_bytes < 2*st->layout.nb_streams-1)
247    {
248       RESTORE_STACK;
249       return OPUS_BUFFER_TOO_SMALL;
250    }
251    /* Counting ToC */
252    tot_size = 0;
253    for (s=0;s<st->layout.nb_streams;s++)
254    {
255       OpusEncoder *enc;
256       int len;
257       int curr_max;
258
259       enc = (OpusEncoder*)ptr;
260       if (s < st->layout.nb_coupled_streams)
261       {
262          int left, right;
263          left = get_left_channel(&st->layout, s, -1);
264          right = get_right_channel(&st->layout, s, -1);
265          for (i=0;i<frame_size;i++)
266          {
267             buf[2*i] = pcm[st->layout.nb_channels*i+left];
268             buf[2*i+1] = pcm[st->layout.nb_channels*i+right];
269          }
270          ptr += align(coupled_size);
271       } else {
272          int chan = get_mono_channel(&st->layout, s, -1);
273          for (i=0;i<frame_size;i++)
274             buf[i] = pcm[st->layout.nb_channels*i+chan];
275          ptr += align(mono_size);
276       }
277       /* number of bytes left (+Toc) */
278       curr_max = max_data_bytes - tot_size;
279       /* Reserve one byte for the last stream and 2 for the others */
280       curr_max -= 2*(st->layout.nb_streams-s)-1;
281       len = opus_encode_native(enc, buf, frame_size, tmp_data, curr_max);
282       if (len<0)
283       {
284          RESTORE_STACK;
285          return len;
286       }
287       /* ToC first */
288       *data++ = tmp_data[0];
289       if (s != st->layout.nb_streams-1)
290       {
291          int tmp = encode_size(len-1, data);
292          data += tmp;
293          tot_size += tmp;
294       }
295       /* IMPORTANT: Here we assume that the encoder only returned one frame */
296       tot_size += len;
297       OPUS_COPY(data, &tmp_data[1], len-1);
298    }
299    RESTORE_STACK;
300    return tot_size;
301
302 }
303
304 #ifdef FIXED_POINT
305
306 #ifndef DISABLE_FLOAT_API
307 int opus_multistream_encode_float(
308     OpusMSEncoder *st,          /* Encoder state */
309     const float *pcm,           /* Input signal (interleaved if 2 channels). length is frame_size*channels */
310     int frame_size,             /* Number of samples per frame of input signal */
311     unsigned char *data,        /* Output payload (no more than max_data_bytes long) */
312     int max_data_bytes          /* Allocated memory for payload; don't use for controlling bitrate */
313 )
314 {
315    int i, ret;
316    VARDECL(opus_int16, in);
317    ALLOC_STACK;
318
319    ALLOC(in, frame_size*st->layout.nb_channels, opus_int16);
320
321    for (i=0;i<frame_size*st->layout.nb_channels;i++)
322       in[i] = FLOAT2INT16(pcm[i]);
323    ret = opus_multistream_encode(st, in, frame_size, data, max_data_bytes);
324    RESTORE_STACK;
325    return ret;
326 }
327 #endif
328
329 #else
330
331 int opus_multistream_encode(
332     OpusMSEncoder *st,          /* Encoder state */
333     const opus_int16 *pcm,      /* Input signal (interleaved if 2 channels). length is frame_size*channels */
334     int frame_size,             /* Number of samples per frame of input signal */
335     unsigned char *data,        /* Output payload (no more than max_data_bytes long) */
336     int max_data_bytes          /* Allocated memory for payload; don't use for controlling bitrate */
337 )
338 {
339    int i, ret;
340    VARDECL(float, in);
341    ALLOC_STACK;
342
343    ALLOC(in, frame_size*st->layout.nb_channels, float);
344
345    for (i=0;i<frame_size*st->layout.nb_channels;i++)
346       in[i] = (1./32768)*pcm[i];
347    ret = opus_multistream_encode_float(st, in, frame_size, data, max_data_bytes);
348    RESTORE_STACK;
349    return ret;
350 }
351
352 #endif
353
354 int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
355 {
356    va_list ap;
357    int coupled_size, mono_size;
358    char *ptr;
359    int ret = OPUS_OK;
360
361    va_start(ap, request);
362
363    coupled_size = opus_encoder_get_size(2);
364    mono_size = opus_encoder_get_size(1);
365    ptr = (char*)st + align(sizeof(OpusMSEncoder));
366    switch (request)
367    {
368    case OPUS_SET_BITRATE_REQUEST:
369    {
370       int chan, s;
371       opus_uint32 value = va_arg(ap, opus_uint32);
372       chan = st->layout.nb_streams + st->layout.nb_coupled_streams;
373       value /= chan;
374       for (s=0;s<st->layout.nb_streams;s++)
375       {
376          OpusEncoder *enc;
377          enc = (OpusEncoder*)ptr;
378          opus_encoder_ctl(enc, request, value * (s < st->layout.nb_coupled_streams ? 2 : 1));
379       }
380    }
381    break;
382    /* FIXME: Add missing ones */
383    case OPUS_GET_BITRATE_REQUEST:
384    case OPUS_GET_VBR_REQUEST:
385    case OPUS_GET_APPLICATION_REQUEST:
386    case OPUS_GET_BANDWIDTH_REQUEST:
387    case OPUS_GET_COMPLEXITY_REQUEST:
388    case OPUS_GET_PACKET_LOSS_PERC_REQUEST:
389    case OPUS_GET_DTX_REQUEST:
390    case OPUS_GET_VOICE_RATIO_REQUEST:
391    case OPUS_GET_VBR_CONSTRAINT_REQUEST:
392    case OPUS_GET_SIGNAL_REQUEST:
393    case OPUS_GET_LOOKAHEAD_REQUEST:
394    {
395       int s;
396       /* This works for int32* params */
397       opus_uint32 *value = va_arg(ap, opus_uint32*);
398       for (s=0;s<st->layout.nb_streams;s++)
399       {
400          OpusEncoder *enc;
401
402          enc = (OpusEncoder*)ptr;
403          if (s < st->layout.nb_coupled_streams)
404             ptr += align(coupled_size);
405          else
406             ptr += align(mono_size);
407          ret = opus_encoder_ctl(enc, request, value);
408          if (ret < 0)
409             break;
410       }
411    }
412    break;
413    default:
414    {
415       int s;
416       /* This works for int32 params */
417       opus_uint32 value = va_arg(ap, opus_uint32);
418       for (s=0;s<st->layout.nb_streams;s++)
419       {
420          OpusEncoder *enc;
421
422          enc = (OpusEncoder*)ptr;
423          if (s < st->layout.nb_coupled_streams)
424             ptr += align(coupled_size);
425          else
426             ptr += align(mono_size);
427          ret = opus_encoder_ctl(enc, request, value);
428          if (ret < 0)
429             break;
430       }
431    }
432    break;
433    }
434
435    va_end(ap);
436    return ret;
437 }
438
439 void opus_multistream_encoder_destroy(OpusMSEncoder *st)
440 {
441     opus_free(st);
442 }
443
444
445 /* DECODER */
446
447 int opus_multistream_decoder_get_size(int nb_streams, int nb_coupled_streams)
448 {
449    int coupled_size;
450    int mono_size;
451
452    coupled_size = opus_decoder_get_size(2);
453    mono_size = opus_decoder_get_size(1);
454    return align(sizeof(OpusMSDecoder))
455          + nb_coupled_streams * align(coupled_size)
456          + (nb_streams-nb_coupled_streams) * align(mono_size);
457 }
458
459 int opus_multistream_decoder_init(
460       OpusMSDecoder *st,            /* Encoder state */
461       opus_int32 Fs,                     /* Sampling rate of input signal (Hz) */
462       int channels,               /* Number of channels (1/2) in input signal */
463       int streams,
464       int coupled_streams,
465       unsigned char *mapping
466 )
467 {
468    int coupled_size;
469    int mono_size;
470    int i;
471    char *ptr;
472
473    st->layout.nb_channels = channels;
474    st->layout.nb_streams = streams;
475    st->layout.nb_coupled_streams = coupled_streams;
476
477    for (i=0;i<st->layout.nb_channels;i++)
478       st->layout.mapping[i] = mapping[i];
479    if (!validate_layout(&st->layout))
480       return OPUS_BAD_ARG;
481
482    ptr = (char*)st + align(sizeof(OpusMSEncoder));
483    coupled_size = opus_decoder_get_size(2);
484    mono_size = opus_decoder_get_size(1);
485
486    for (i=0;i<st->layout.nb_coupled_streams;i++)
487    {
488       opus_decoder_init((OpusDecoder*)ptr, Fs, 2);
489       ptr += align(coupled_size);
490    }
491    for (;i<st->layout.nb_streams;i++)
492    {
493       opus_decoder_init((OpusDecoder*)ptr, Fs, 1);
494       ptr += align(mono_size);
495    }
496    return OPUS_OK;
497 }
498
499
500 OpusMSDecoder *opus_multistream_decoder_create(
501       opus_int32 Fs,                     /* Sampling rate of input signal (Hz) */
502       int channels,               /* Number of channels (1/2) in input signal */
503       int streams,
504       int coupled_streams,
505       unsigned char *mapping,
506       int *error                  /* Error code */
507 )
508 {
509    int ret;
510    OpusMSDecoder *st = (OpusMSDecoder *)opus_alloc(opus_multistream_decoder_get_size(streams, coupled_streams));
511    if (st==NULL)
512    {
513       if (error)
514          *error = OPUS_ALLOC_FAIL;
515       return NULL;
516    }
517    ret = opus_multistream_decoder_init(st, Fs, channels, streams, coupled_streams, mapping);
518    if (error)
519       *error = ret;
520    if (ret != OPUS_OK)
521    {
522       opus_free(st);
523       st = NULL;
524    }
525    return st;
526
527
528 }
529
530 static int opus_multistream_decode_native(
531       OpusMSDecoder *st,            /* Encoder state */
532       const unsigned char *data,
533       int len,
534       opus_val16 *pcm,
535       int frame_size,
536       int decode_fec
537 )
538 {
539    int coupled_size;
540    int mono_size;
541    int s, i, c;
542    char *ptr;
543    VARDECL(opus_val16, buf);
544    ALLOC_STACK;
545
546    ALLOC(buf, 2*frame_size, opus_val16);
547    ptr = (char*)st + align(sizeof(OpusMSEncoder));
548    coupled_size = opus_decoder_get_size(2);
549    mono_size = opus_decoder_get_size(1);
550
551    if (len < 2*st->layout.nb_streams-1)
552       return OPUS_BUFFER_TOO_SMALL;
553    for (s=0;s<st->layout.nb_streams;s++)
554    {
555       OpusDecoder *dec;
556       int packet_offset, ret;
557
558       dec = (OpusDecoder*)ptr;
559       ptr += (s < st->layout.nb_coupled_streams) ? align(coupled_size) : align(mono_size);
560
561       if (len<=0)
562       {
563          RESTORE_STACK;
564          return OPUS_INVALID_PACKET;
565       }
566       ret = opus_decode_native(dec, data, len, buf, frame_size, decode_fec, 1, &packet_offset);
567       data += packet_offset;
568       len -= packet_offset;
569       if (ret > frame_size)
570       {
571          RESTORE_STACK;
572          return OPUS_BUFFER_TOO_SMALL;
573       }
574       if (s>0 && ret != frame_size)
575       {
576          RESTORE_STACK;
577          return OPUS_INVALID_PACKET;
578       }
579       if (ret <= 0)
580       {
581          RESTORE_STACK;
582          return ret;
583       }
584       frame_size = ret;
585       if (s < st->layout.nb_coupled_streams)
586       {
587          int chan, prev;
588          prev = -1;
589          /* Copy "left" audio to the channel(s) where it belongs */
590          while ( (chan = get_left_channel(&st->layout, s, prev)) != -1)
591          {
592             for (i=0;i<frame_size;i++)
593                pcm[st->layout.nb_channels*i+chan] = buf[2*i];
594             prev = chan;
595          }
596          prev = -1;
597          /* Copy "right" audio to the channel(s) where it belongs */
598          while ( (chan = get_right_channel(&st->layout, s, prev)) != -1)
599          {
600             for (i=0;i<frame_size;i++)
601                pcm[st->layout.nb_channels*i+chan] = buf[2*i+1];
602             prev = chan;
603          }
604       } else {
605          int chan, prev;
606          prev = -1;
607          /* Copy audio to the channel(s) where it belongs */
608          while ( (chan = get_mono_channel(&st->layout, s, prev)) != -1)
609          {
610             for (i=0;i<frame_size;i++)
611                pcm[st->layout.nb_channels*i+chan] = buf[i];
612             prev = chan;
613          }
614       }
615    }
616    /* Handle muted channels */
617    for (c=0;c<st->layout.nb_channels;c++)
618    {
619       if (st->layout.mapping[c] == 255)
620       {
621          for (i=0;i<frame_size;i++)
622             pcm[st->layout.nb_channels*i+c] = 0;
623       }
624    }
625    RESTORE_STACK;
626    return frame_size;
627 }
628
629 #ifdef FIXED_POINT
630 int opus_multistream_decode(
631       OpusMSDecoder *st,            /* Encoder state */
632       const unsigned char *data,
633       int len,
634       opus_int16 *pcm,
635       int frame_size,
636       int decode_fec
637 )
638 {
639    return opus_multistream_decode_native(st, data, len, pcm, frame_size, decode_fec);
640 }
641
642 #ifndef DISABLE_FLOAT_API
643 int opus_multistream_decode_float(OpusMSDecoder *st, const unsigned char *data,
644       int len, float *pcm, int frame_size, int decode_fec)
645 {
646    VARDECL(opus_int16, out);
647    int ret, i;
648    ALLOC_STACK;
649
650    ALLOC(out, frame_size*st->layout.nb_channels, opus_int16);
651
652    ret = opus_multistream_decode_native(st, data, len, out, frame_size, decode_fec);
653    if (ret > 0)
654    {
655       for (i=0;i<ret*st->layout.nb_channels;i++)
656          pcm[i] = (1./32768.)*(out[i]);
657    }
658    RESTORE_STACK;
659    return ret;
660 }
661 #endif
662
663 #else
664
665 int opus_multistream_decode(OpusMSDecoder *st, const unsigned char *data,
666       int len, opus_int16 *pcm, int frame_size, int decode_fec)
667 {
668    VARDECL(float, out);
669    int ret, i;
670    ALLOC_STACK;
671
672    ALLOC(out, frame_size*st->layout.nb_channels, float);
673
674    ret = opus_multistream_decode_native(st, data, len, out, frame_size, decode_fec);
675    if (ret > 0)
676    {
677       for (i=0;i<ret*st->layout.nb_channels;i++)
678          pcm[i] = FLOAT2INT16(out[i]);
679    }
680    RESTORE_STACK;
681    return ret;
682 }
683
684 int opus_multistream_decode_float(
685       OpusMSDecoder *st,            /* Encoder state */
686       const unsigned char *data,
687       int len,
688       float *pcm,
689       int frame_size,
690       int decode_fec
691 )
692 {
693    return opus_multistream_decode_native(st, data, len, pcm, frame_size, decode_fec);
694 }
695 #endif
696
697 int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...)
698 {
699    va_list ap;
700    int coupled_size, mono_size;
701    char *ptr;
702    int ret = OPUS_OK;
703
704    va_start(ap, request);
705
706    coupled_size = opus_decoder_get_size(2);
707    mono_size = opus_decoder_get_size(1);
708    ptr = (char*)st + align(sizeof(OpusMSDecoder));
709    switch (request)
710    {
711        default:
712        {
713           int s;
714           /* This only works for int32* params, but that's all we have right now */
715           opus_uint32 *value = va_arg(ap, opus_uint32*);
716           for (s=0;s<st->layout.nb_streams;s++)
717           {
718              OpusDecoder *enc;
719
720              enc = (OpusDecoder*)ptr;
721              if (s < st->layout.nb_coupled_streams)
722                 ptr += align(coupled_size);
723              else
724                 ptr += align(mono_size);
725              ret = opus_decoder_ctl(enc, request, value);
726              if (ret < 0)
727                 break;
728           }
729        }
730        break;
731    }
732
733    va_end(ap);
734    return ret;
735 }
736
737
738 void opus_multistream_decoder_destroy(OpusMSDecoder *st)
739 {
740     opus_free(st);
741 }