Adds support for all Vorbis mappings
[opus.git] / src / opus_multistream_encoder.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 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 "analysis.h"
40
41 typedef struct {
42    int nb_streams;
43    int nb_coupled_streams;
44    unsigned char mapping[8];
45 } VorbisLayout;
46
47 /* Index is nb_channel-1*/
48 static const VorbisLayout vorbis_mappings[8] = {
49       {1, 0, {0}},                      /* 1: mono */
50       {1, 1, {0, 1}},                   /* 2: stereo */
51       {2, 1, {0, 2, 1}},                /* 3: 1-d surround */
52       {2, 2, {0, 1, 2, 3}},             /* 4: quadraphonic surround */
53       {3, 2, {0, 4, 1, 2, 3}},          /* 5: 5-channel surround */
54       {4, 2, {0, 4, 1, 2, 3, 5}},       /* 6: 5.1 surround */
55       {4, 3, {0, 4, 1, 2, 3, 5, 6}},    /* 7: 6.1 surround */
56       {5, 3, {0, 6, 1, 2, 3, 4, 5, 7}}, /* 8: 7.1 surround */
57 };
58
59 struct OpusMSEncoder {
60    TonalityAnalysisState analysis;
61    ChannelLayout layout;
62    int lfe_stream;
63    int variable_duration;
64    opus_int32 bitrate_bps;
65    opus_val32 subframe_mem[3];
66    /* Encoder states go here */
67 };
68
69
70 static int validate_encoder_layout(const ChannelLayout *layout)
71 {
72    int s;
73    for (s=0;s<layout->nb_streams;s++)
74    {
75       if (s < layout->nb_coupled_streams)
76       {
77          if (get_left_channel(layout, s, -1)==-1)
78             return 0;
79          if (get_right_channel(layout, s, -1)==-1)
80             return 0;
81       } else {
82          if (get_mono_channel(layout, s, -1)==-1)
83             return 0;
84       }
85    }
86    return 1;
87 }
88
89
90 opus_int32 opus_multistream_encoder_get_size(int nb_streams, int nb_coupled_streams)
91 {
92    int coupled_size;
93    int mono_size;
94
95    if(nb_streams<1||nb_coupled_streams>nb_streams||nb_coupled_streams<0)return 0;
96    coupled_size = opus_encoder_get_size(2);
97    mono_size = opus_encoder_get_size(1);
98    return align(sizeof(OpusMSEncoder))
99         + nb_coupled_streams * align(coupled_size)
100         + (nb_streams-nb_coupled_streams) * align(mono_size);
101 }
102
103 opus_int32 opus_multistream_surround_encoder_get_size(int channels, int mapping_family)
104 {
105    int nb_streams;
106    int nb_coupled_streams;
107
108    if (mapping_family==0)
109    {
110       if (channels==1)
111       {
112          nb_streams=1;
113          nb_coupled_streams=0;
114       } else if (channels==2)
115       {
116          nb_streams=1;
117          nb_coupled_streams=1;
118       } else
119          return 0;
120    } else if (mapping_family==1 && channels<=8 && channels>=1)
121    {
122       nb_streams=vorbis_mappings[channels-1].nb_streams;
123       nb_coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams;
124    } else if (mapping_family==255)
125    {
126       nb_streams=channels;
127       nb_coupled_streams=0;
128    } else
129       return 0;
130    return opus_multistream_encoder_get_size(nb_streams, nb_coupled_streams);
131 }
132
133
134 static int opus_multistream_encoder_init_impl(
135       OpusMSEncoder *st,
136       opus_int32 Fs,
137       int channels,
138       int streams,
139       int coupled_streams,
140       const unsigned char *mapping,
141       int application,
142       int surround
143 )
144 {
145    int coupled_size;
146    int mono_size;
147    int i, ret;
148    char *ptr;
149
150    if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
151        (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0))
152       return OPUS_BAD_ARG;
153
154    st->layout.nb_channels = channels;
155    st->layout.nb_streams = streams;
156    st->layout.nb_coupled_streams = coupled_streams;
157    st->subframe_mem[0]=st->subframe_mem[1]=st->subframe_mem[2]=0;
158    OPUS_CLEAR(&st->analysis,1);
159    if (!surround)
160       st->lfe_stream = -1;
161    st->bitrate_bps = OPUS_AUTO;
162    st->variable_duration = OPUS_FRAMESIZE_ARG;
163    for (i=0;i<st->layout.nb_channels;i++)
164       st->layout.mapping[i] = mapping[i];
165    if (!validate_layout(&st->layout) || !validate_encoder_layout(&st->layout))
166       return OPUS_BAD_ARG;
167    ptr = (char*)st + align(sizeof(OpusMSEncoder));
168    coupled_size = opus_encoder_get_size(2);
169    mono_size = opus_encoder_get_size(1);
170
171    for (i=0;i<st->layout.nb_coupled_streams;i++)
172    {
173       ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 2, application);
174       if (i==st->lfe_stream)
175          opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1));
176       if(ret!=OPUS_OK)return ret;
177       ptr += align(coupled_size);
178    }
179    for (;i<st->layout.nb_streams;i++)
180    {
181       ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 1, application);
182       if (i==st->lfe_stream)
183          opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1));
184       if(ret!=OPUS_OK)return ret;
185       ptr += align(mono_size);
186    }
187    return OPUS_OK;
188 }
189
190 int opus_multistream_encoder_init(
191       OpusMSEncoder *st,
192       opus_int32 Fs,
193       int channels,
194       int streams,
195       int coupled_streams,
196       const unsigned char *mapping,
197       int application
198 )
199 {
200    return opus_multistream_encoder_init_impl(st, Fs, channels, streams, coupled_streams, mapping, application, 0);
201 }
202
203 int opus_multistream_surround_encoder_init(
204       OpusMSEncoder *st,
205       opus_int32 Fs,
206       int channels,
207       int mapping_family,
208       int *streams,
209       int *coupled_streams,
210       unsigned char *mapping,
211       int application
212 )
213 {
214    st->lfe_stream = -1;
215    if (mapping_family==0)
216    {
217       if (channels==1)
218       {
219          *streams=1;
220          *coupled_streams=0;
221          mapping[0]=0;
222       } else if (channels==2)
223       {
224          *streams=1;
225          *coupled_streams=1;
226          mapping[0]=0;
227          mapping[1]=1;
228       } else
229          return OPUS_UNIMPLEMENTED;
230    } else if (mapping_family==1 && channels<=8 && channels>=1)
231    {
232       int i;
233       *streams=vorbis_mappings[channels-1].nb_streams;
234       *coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams;
235       for (i=0;i<channels;i++)
236          mapping[i] = vorbis_mappings[channels-1].mapping[i];
237       if (channels>=6)
238          st->lfe_stream = *streams-1;
239    } else if (mapping_family==255)
240    {
241       int i;
242       *streams=channels;
243       *coupled_streams=0;
244       for(i=0;i<channels;i++)
245          mapping[i] = i;
246    } else
247       return OPUS_UNIMPLEMENTED;
248    opus_multistream_encoder_init_impl(st, Fs, channels, *streams, *coupled_streams, mapping, application, 1);
249    return OPUS_OK;
250 }
251
252 OpusMSEncoder *opus_multistream_encoder_create(
253       opus_int32 Fs,
254       int channels,
255       int streams,
256       int coupled_streams,
257       const unsigned char *mapping,
258       int application,
259       int *error
260 )
261 {
262    int ret;
263    OpusMSEncoder *st;
264    if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
265        (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0))
266    {
267       if (error)
268          *error = OPUS_BAD_ARG;
269       return NULL;
270    }
271    st = (OpusMSEncoder *)opus_alloc(opus_multistream_encoder_get_size(streams, coupled_streams));
272    if (st==NULL)
273    {
274       if (error)
275          *error = OPUS_ALLOC_FAIL;
276       return NULL;
277    }
278    ret = opus_multistream_encoder_init(st, Fs, channels, streams, coupled_streams, mapping, application);
279    if (ret != OPUS_OK)
280    {
281       opus_free(st);
282       st = NULL;
283    }
284    if (error)
285       *error = ret;
286    return st;
287 }
288
289 OpusMSEncoder *opus_multistream_surround_encoder_create(
290       opus_int32 Fs,
291       int channels,
292       int mapping_family,
293       int *streams,
294       int *coupled_streams,
295       unsigned char *mapping,
296       int application,
297       int *error
298 )
299 {
300    int ret;
301    OpusMSEncoder *st;
302    if ((channels>255) || (channels<1))
303    {
304       if (error)
305          *error = OPUS_BAD_ARG;
306       return NULL;
307    }
308    st = (OpusMSEncoder *)opus_alloc(opus_multistream_surround_encoder_get_size(channels, mapping_family));
309    if (st==NULL)
310    {
311       if (error)
312          *error = OPUS_ALLOC_FAIL;
313       return NULL;
314    }
315    ret = opus_multistream_surround_encoder_init(st, Fs, channels, mapping_family, streams, coupled_streams, mapping, application);
316    if (ret != OPUS_OK)
317    {
318       opus_free(st);
319       st = NULL;
320    }
321    if (error)
322       *error = ret;
323    return st;
324 }
325
326 typedef void (*opus_copy_channel_in_func)(
327   opus_val16 *dst,
328   int dst_stride,
329   const void *src,
330   int src_stride,
331   int src_channel,
332   int frame_size
333 );
334
335 static void surround_rate_allocation(
336       OpusMSEncoder *st,
337       opus_int32 *rate,
338       int frame_size
339       )
340 {
341    int i;
342    opus_int32 channel_rate;
343    opus_int32 Fs;
344    char *ptr;
345    int coupled_ratio; /* Q8 */
346    int lfe_ratio;     /* Q8 */
347
348    ptr = (char*)st + align(sizeof(OpusMSEncoder));
349    opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
350
351    /* Should depend on the bitrate, for now we assume coupled streams get 60% more bits than mono */
352    coupled_ratio = 410;
353    /* Should depend on the bitrate, for now we assume LFE gets 1/12 the bits of mono */
354    lfe_ratio = 32;
355
356    /* Compute bitrate allocation between streams */
357    if (st->bitrate_bps==OPUS_AUTO)
358    {
359       channel_rate = Fs+60*Fs/frame_size;
360    } else if (st->bitrate_bps==OPUS_BITRATE_MAX)
361    {
362       channel_rate = 300000;
363    } else {
364       int total = ((st->layout.nb_streams-st->layout.nb_coupled_streams-(st->lfe_stream!=-1))<<8) /* mono */
365             + coupled_ratio*st->layout.nb_coupled_streams /* stereo */
366             + (st->lfe_stream!=-1)*lfe_ratio;
367       channel_rate = 256*(st->bitrate_bps-2000)/total;
368    }
369 #ifndef FIXED_POINT
370    if (st->variable_duration==OPUS_FRAMESIZE_VARIABLE && frame_size != Fs/50)
371    {
372       opus_int32 bonus;
373       bonus = 60*(Fs/frame_size-50);
374       channel_rate += bonus;
375    }
376 #endif
377
378    for (i=0;i<st->layout.nb_streams;i++)
379    {
380       if (i<st->layout.nb_coupled_streams)
381          rate[i] = channel_rate*coupled_ratio>>8;
382       else if (i!=st->lfe_stream)
383          rate[i] = channel_rate;
384       else
385          rate[i] = 2000+(channel_rate*lfe_ratio>>8);
386    }
387
388
389 }
390
391 /* Max size in case the encoder decides to return three frames */
392 #define MS_FRAME_TMP (3*1275+7)
393 static int opus_multistream_encode_native
394 (
395     OpusMSEncoder *st,
396     opus_copy_channel_in_func copy_channel_in,
397     const void *pcm,
398     int frame_size,
399     unsigned char *data,
400     opus_int32 max_data_bytes,
401     int lsb_depth
402 #ifndef FIXED_POINT
403     , downmix_func downmix
404     , const void *pcm_analysis
405 #endif
406 )
407 {
408    opus_int32 Fs;
409    int coupled_size;
410    int mono_size;
411    int s;
412    char *ptr;
413    int tot_size;
414    VARDECL(opus_val16, buf);
415    unsigned char tmp_data[MS_FRAME_TMP];
416    OpusRepacketizer rp;
417    opus_int32 complexity;
418    AnalysisInfo analysis_info;
419    const CELTMode *celt_mode;
420    opus_int32 bitrates[256];
421    ALLOC_STACK;
422
423    ptr = (char*)st + align(sizeof(OpusMSEncoder));
424    opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
425    opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_COMPLEXITY(&complexity));
426    opus_encoder_ctl((OpusEncoder*)ptr, CELT_GET_MODE(&celt_mode));
427
428    if (400*frame_size < Fs)
429    {
430       RESTORE_STACK;
431       return OPUS_BAD_ARG;
432    }
433 #ifndef FIXED_POINT
434    analysis_info.valid = 0;
435    if (complexity >= 7 && Fs==48000)
436    {
437       opus_int32 delay_compensation;
438       int channels;
439
440       channels = st->layout.nb_streams + st->layout.nb_coupled_streams;
441       opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_LOOKAHEAD(&delay_compensation));
442       delay_compensation -= Fs/400;
443
444       frame_size = run_analysis(&st->analysis, celt_mode, pcm, pcm_analysis,
445             frame_size, st->variable_duration, channels, Fs, st->bitrate_bps, delay_compensation, lsb_depth, downmix, &analysis_info);
446    } else
447 #endif
448    {
449       frame_size = frame_size_select(frame_size, st->variable_duration, Fs);
450    }
451    /* Validate frame_size before using it to allocate stack space.
452       This mirrors the checks in opus_encode[_float](). */
453    if (400*frame_size != Fs && 200*frame_size != Fs &&
454        100*frame_size != Fs &&  50*frame_size != Fs &&
455         25*frame_size != Fs &&  50*frame_size != 3*Fs)
456    {
457       RESTORE_STACK;
458       return OPUS_BAD_ARG;
459    }
460    ALLOC(buf, 2*frame_size, opus_val16);
461    coupled_size = opus_encoder_get_size(2);
462    mono_size = opus_encoder_get_size(1);
463
464    if (max_data_bytes < 4*st->layout.nb_streams-1)
465    {
466       RESTORE_STACK;
467       return OPUS_BUFFER_TOO_SMALL;
468    }
469
470    /* Compute bitrate allocation between streams (this could be a lot better) */
471    surround_rate_allocation(st, bitrates, frame_size);
472
473    ptr = (char*)st + align(sizeof(OpusMSEncoder));
474    for (s=0;s<st->layout.nb_streams;s++)
475    {
476       OpusEncoder *enc;
477       enc = (OpusEncoder*)ptr;
478       if (s < st->layout.nb_coupled_streams)
479          ptr += align(coupled_size);
480       else
481          ptr += align(mono_size);
482       opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrates[s]));
483    }
484
485    ptr = (char*)st + align(sizeof(OpusMSEncoder));
486    /* Counting ToC */
487    tot_size = 0;
488    for (s=0;s<st->layout.nb_streams;s++)
489    {
490       OpusEncoder *enc;
491       int len;
492       int curr_max;
493
494       opus_repacketizer_init(&rp);
495       enc = (OpusEncoder*)ptr;
496       if (s < st->layout.nb_coupled_streams)
497       {
498          int left, right;
499          left = get_left_channel(&st->layout, s, -1);
500          right = get_right_channel(&st->layout, s, -1);
501          (*copy_channel_in)(buf, 2,
502             pcm, st->layout.nb_channels, left, frame_size);
503          (*copy_channel_in)(buf+1, 2,
504             pcm, st->layout.nb_channels, right, frame_size);
505          ptr += align(coupled_size);
506       } else {
507          int chan = get_mono_channel(&st->layout, s, -1);
508          (*copy_channel_in)(buf, 1,
509             pcm, st->layout.nb_channels, chan, frame_size);
510          ptr += align(mono_size);
511       }
512       /* number of bytes left (+Toc) */
513       curr_max = max_data_bytes - tot_size;
514       /* Reserve three bytes for the last stream and four for the others */
515       curr_max -= IMAX(0,4*(st->layout.nb_streams-s-1)-1);
516       curr_max = IMIN(curr_max,MS_FRAME_TMP);
517       len = opus_encode_native(enc, buf, frame_size, tmp_data, curr_max, lsb_depth
518 #ifndef FIXED_POINT
519             , &analysis_info
520 #endif
521             );
522       if (len<0)
523       {
524          RESTORE_STACK;
525          return len;
526       }
527       /* We need to use the repacketizer to add the self-delimiting lengths
528          while taking into account the fact that the encoder can now return
529          more than one frame at a time (e.g. 60 ms CELT-only) */
530       opus_repacketizer_cat(&rp, tmp_data, len);
531       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);
532       data += len;
533       tot_size += len;
534    }
535    RESTORE_STACK;
536    return tot_size;
537
538 }
539
540 #if !defined(DISABLE_FLOAT_API)
541 static void opus_copy_channel_in_float(
542   opus_val16 *dst,
543   int dst_stride,
544   const void *src,
545   int src_stride,
546   int src_channel,
547   int frame_size
548 )
549 {
550    const float *float_src;
551    opus_int32 i;
552    float_src = (const float *)src;
553    for (i=0;i<frame_size;i++)
554 #if defined(FIXED_POINT)
555       dst[i*dst_stride] = FLOAT2INT16(float_src[i*src_stride+src_channel]);
556 #else
557       dst[i*dst_stride] = float_src[i*src_stride+src_channel];
558 #endif
559 }
560 #endif
561
562 static void opus_copy_channel_in_short(
563   opus_val16 *dst,
564   int dst_stride,
565   const void *src,
566   int src_stride,
567   int src_channel,
568   int frame_size
569 )
570 {
571    const opus_int16 *short_src;
572    opus_int32 i;
573    short_src = (const opus_int16 *)src;
574    for (i=0;i<frame_size;i++)
575 #if defined(FIXED_POINT)
576       dst[i*dst_stride] = short_src[i*src_stride+src_channel];
577 #else
578       dst[i*dst_stride] = (1/32768.f)*short_src[i*src_stride+src_channel];
579 #endif
580 }
581
582 #ifdef FIXED_POINT
583 int opus_multistream_encode(
584     OpusMSEncoder *st,
585     const opus_val16 *pcm,
586     int frame_size,
587     unsigned char *data,
588     opus_int32 max_data_bytes
589 )
590 {
591    return opus_multistream_encode_native(st, opus_copy_channel_in_short,
592       pcm, frame_size, data, max_data_bytes, 16);
593 }
594
595 #ifndef DISABLE_FLOAT_API
596 int opus_multistream_encode_float(
597     OpusMSEncoder *st,
598     const float *pcm,
599     int frame_size,
600     unsigned char *data,
601     opus_int32 max_data_bytes
602 )
603 {
604    return opus_multistream_encode_native(st, opus_copy_channel_in_float,
605       pcm, frame_size, data, max_data_bytes, 16);
606 }
607 #endif
608
609 #else
610
611 int opus_multistream_encode_float
612 (
613     OpusMSEncoder *st,
614     const opus_val16 *pcm,
615     int frame_size,
616     unsigned char *data,
617     opus_int32 max_data_bytes
618 )
619 {
620    int channels = st->layout.nb_streams + st->layout.nb_coupled_streams;
621    return opus_multistream_encode_native(st, opus_copy_channel_in_float,
622       pcm, frame_size, data, max_data_bytes, 24, downmix_float, pcm+channels*st->analysis.analysis_offset);
623 }
624
625 int opus_multistream_encode(
626     OpusMSEncoder *st,
627     const opus_int16 *pcm,
628     int frame_size,
629     unsigned char *data,
630     opus_int32 max_data_bytes
631 )
632 {
633    int channels = st->layout.nb_streams + st->layout.nb_coupled_streams;
634    return opus_multistream_encode_native(st, opus_copy_channel_in_short,
635       pcm, frame_size, data, max_data_bytes, 16, downmix_int, pcm+channels*st->analysis.analysis_offset);
636 }
637 #endif
638
639 int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
640 {
641    va_list ap;
642    int coupled_size, mono_size;
643    char *ptr;
644    int ret = OPUS_OK;
645
646    va_start(ap, request);
647
648    coupled_size = opus_encoder_get_size(2);
649    mono_size = opus_encoder_get_size(1);
650    ptr = (char*)st + align(sizeof(OpusMSEncoder));
651    switch (request)
652    {
653    case OPUS_SET_BITRATE_REQUEST:
654    {
655       opus_int32 value = va_arg(ap, opus_int32);
656       if (value<0 && value!=OPUS_AUTO && value!=OPUS_BITRATE_MAX)
657          goto bad_arg;
658       st->bitrate_bps = value;
659    }
660    break;
661    case OPUS_GET_BITRATE_REQUEST:
662    {
663       int s;
664       opus_int32 *value = va_arg(ap, opus_int32*);
665       *value = 0;
666       for (s=0;s<st->layout.nb_streams;s++)
667       {
668          opus_int32 rate;
669          OpusEncoder *enc;
670          enc = (OpusEncoder*)ptr;
671          if (s < st->layout.nb_coupled_streams)
672             ptr += align(coupled_size);
673          else
674             ptr += align(mono_size);
675          opus_encoder_ctl(enc, request, &rate);
676          *value += rate;
677       }
678    }
679    break;
680    case OPUS_GET_LSB_DEPTH_REQUEST:
681    case OPUS_GET_VBR_REQUEST:
682    case OPUS_GET_APPLICATION_REQUEST:
683    case OPUS_GET_BANDWIDTH_REQUEST:
684    case OPUS_GET_COMPLEXITY_REQUEST:
685    case OPUS_GET_PACKET_LOSS_PERC_REQUEST:
686    case OPUS_GET_DTX_REQUEST:
687    case OPUS_GET_VOICE_RATIO_REQUEST:
688    case OPUS_GET_VBR_CONSTRAINT_REQUEST:
689    case OPUS_GET_SIGNAL_REQUEST:
690    case OPUS_GET_LOOKAHEAD_REQUEST:
691    case OPUS_GET_SAMPLE_RATE_REQUEST:
692    case OPUS_GET_INBAND_FEC_REQUEST:
693    case OPUS_GET_FORCE_CHANNELS_REQUEST:
694    {
695       OpusEncoder *enc;
696       /* For int32* GET params, just query the first stream */
697       opus_int32 *value = va_arg(ap, opus_int32*);
698       enc = (OpusEncoder*)ptr;
699       ret = opus_encoder_ctl(enc, request, value);
700    }
701    break;
702    case OPUS_GET_FINAL_RANGE_REQUEST:
703    {
704       int s;
705       opus_uint32 *value = va_arg(ap, opus_uint32*);
706       opus_uint32 tmp;
707       *value=0;
708       for (s=0;s<st->layout.nb_streams;s++)
709       {
710          OpusEncoder *enc;
711          enc = (OpusEncoder*)ptr;
712          if (s < st->layout.nb_coupled_streams)
713             ptr += align(coupled_size);
714          else
715             ptr += align(mono_size);
716          ret = opus_encoder_ctl(enc, request, &tmp);
717          if (ret != OPUS_OK) break;
718          *value ^= tmp;
719       }
720    }
721    break;
722    case OPUS_SET_LSB_DEPTH_REQUEST:
723    case OPUS_SET_COMPLEXITY_REQUEST:
724    case OPUS_SET_VBR_REQUEST:
725    case OPUS_SET_VBR_CONSTRAINT_REQUEST:
726    case OPUS_SET_BANDWIDTH_REQUEST:
727    case OPUS_SET_SIGNAL_REQUEST:
728    case OPUS_SET_APPLICATION_REQUEST:
729    case OPUS_SET_INBAND_FEC_REQUEST:
730    case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
731    case OPUS_SET_DTX_REQUEST:
732    case OPUS_SET_FORCE_MODE_REQUEST:
733    case OPUS_SET_FORCE_CHANNELS_REQUEST:
734    {
735       int s;
736       /* This works for int32 params */
737       opus_int32 value = va_arg(ap, opus_int32);
738       for (s=0;s<st->layout.nb_streams;s++)
739       {
740          OpusEncoder *enc;
741
742          enc = (OpusEncoder*)ptr;
743          if (s < st->layout.nb_coupled_streams)
744             ptr += align(coupled_size);
745          else
746             ptr += align(mono_size);
747          ret = opus_encoder_ctl(enc, request, value);
748          if (ret != OPUS_OK)
749             break;
750       }
751    }
752    break;
753    case OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST:
754    {
755       int s;
756       opus_int32 stream_id;
757       OpusEncoder **value;
758       stream_id = va_arg(ap, opus_int32);
759       if (stream_id<0 || stream_id >= st->layout.nb_streams)
760          ret = OPUS_BAD_ARG;
761       value = va_arg(ap, OpusEncoder**);
762       for (s=0;s<stream_id;s++)
763       {
764          if (s < st->layout.nb_coupled_streams)
765             ptr += align(coupled_size);
766          else
767             ptr += align(mono_size);
768       }
769       *value = (OpusEncoder*)ptr;
770    }
771    break;
772    case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST:
773    {
774        opus_int32 value = va_arg(ap, opus_int32);
775        st->variable_duration = value;
776    }
777    break;
778    case OPUS_GET_EXPERT_FRAME_DURATION_REQUEST:
779    {
780        opus_int32 *value = va_arg(ap, opus_int32*);
781        *value = st->variable_duration;
782    }
783    break;
784    default:
785       ret = OPUS_UNIMPLEMENTED;
786       break;
787    }
788
789    va_end(ap);
790    return ret;
791 bad_arg:
792    va_end(ap);
793    return OPUS_BAD_ARG;
794 }
795
796 void opus_multistream_encoder_destroy(OpusMSEncoder *st)
797 {
798     opus_free(st);
799 }
800
801