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