• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (c) 2011 Xiph.Org Foundation
2    Written by Jean-Marc Valin */
3 /*
4    Redistribution and use in source and binary forms, with or without
5    modification, are permitted provided that the following conditions
6    are met:
7 
8    - Redistributions of source code must retain the above copyright
9    notice, this list of conditions and the following disclaimer.
10 
11    - Redistributions in binary form must reproduce the above copyright
12    notice, this list of conditions and the following disclaimer in the
13    documentation and/or other materials provided with the distribution.
14 
15    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19    OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27 
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
31 
32 #include "opus_multistream.h"
33 #include "opus.h"
34 #include "opus_private.h"
35 #include "stack_alloc.h"
36 #include <stdarg.h>
37 #include "float_cast.h"
38 #include "os_support.h"
39 #include "mathops.h"
40 #include "mdct.h"
41 #include "modes.h"
42 #include "bands.h"
43 #include "quant_bands.h"
44 #include "pitch.h"
45 
46 typedef struct {
47    int nb_streams;
48    int nb_coupled_streams;
49    unsigned char mapping[8];
50 } VorbisLayout;
51 
52 /* Index is nb_channel-1*/
53 static const VorbisLayout vorbis_mappings[8] = {
54       {1, 0, {0}},                      /* 1: mono */
55       {1, 1, {0, 1}},                   /* 2: stereo */
56       {2, 1, {0, 2, 1}},                /* 3: 1-d surround */
57       {2, 2, {0, 1, 2, 3}},             /* 4: quadraphonic surround */
58       {3, 2, {0, 4, 1, 2, 3}},          /* 5: 5-channel surround */
59       {4, 2, {0, 4, 1, 2, 3, 5}},       /* 6: 5.1 surround */
60       {4, 3, {0, 4, 1, 2, 3, 5, 6}},    /* 7: 6.1 surround */
61       {5, 3, {0, 6, 1, 2, 3, 4, 5, 7}}, /* 8: 7.1 surround */
62 };
63 
64 typedef void (*opus_copy_channel_in_func)(
65   opus_val16 *dst,
66   int dst_stride,
67   const void *src,
68   int src_stride,
69   int src_channel,
70   int frame_size
71 );
72 
73 typedef enum {
74   MAPPING_TYPE_NONE,
75   MAPPING_TYPE_SURROUND
76 #ifdef ENABLE_EXPERIMENTAL_AMBISONICS
77   ,  /* Do not include comma at end of enumerator list */
78   MAPPING_TYPE_AMBISONICS
79 #endif
80 } MappingType;
81 
82 struct OpusMSEncoder {
83    ChannelLayout layout;
84    int arch;
85    int lfe_stream;
86    int application;
87    int variable_duration;
88    MappingType mapping_type;
89    opus_int32 bitrate_bps;
90    /* Encoder states go here */
91    /* then opus_val32 window_mem[channels*120]; */
92    /* then opus_val32 preemph_mem[channels]; */
93 };
94 
ms_get_preemph_mem(OpusMSEncoder * st)95 static opus_val32 *ms_get_preemph_mem(OpusMSEncoder *st)
96 {
97    int s;
98    char *ptr;
99    int coupled_size, mono_size;
100 
101    coupled_size = opus_encoder_get_size(2);
102    mono_size = opus_encoder_get_size(1);
103    ptr = (char*)st + align(sizeof(OpusMSEncoder));
104    for (s=0;s<st->layout.nb_streams;s++)
105    {
106       if (s < st->layout.nb_coupled_streams)
107          ptr += align(coupled_size);
108       else
109          ptr += align(mono_size);
110    }
111    /* void* cast avoids clang -Wcast-align warning */
112    return (opus_val32*)(void*)(ptr+st->layout.nb_channels*120*sizeof(opus_val32));
113 }
114 
ms_get_window_mem(OpusMSEncoder * st)115 static opus_val32 *ms_get_window_mem(OpusMSEncoder *st)
116 {
117    int s;
118    char *ptr;
119    int coupled_size, mono_size;
120 
121    coupled_size = opus_encoder_get_size(2);
122    mono_size = opus_encoder_get_size(1);
123    ptr = (char*)st + align(sizeof(OpusMSEncoder));
124    for (s=0;s<st->layout.nb_streams;s++)
125    {
126       if (s < st->layout.nb_coupled_streams)
127          ptr += align(coupled_size);
128       else
129          ptr += align(mono_size);
130    }
131    /* void* cast avoids clang -Wcast-align warning */
132    return (opus_val32*)(void*)ptr;
133 }
134 
135 #ifdef ENABLE_EXPERIMENTAL_AMBISONICS
validate_ambisonics(int nb_channels,int * nb_streams,int * nb_coupled_streams)136 static int validate_ambisonics(int nb_channels, int *nb_streams, int *nb_coupled_streams)
137 {
138    int order_plus_one;
139    int acn_channels;
140    int nondiegetic_channels;
141 
142    order_plus_one = isqrt32(nb_channels);
143    acn_channels = order_plus_one * order_plus_one;
144    nondiegetic_channels = nb_channels - acn_channels;
145 
146    if (order_plus_one < 1 || order_plus_one > 15 ||
147        (nondiegetic_channels != 0 && nondiegetic_channels != 2))
148       return 0;
149 
150    if (nb_streams)
151       *nb_streams = acn_channels + (nondiegetic_channels != 0);
152    if (nb_coupled_streams)
153       *nb_coupled_streams = nondiegetic_channels != 0;
154    return 1;
155 }
156 #endif
157 
validate_encoder_layout(const ChannelLayout * layout)158 static int validate_encoder_layout(const ChannelLayout *layout)
159 {
160    int s;
161    for (s=0;s<layout->nb_streams;s++)
162    {
163       if (s < layout->nb_coupled_streams)
164       {
165          if (get_left_channel(layout, s, -1)==-1)
166             return 0;
167          if (get_right_channel(layout, s, -1)==-1)
168             return 0;
169       } else {
170          if (get_mono_channel(layout, s, -1)==-1)
171             return 0;
172       }
173    }
174    return 1;
175 }
176 
channel_pos(int channels,int pos[8])177 static void channel_pos(int channels, int pos[8])
178 {
179    /* Position in the mix: 0 don't mix, 1: left, 2: center, 3:right */
180    if (channels==4)
181    {
182       pos[0]=1;
183       pos[1]=3;
184       pos[2]=1;
185       pos[3]=3;
186    } else if (channels==3||channels==5||channels==6)
187    {
188       pos[0]=1;
189       pos[1]=2;
190       pos[2]=3;
191       pos[3]=1;
192       pos[4]=3;
193       pos[5]=0;
194    } else if (channels==7)
195    {
196       pos[0]=1;
197       pos[1]=2;
198       pos[2]=3;
199       pos[3]=1;
200       pos[4]=3;
201       pos[5]=2;
202       pos[6]=0;
203    } else if (channels==8)
204    {
205       pos[0]=1;
206       pos[1]=2;
207       pos[2]=3;
208       pos[3]=1;
209       pos[4]=3;
210       pos[5]=1;
211       pos[6]=3;
212       pos[7]=0;
213    }
214 }
215 
216 #if 1
217 /* Computes a rough approximation of log2(2^a + 2^b) */
logSum(opus_val16 a,opus_val16 b)218 static opus_val16 logSum(opus_val16 a, opus_val16 b)
219 {
220    opus_val16 max;
221    opus_val32 diff;
222    opus_val16 frac;
223    static const opus_val16 diff_table[17] = {
224          QCONST16(0.5000000f, DB_SHIFT), QCONST16(0.2924813f, DB_SHIFT), QCONST16(0.1609640f, DB_SHIFT), QCONST16(0.0849625f, DB_SHIFT),
225          QCONST16(0.0437314f, DB_SHIFT), QCONST16(0.0221971f, DB_SHIFT), QCONST16(0.0111839f, DB_SHIFT), QCONST16(0.0056136f, DB_SHIFT),
226          QCONST16(0.0028123f, DB_SHIFT)
227    };
228    int low;
229    if (a>b)
230    {
231       max = a;
232       diff = SUB32(EXTEND32(a),EXTEND32(b));
233    } else {
234       max = b;
235       diff = SUB32(EXTEND32(b),EXTEND32(a));
236    }
237    if (!(diff < QCONST16(8.f, DB_SHIFT)))  /* inverted to catch NaNs */
238       return max;
239 #ifdef FIXED_POINT
240    low = SHR32(diff, DB_SHIFT-1);
241    frac = SHL16(diff - SHL16(low, DB_SHIFT-1), 16-DB_SHIFT);
242 #else
243    low = (int)floor(2*diff);
244    frac = 2*diff - low;
245 #endif
246    return max + diff_table[low] + MULT16_16_Q15(frac, SUB16(diff_table[low+1], diff_table[low]));
247 }
248 #else
logSum(opus_val16 a,opus_val16 b)249 opus_val16 logSum(opus_val16 a, opus_val16 b)
250 {
251    return log2(pow(4, a)+ pow(4, b))/2;
252 }
253 #endif
254 
surround_analysis(const CELTMode * celt_mode,const void * pcm,opus_val16 * bandLogE,opus_val32 * mem,opus_val32 * preemph_mem,int len,int overlap,int channels,int rate,opus_copy_channel_in_func copy_channel_in,int arch)255 void surround_analysis(const CELTMode *celt_mode, const void *pcm, opus_val16 *bandLogE, opus_val32 *mem, opus_val32 *preemph_mem,
256       int len, int overlap, int channels, int rate, opus_copy_channel_in_func copy_channel_in, int arch
257 )
258 {
259    int c;
260    int i;
261    int LM;
262    int pos[8] = {0};
263    int upsample;
264    int frame_size;
265    int freq_size;
266    opus_val16 channel_offset;
267    opus_val32 bandE[21];
268    opus_val16 maskLogE[3][21];
269    VARDECL(opus_val32, in);
270    VARDECL(opus_val16, x);
271    VARDECL(opus_val32, freq);
272    SAVE_STACK;
273 
274    upsample = resampling_factor(rate);
275    frame_size = len*upsample;
276    freq_size = IMIN(960, frame_size);
277 
278    /* LM = log2(frame_size / 120) */
279    for (LM=0;LM<celt_mode->maxLM;LM++)
280       if (celt_mode->shortMdctSize<<LM==frame_size)
281          break;
282 
283    ALLOC(in, frame_size+overlap, opus_val32);
284    ALLOC(x, len, opus_val16);
285    ALLOC(freq, freq_size, opus_val32);
286 
287    channel_pos(channels, pos);
288 
289    for (c=0;c<3;c++)
290       for (i=0;i<21;i++)
291          maskLogE[c][i] = -QCONST16(28.f, DB_SHIFT);
292 
293    for (c=0;c<channels;c++)
294    {
295       int frame;
296       int nb_frames = frame_size/freq_size;
297       celt_assert(nb_frames*freq_size == frame_size);
298       OPUS_COPY(in, mem+c*overlap, overlap);
299       (*copy_channel_in)(x, 1, pcm, channels, c, len);
300       celt_preemphasis(x, in+overlap, frame_size, 1, upsample, celt_mode->preemph, preemph_mem+c, 0);
301 #ifndef FIXED_POINT
302       {
303          opus_val32 sum;
304          sum = celt_inner_prod(in, in, frame_size+overlap, 0);
305          /* This should filter out both NaNs and ridiculous signals that could
306             cause NaNs further down. */
307          if (!(sum < 1e18f) || celt_isnan(sum))
308          {
309             OPUS_CLEAR(in, frame_size+overlap);
310             preemph_mem[c] = 0;
311          }
312       }
313 #endif
314       OPUS_CLEAR(bandE, 21);
315       for (frame=0;frame<nb_frames;frame++)
316       {
317          opus_val32 tmpE[21];
318          clt_mdct_forward(&celt_mode->mdct, in+960*frame, freq, celt_mode->window,
319                overlap, celt_mode->maxLM-LM, 1, arch);
320          if (upsample != 1)
321          {
322             int bound = freq_size/upsample;
323             for (i=0;i<bound;i++)
324                freq[i] *= upsample;
325             for (;i<freq_size;i++)
326                freq[i] = 0;
327          }
328 
329          compute_band_energies(celt_mode, freq, tmpE, 21, 1, LM, arch);
330          /* If we have multiple frames, take the max energy. */
331          for (i=0;i<21;i++)
332             bandE[i] = MAX32(bandE[i], tmpE[i]);
333       }
334       amp2Log2(celt_mode, 21, 21, bandE, bandLogE+21*c, 1);
335       /* Apply spreading function with -6 dB/band going up and -12 dB/band going down. */
336       for (i=1;i<21;i++)
337          bandLogE[21*c+i] = MAX16(bandLogE[21*c+i], bandLogE[21*c+i-1]-QCONST16(1.f, DB_SHIFT));
338       for (i=19;i>=0;i--)
339          bandLogE[21*c+i] = MAX16(bandLogE[21*c+i], bandLogE[21*c+i+1]-QCONST16(2.f, DB_SHIFT));
340       if (pos[c]==1)
341       {
342          for (i=0;i<21;i++)
343             maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]);
344       } else if (pos[c]==3)
345       {
346          for (i=0;i<21;i++)
347             maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]);
348       } else if (pos[c]==2)
349       {
350          for (i=0;i<21;i++)
351          {
352             maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]-QCONST16(.5f, DB_SHIFT));
353             maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]-QCONST16(.5f, DB_SHIFT));
354          }
355       }
356 #if 0
357       for (i=0;i<21;i++)
358          printf("%f ", bandLogE[21*c+i]);
359       float sum=0;
360       for (i=0;i<21;i++)
361          sum += bandLogE[21*c+i];
362       printf("%f ", sum/21);
363 #endif
364       OPUS_COPY(mem+c*overlap, in+frame_size, overlap);
365    }
366    for (i=0;i<21;i++)
367       maskLogE[1][i] = MIN32(maskLogE[0][i],maskLogE[2][i]);
368    channel_offset = HALF16(celt_log2(QCONST32(2.f,14)/(channels-1)));
369    for (c=0;c<3;c++)
370       for (i=0;i<21;i++)
371          maskLogE[c][i] += channel_offset;
372 #if 0
373    for (c=0;c<3;c++)
374    {
375       for (i=0;i<21;i++)
376          printf("%f ", maskLogE[c][i]);
377    }
378 #endif
379    for (c=0;c<channels;c++)
380    {
381       opus_val16 *mask;
382       if (pos[c]!=0)
383       {
384          mask = &maskLogE[pos[c]-1][0];
385          for (i=0;i<21;i++)
386             bandLogE[21*c+i] = bandLogE[21*c+i] - mask[i];
387       } else {
388          for (i=0;i<21;i++)
389             bandLogE[21*c+i] = 0;
390       }
391 #if 0
392       for (i=0;i<21;i++)
393          printf("%f ", bandLogE[21*c+i]);
394       printf("\n");
395 #endif
396 #if 0
397       float sum=0;
398       for (i=0;i<21;i++)
399          sum += bandLogE[21*c+i];
400       printf("%f ", sum/(float)QCONST32(21.f, DB_SHIFT));
401       printf("\n");
402 #endif
403    }
404    RESTORE_STACK;
405 }
406 
opus_multistream_encoder_get_size(int nb_streams,int nb_coupled_streams)407 opus_int32 opus_multistream_encoder_get_size(int nb_streams, int nb_coupled_streams)
408 {
409    int coupled_size;
410    int mono_size;
411 
412    if(nb_streams<1||nb_coupled_streams>nb_streams||nb_coupled_streams<0)return 0;
413    coupled_size = opus_encoder_get_size(2);
414    mono_size = opus_encoder_get_size(1);
415    return align(sizeof(OpusMSEncoder))
416         + nb_coupled_streams * align(coupled_size)
417         + (nb_streams-nb_coupled_streams) * align(mono_size);
418 }
419 
opus_multistream_surround_encoder_get_size(int channels,int mapping_family)420 opus_int32 opus_multistream_surround_encoder_get_size(int channels, int mapping_family)
421 {
422    int nb_streams;
423    int nb_coupled_streams;
424    opus_int32 size;
425 
426    if (mapping_family==0)
427    {
428       if (channels==1)
429       {
430          nb_streams=1;
431          nb_coupled_streams=0;
432       } else if (channels==2)
433       {
434          nb_streams=1;
435          nb_coupled_streams=1;
436       } else
437          return 0;
438    } else if (mapping_family==1 && channels<=8 && channels>=1)
439    {
440       nb_streams=vorbis_mappings[channels-1].nb_streams;
441       nb_coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams;
442    } else if (mapping_family==255)
443    {
444       nb_streams=channels;
445       nb_coupled_streams=0;
446 #ifdef ENABLE_EXPERIMENTAL_AMBISONICS
447    } else if (mapping_family==254)
448    {
449       if (!validate_ambisonics(channels, &nb_streams, &nb_coupled_streams))
450          return 0;
451 #endif
452    } else
453       return 0;
454    size = opus_multistream_encoder_get_size(nb_streams, nb_coupled_streams);
455    if (channels>2)
456    {
457       size += channels*(120*sizeof(opus_val32) + sizeof(opus_val32));
458    }
459    return size;
460 }
461 
opus_multistream_encoder_init_impl(OpusMSEncoder * st,opus_int32 Fs,int channels,int streams,int coupled_streams,const unsigned char * mapping,int application,MappingType mapping_type)462 static int opus_multistream_encoder_init_impl(
463       OpusMSEncoder *st,
464       opus_int32 Fs,
465       int channels,
466       int streams,
467       int coupled_streams,
468       const unsigned char *mapping,
469       int application,
470       MappingType mapping_type
471 )
472 {
473    int coupled_size;
474    int mono_size;
475    int i, ret;
476    char *ptr;
477 
478    if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
479        (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams))
480       return OPUS_BAD_ARG;
481 
482    st->arch = opus_select_arch();
483    st->layout.nb_channels = channels;
484    st->layout.nb_streams = streams;
485    st->layout.nb_coupled_streams = coupled_streams;
486    if (mapping_type != MAPPING_TYPE_SURROUND)
487       st->lfe_stream = -1;
488    st->bitrate_bps = OPUS_AUTO;
489    st->application = application;
490    st->variable_duration = OPUS_FRAMESIZE_ARG;
491    for (i=0;i<st->layout.nb_channels;i++)
492       st->layout.mapping[i] = mapping[i];
493    if (!validate_layout(&st->layout))
494       return OPUS_BAD_ARG;
495    if (mapping_type == MAPPING_TYPE_SURROUND &&
496        !validate_encoder_layout(&st->layout))
497       return OPUS_BAD_ARG;
498 #ifdef ENABLE_EXPERIMENTAL_AMBISONICS
499    if (mapping_type == MAPPING_TYPE_AMBISONICS &&
500        !validate_ambisonics(st->layout.nb_channels, NULL, NULL))
501       return OPUS_BAD_ARG;
502 #endif
503    ptr = (char*)st + align(sizeof(OpusMSEncoder));
504    coupled_size = opus_encoder_get_size(2);
505    mono_size = opus_encoder_get_size(1);
506 
507    for (i=0;i<st->layout.nb_coupled_streams;i++)
508    {
509       ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 2, application);
510       if(ret!=OPUS_OK)return ret;
511       if (i==st->lfe_stream)
512          opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1));
513       ptr += align(coupled_size);
514    }
515    for (;i<st->layout.nb_streams;i++)
516    {
517       ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 1, application);
518       if (i==st->lfe_stream)
519          opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1));
520       if(ret!=OPUS_OK)return ret;
521       ptr += align(mono_size);
522    }
523    if (mapping_type == MAPPING_TYPE_SURROUND)
524    {
525       OPUS_CLEAR(ms_get_preemph_mem(st), channels);
526       OPUS_CLEAR(ms_get_window_mem(st), channels*120);
527    }
528    st->mapping_type = mapping_type;
529    return OPUS_OK;
530 }
531 
opus_multistream_encoder_init(OpusMSEncoder * st,opus_int32 Fs,int channels,int streams,int coupled_streams,const unsigned char * mapping,int application)532 int opus_multistream_encoder_init(
533       OpusMSEncoder *st,
534       opus_int32 Fs,
535       int channels,
536       int streams,
537       int coupled_streams,
538       const unsigned char *mapping,
539       int application
540 )
541 {
542    return opus_multistream_encoder_init_impl(st, Fs, channels, streams,
543                                              coupled_streams, mapping,
544                                              application, MAPPING_TYPE_NONE);
545 }
546 
opus_multistream_surround_encoder_init(OpusMSEncoder * st,opus_int32 Fs,int channels,int mapping_family,int * streams,int * coupled_streams,unsigned char * mapping,int application)547 int opus_multistream_surround_encoder_init(
548       OpusMSEncoder *st,
549       opus_int32 Fs,
550       int channels,
551       int mapping_family,
552       int *streams,
553       int *coupled_streams,
554       unsigned char *mapping,
555       int application
556 )
557 {
558    MappingType mapping_type;
559 
560    if ((channels>255) || (channels<1))
561       return OPUS_BAD_ARG;
562    st->lfe_stream = -1;
563    if (mapping_family==0)
564    {
565       if (channels==1)
566       {
567          *streams=1;
568          *coupled_streams=0;
569          mapping[0]=0;
570       } else if (channels==2)
571       {
572          *streams=1;
573          *coupled_streams=1;
574          mapping[0]=0;
575          mapping[1]=1;
576       } else
577          return OPUS_UNIMPLEMENTED;
578    } else if (mapping_family==1 && channels<=8 && channels>=1)
579    {
580       int i;
581       *streams=vorbis_mappings[channels-1].nb_streams;
582       *coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams;
583       for (i=0;i<channels;i++)
584          mapping[i] = vorbis_mappings[channels-1].mapping[i];
585       if (channels>=6)
586          st->lfe_stream = *streams-1;
587    } else if (mapping_family==255)
588    {
589       int i;
590       *streams=channels;
591       *coupled_streams=0;
592       for(i=0;i<channels;i++)
593          mapping[i] = i;
594 #ifdef ENABLE_EXPERIMENTAL_AMBISONICS
595    } else if (mapping_family==254)
596    {
597       int i;
598       if (!validate_ambisonics(channels, streams, coupled_streams))
599          return OPUS_BAD_ARG;
600       for(i = 0; i < (*streams - *coupled_streams); i++)
601          mapping[i] = i + (*coupled_streams * 2);
602       for(i = 0; i < *coupled_streams * 2; i++)
603          mapping[i + (*streams - *coupled_streams)] = i;
604 #endif
605    } else
606       return OPUS_UNIMPLEMENTED;
607 
608    if (channels>2 && mapping_family==1) {
609       mapping_type = MAPPING_TYPE_SURROUND;
610 #ifdef ENABLE_EXPERIMENTAL_AMBISONICS
611    } else if (mapping_family==254)
612    {
613       mapping_type = MAPPING_TYPE_AMBISONICS;
614 #endif
615    } else
616    {
617       mapping_type = MAPPING_TYPE_NONE;
618    }
619    return opus_multistream_encoder_init_impl(st, Fs, channels, *streams,
620                                              *coupled_streams, mapping,
621                                              application, mapping_type);
622 }
623 
opus_multistream_encoder_create(opus_int32 Fs,int channels,int streams,int coupled_streams,const unsigned char * mapping,int application,int * error)624 OpusMSEncoder *opus_multistream_encoder_create(
625       opus_int32 Fs,
626       int channels,
627       int streams,
628       int coupled_streams,
629       const unsigned char *mapping,
630       int application,
631       int *error
632 )
633 {
634    int ret;
635    OpusMSEncoder *st;
636    if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
637        (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams))
638    {
639       if (error)
640          *error = OPUS_BAD_ARG;
641       return NULL;
642    }
643    st = (OpusMSEncoder *)opus_alloc(opus_multistream_encoder_get_size(streams, coupled_streams));
644    if (st==NULL)
645    {
646       if (error)
647          *error = OPUS_ALLOC_FAIL;
648       return NULL;
649    }
650    ret = opus_multistream_encoder_init(st, Fs, channels, streams, coupled_streams, mapping, application);
651    if (ret != OPUS_OK)
652    {
653       opus_free(st);
654       st = NULL;
655    }
656    if (error)
657       *error = ret;
658    return st;
659 }
660 
opus_multistream_surround_encoder_create(opus_int32 Fs,int channels,int mapping_family,int * streams,int * coupled_streams,unsigned char * mapping,int application,int * error)661 OpusMSEncoder *opus_multistream_surround_encoder_create(
662       opus_int32 Fs,
663       int channels,
664       int mapping_family,
665       int *streams,
666       int *coupled_streams,
667       unsigned char *mapping,
668       int application,
669       int *error
670 )
671 {
672    int ret;
673    opus_int32 size;
674    OpusMSEncoder *st;
675    if ((channels>255) || (channels<1))
676    {
677       if (error)
678          *error = OPUS_BAD_ARG;
679       return NULL;
680    }
681    size = opus_multistream_surround_encoder_get_size(channels, mapping_family);
682    if (!size)
683    {
684       if (error)
685          *error = OPUS_UNIMPLEMENTED;
686       return NULL;
687    }
688    st = (OpusMSEncoder *)opus_alloc(size);
689    if (st==NULL)
690    {
691       if (error)
692          *error = OPUS_ALLOC_FAIL;
693       return NULL;
694    }
695    ret = opus_multistream_surround_encoder_init(st, Fs, channels, mapping_family, streams, coupled_streams, mapping, application);
696    if (ret != OPUS_OK)
697    {
698       opus_free(st);
699       st = NULL;
700    }
701    if (error)
702       *error = ret;
703    return st;
704 }
705 
surround_rate_allocation(OpusMSEncoder * st,opus_int32 * rate,int frame_size,opus_int32 Fs)706 static void surround_rate_allocation(
707       OpusMSEncoder *st,
708       opus_int32 *rate,
709       int frame_size,
710       opus_int32 Fs
711       )
712 {
713    int i;
714    opus_int32 channel_rate;
715    int stream_offset;
716    int lfe_offset;
717    int coupled_ratio; /* Q8 */
718    int lfe_ratio;     /* Q8 */
719    int nb_lfe;
720    int nb_uncoupled;
721    int nb_coupled;
722    int nb_normal;
723    opus_int32 channel_offset;
724    opus_int32 bitrate;
725    int total;
726 
727    nb_lfe = (st->lfe_stream!=-1);
728    nb_coupled = st->layout.nb_coupled_streams;
729    nb_uncoupled = st->layout.nb_streams-nb_coupled-nb_lfe;
730    nb_normal = 2*nb_coupled + nb_uncoupled;
731 
732    /* Give each non-LFE channel enough bits per channel for coding band energy. */
733    channel_offset = 40*IMAX(50, Fs/frame_size);
734 
735    if (st->bitrate_bps==OPUS_AUTO)
736    {
737       bitrate = nb_normal*(channel_offset + Fs + 10000) + 8000*nb_lfe;
738    } else if (st->bitrate_bps==OPUS_BITRATE_MAX)
739    {
740       bitrate = nb_normal*300000 + nb_lfe*128000;
741    } else {
742       bitrate = st->bitrate_bps;
743    }
744 
745    /* Give LFE some basic stream_channel allocation but never exceed 1/20 of the
746       total rate for the non-energy part to avoid problems at really low rate. */
747    lfe_offset = IMIN(bitrate/20, 3000) + 15*IMAX(50, Fs/frame_size);
748 
749    /* We give each stream (coupled or uncoupled) a starting bitrate.
750       This models the main saving of coupled channels over uncoupled. */
751    stream_offset = (bitrate - channel_offset*nb_normal - lfe_offset*nb_lfe)/nb_normal/2;
752    stream_offset = IMAX(0, IMIN(20000, stream_offset));
753 
754    /* Coupled streams get twice the mono rate after the offset is allocated. */
755    coupled_ratio = 512;
756    /* Should depend on the bitrate, for now we assume LFE gets 1/8 the bits of mono */
757    lfe_ratio = 32;
758 
759    total = (nb_uncoupled<<8)         /* mono */
760          + coupled_ratio*nb_coupled /* stereo */
761          + nb_lfe*lfe_ratio;
762    channel_rate = 256*(opus_int64)(bitrate - lfe_offset*nb_lfe - stream_offset*(nb_coupled+nb_uncoupled) - channel_offset*nb_normal)/total;
763 
764    for (i=0;i<st->layout.nb_streams;i++)
765    {
766       if (i<st->layout.nb_coupled_streams)
767          rate[i] = 2*channel_offset + IMAX(0, stream_offset+(channel_rate*coupled_ratio>>8));
768       else if (i!=st->lfe_stream)
769          rate[i] = channel_offset + IMAX(0, stream_offset + channel_rate);
770       else
771          rate[i] = IMAX(0, lfe_offset+(channel_rate*lfe_ratio>>8));
772    }
773 }
774 
775 #ifdef ENABLE_EXPERIMENTAL_AMBISONICS
ambisonics_rate_allocation(OpusMSEncoder * st,opus_int32 * rate,int frame_size,opus_int32 Fs)776 static void ambisonics_rate_allocation(
777       OpusMSEncoder *st,
778       opus_int32 *rate,
779       int frame_size,
780       opus_int32 Fs
781       )
782 {
783    int i;
784    int total_rate;
785    int directional_rate;
786    int nondirectional_rate;
787    int leftover_bits;
788 
789    /* Each nondirectional channel gets (rate_ratio_num / rate_ratio_den) times
790     * as many bits as all other ambisonics channels.
791     */
792    const int rate_ratio_num = 4;
793    const int rate_ratio_den = 3;
794    const int nb_channels = st->layout.nb_streams + st->layout.nb_coupled_streams;
795    const int nb_nondirectional_channels = st->layout.nb_coupled_streams * 2 + 1;
796    const int nb_directional_channels = st->layout.nb_streams - 1;
797 
798    if (st->bitrate_bps==OPUS_AUTO)
799    {
800       total_rate = (st->layout.nb_coupled_streams + st->layout.nb_streams) *
801          (Fs+60*Fs/frame_size) + st->layout.nb_streams * 15000;
802    } else if (st->bitrate_bps==OPUS_BITRATE_MAX)
803    {
804       total_rate = nb_channels * 320000;
805    } else
806    {
807       total_rate = st->bitrate_bps;
808    }
809 
810    /* Let y be the directional rate, m be the num of nondirectional channels
811     *   m = (s + 1)
812     * and let p, q be integers such that the nondirectional rate is
813     *   m_rate = (p / q) * y
814     * Also let T be the total bitrate to allocate. Then
815     *   T = (n - m) * y + m * m_rate
816     * Solving for y,
817     *   y = (q * T) / (m * (p - q) + n * q)
818     */
819    directional_rate =
820       total_rate * rate_ratio_den
821       / (nb_nondirectional_channels * (rate_ratio_num - rate_ratio_den)
822        + nb_channels * rate_ratio_den);
823 
824    /* Calculate the nondirectional rate.
825     *   m_rate = y * (p / q)
826     */
827    nondirectional_rate = directional_rate * rate_ratio_num / rate_ratio_den;
828 
829    /* Calculate the leftover from truncation error.
830     *   leftover = T - y * (n - m) - m_rate * m
831     * Place leftover bits in omnidirectional channel.
832     */
833    leftover_bits = total_rate
834       - directional_rate * nb_directional_channels
835       - nondirectional_rate * nb_nondirectional_channels;
836 
837    /* Calculate rates for each channel */
838    for (i = 0; i < st->layout.nb_streams; i++)
839    {
840       if (i < st->layout.nb_coupled_streams)
841       {
842          rate[i] = nondirectional_rate * 2;
843       } else if (i == st->layout.nb_coupled_streams)
844       {
845          rate[i] = nondirectional_rate + leftover_bits;
846       } else
847       {
848          rate[i] = directional_rate;
849       }
850    }
851 }
852 #endif /* ENABLE_EXPERIMENTAL_AMBISONICS */
853 
rate_allocation(OpusMSEncoder * st,opus_int32 * rate,int frame_size)854 static opus_int32 rate_allocation(
855       OpusMSEncoder *st,
856       opus_int32 *rate,
857       int frame_size
858       )
859 {
860    int i;
861    opus_int32 rate_sum=0;
862    opus_int32 Fs;
863    char *ptr;
864 
865    ptr = (char*)st + align(sizeof(OpusMSEncoder));
866    opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
867 
868 #ifdef ENABLE_EXPERIMENTAL_AMBISONICS
869    if (st->mapping_type == MAPPING_TYPE_AMBISONICS) {
870      ambisonics_rate_allocation(st, rate, frame_size, Fs);
871    } else
872 #endif
873    {
874      surround_rate_allocation(st, rate, frame_size, Fs);
875    }
876 
877    for (i=0;i<st->layout.nb_streams;i++)
878    {
879       rate[i] = IMAX(rate[i], 500);
880       rate_sum += rate[i];
881    }
882    return rate_sum;
883 }
884 
885 /* Max size in case the encoder decides to return six frames (6 x 20 ms = 120 ms) */
886 #define MS_FRAME_TMP (6*1275+12)
opus_multistream_encode_native(OpusMSEncoder * st,opus_copy_channel_in_func copy_channel_in,const void * pcm,int analysis_frame_size,unsigned char * data,opus_int32 max_data_bytes,int lsb_depth,downmix_func downmix,int float_api)887 static int opus_multistream_encode_native
888 (
889     OpusMSEncoder *st,
890     opus_copy_channel_in_func copy_channel_in,
891     const void *pcm,
892     int analysis_frame_size,
893     unsigned char *data,
894     opus_int32 max_data_bytes,
895     int lsb_depth,
896     downmix_func downmix,
897     int float_api
898 )
899 {
900    opus_int32 Fs;
901    int coupled_size;
902    int mono_size;
903    int s;
904    char *ptr;
905    int tot_size;
906    VARDECL(opus_val16, buf);
907    VARDECL(opus_val16, bandSMR);
908    unsigned char tmp_data[MS_FRAME_TMP];
909    OpusRepacketizer rp;
910    opus_int32 vbr;
911    const CELTMode *celt_mode;
912    opus_int32 bitrates[256];
913    opus_val16 bandLogE[42];
914    opus_val32 *mem = NULL;
915    opus_val32 *preemph_mem=NULL;
916    int frame_size;
917    opus_int32 rate_sum;
918    opus_int32 smallest_packet;
919    ALLOC_STACK;
920 
921    if (st->mapping_type == MAPPING_TYPE_SURROUND)
922    {
923       preemph_mem = ms_get_preemph_mem(st);
924       mem = ms_get_window_mem(st);
925    }
926 
927    ptr = (char*)st + align(sizeof(OpusMSEncoder));
928    opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
929    opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_VBR(&vbr));
930    opus_encoder_ctl((OpusEncoder*)ptr, CELT_GET_MODE(&celt_mode));
931 
932    frame_size = frame_size_select(analysis_frame_size, st->variable_duration, Fs);
933    if (frame_size <= 0)
934    {
935       RESTORE_STACK;
936       return OPUS_BAD_ARG;
937    }
938 
939    /* Smallest packet the encoder can produce. */
940    smallest_packet = st->layout.nb_streams*2-1;
941    /* 100 ms needs an extra byte per stream for the ToC. */
942    if (Fs/frame_size == 10)
943      smallest_packet += st->layout.nb_streams;
944    if (max_data_bytes < smallest_packet)
945    {
946       RESTORE_STACK;
947       return OPUS_BUFFER_TOO_SMALL;
948    }
949    ALLOC(buf, 2*frame_size, opus_val16);
950    coupled_size = opus_encoder_get_size(2);
951    mono_size = opus_encoder_get_size(1);
952 
953    ALLOC(bandSMR, 21*st->layout.nb_channels, opus_val16);
954    if (st->mapping_type == MAPPING_TYPE_SURROUND)
955    {
956       surround_analysis(celt_mode, pcm, bandSMR, mem, preemph_mem, frame_size, 120, st->layout.nb_channels, Fs, copy_channel_in, st->arch);
957    }
958 
959    /* Compute bitrate allocation between streams (this could be a lot better) */
960    rate_sum = rate_allocation(st, bitrates, frame_size);
961 
962    if (!vbr)
963    {
964       if (st->bitrate_bps == OPUS_AUTO)
965       {
966          max_data_bytes = IMIN(max_data_bytes, 3*rate_sum/(3*8*Fs/frame_size));
967       } else if (st->bitrate_bps != OPUS_BITRATE_MAX)
968       {
969          max_data_bytes = IMIN(max_data_bytes, IMAX(smallest_packet,
970                           3*st->bitrate_bps/(3*8*Fs/frame_size)));
971       }
972    }
973    ptr = (char*)st + align(sizeof(OpusMSEncoder));
974    for (s=0;s<st->layout.nb_streams;s++)
975    {
976       OpusEncoder *enc;
977       enc = (OpusEncoder*)ptr;
978       if (s < st->layout.nb_coupled_streams)
979          ptr += align(coupled_size);
980       else
981          ptr += align(mono_size);
982       opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrates[s]));
983       if (st->mapping_type == MAPPING_TYPE_SURROUND)
984       {
985          opus_int32 equiv_rate;
986          equiv_rate = st->bitrate_bps;
987          if (frame_size*50 < Fs)
988             equiv_rate -= 60*(Fs/frame_size - 50)*st->layout.nb_channels;
989          if (equiv_rate > 10000*st->layout.nb_channels)
990             opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
991          else if (equiv_rate > 7000*st->layout.nb_channels)
992             opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_SUPERWIDEBAND));
993          else if (equiv_rate > 5000*st->layout.nb_channels)
994             opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_WIDEBAND));
995          else
996             opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND));
997          if (s < st->layout.nb_coupled_streams)
998          {
999             /* To preserve the spatial image, force stereo CELT on coupled streams */
1000             opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY));
1001             opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(2));
1002          }
1003       }
1004 #ifdef ENABLE_EXPERIMENTAL_AMBISONICS
1005       else if (st->mapping_type == MAPPING_TYPE_AMBISONICS) {
1006         opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY));
1007       }
1008 #endif
1009    }
1010 
1011    ptr = (char*)st + align(sizeof(OpusMSEncoder));
1012    /* Counting ToC */
1013    tot_size = 0;
1014    for (s=0;s<st->layout.nb_streams;s++)
1015    {
1016       OpusEncoder *enc;
1017       int len;
1018       int curr_max;
1019       int c1, c2;
1020       int ret;
1021 
1022       opus_repacketizer_init(&rp);
1023       enc = (OpusEncoder*)ptr;
1024       if (s < st->layout.nb_coupled_streams)
1025       {
1026          int i;
1027          int left, right;
1028          left = get_left_channel(&st->layout, s, -1);
1029          right = get_right_channel(&st->layout, s, -1);
1030          (*copy_channel_in)(buf, 2,
1031             pcm, st->layout.nb_channels, left, frame_size);
1032          (*copy_channel_in)(buf+1, 2,
1033             pcm, st->layout.nb_channels, right, frame_size);
1034          ptr += align(coupled_size);
1035          if (st->mapping_type == MAPPING_TYPE_SURROUND)
1036          {
1037             for (i=0;i<21;i++)
1038             {
1039                bandLogE[i] = bandSMR[21*left+i];
1040                bandLogE[21+i] = bandSMR[21*right+i];
1041             }
1042          }
1043          c1 = left;
1044          c2 = right;
1045       } else {
1046          int i;
1047          int chan = get_mono_channel(&st->layout, s, -1);
1048          (*copy_channel_in)(buf, 1,
1049             pcm, st->layout.nb_channels, chan, frame_size);
1050          ptr += align(mono_size);
1051          if (st->mapping_type == MAPPING_TYPE_SURROUND)
1052          {
1053             for (i=0;i<21;i++)
1054                bandLogE[i] = bandSMR[21*chan+i];
1055          }
1056          c1 = chan;
1057          c2 = -1;
1058       }
1059       if (st->mapping_type == MAPPING_TYPE_SURROUND)
1060          opus_encoder_ctl(enc, OPUS_SET_ENERGY_MASK(bandLogE));
1061       /* number of bytes left (+Toc) */
1062       curr_max = max_data_bytes - tot_size;
1063       /* Reserve one byte for the last stream and two for the others */
1064       curr_max -= IMAX(0,2*(st->layout.nb_streams-s-1)-1);
1065       /* For 100 ms, reserve an extra byte per stream for the ToC */
1066       if (Fs/frame_size == 10)
1067         curr_max -= st->layout.nb_streams-s-1;
1068       curr_max = IMIN(curr_max,MS_FRAME_TMP);
1069       /* Repacketizer will add one or two bytes for self-delimited frames */
1070       if (s != st->layout.nb_streams-1) curr_max -=  curr_max>253 ? 2 : 1;
1071       if (!vbr && s == st->layout.nb_streams-1)
1072          opus_encoder_ctl(enc, OPUS_SET_BITRATE(curr_max*(8*Fs/frame_size)));
1073       len = opus_encode_native(enc, buf, frame_size, tmp_data, curr_max, lsb_depth,
1074             pcm, analysis_frame_size, c1, c2, st->layout.nb_channels, downmix, float_api);
1075       if (len<0)
1076       {
1077          RESTORE_STACK;
1078          return len;
1079       }
1080       /* We need to use the repacketizer to add the self-delimiting lengths
1081          while taking into account the fact that the encoder can now return
1082          more than one frame at a time (e.g. 60 ms CELT-only) */
1083       ret = opus_repacketizer_cat(&rp, tmp_data, len);
1084       /* If the opus_repacketizer_cat() fails, then something's seriously wrong
1085          with the encoder. */
1086       if (ret != OPUS_OK)
1087       {
1088          RESTORE_STACK;
1089          return OPUS_INTERNAL_ERROR;
1090       }
1091       len = opus_repacketizer_out_range_impl(&rp, 0, opus_repacketizer_get_nb_frames(&rp),
1092             data, max_data_bytes-tot_size, s != st->layout.nb_streams-1, !vbr && s == st->layout.nb_streams-1);
1093       data += len;
1094       tot_size += len;
1095    }
1096    /*printf("\n");*/
1097    RESTORE_STACK;
1098    return tot_size;
1099 }
1100 
1101 #if !defined(DISABLE_FLOAT_API)
opus_copy_channel_in_float(opus_val16 * dst,int dst_stride,const void * src,int src_stride,int src_channel,int frame_size)1102 static void opus_copy_channel_in_float(
1103   opus_val16 *dst,
1104   int dst_stride,
1105   const void *src,
1106   int src_stride,
1107   int src_channel,
1108   int frame_size
1109 )
1110 {
1111    const float *float_src;
1112    opus_int32 i;
1113    float_src = (const float *)src;
1114    for (i=0;i<frame_size;i++)
1115 #if defined(FIXED_POINT)
1116       dst[i*dst_stride] = FLOAT2INT16(float_src[i*src_stride+src_channel]);
1117 #else
1118       dst[i*dst_stride] = float_src[i*src_stride+src_channel];
1119 #endif
1120 }
1121 #endif
1122 
opus_copy_channel_in_short(opus_val16 * dst,int dst_stride,const void * src,int src_stride,int src_channel,int frame_size)1123 static void opus_copy_channel_in_short(
1124   opus_val16 *dst,
1125   int dst_stride,
1126   const void *src,
1127   int src_stride,
1128   int src_channel,
1129   int frame_size
1130 )
1131 {
1132    const opus_int16 *short_src;
1133    opus_int32 i;
1134    short_src = (const opus_int16 *)src;
1135    for (i=0;i<frame_size;i++)
1136 #if defined(FIXED_POINT)
1137       dst[i*dst_stride] = short_src[i*src_stride+src_channel];
1138 #else
1139       dst[i*dst_stride] = (1/32768.f)*short_src[i*src_stride+src_channel];
1140 #endif
1141 }
1142 
1143 
1144 #ifdef FIXED_POINT
opus_multistream_encode(OpusMSEncoder * st,const opus_val16 * pcm,int frame_size,unsigned char * data,opus_int32 max_data_bytes)1145 int opus_multistream_encode(
1146     OpusMSEncoder *st,
1147     const opus_val16 *pcm,
1148     int frame_size,
1149     unsigned char *data,
1150     opus_int32 max_data_bytes
1151 )
1152 {
1153    return opus_multistream_encode_native(st, opus_copy_channel_in_short,
1154       pcm, frame_size, data, max_data_bytes, 16, downmix_int, 0);
1155 }
1156 
1157 #ifndef DISABLE_FLOAT_API
opus_multistream_encode_float(OpusMSEncoder * st,const float * pcm,int frame_size,unsigned char * data,opus_int32 max_data_bytes)1158 int opus_multistream_encode_float(
1159     OpusMSEncoder *st,
1160     const float *pcm,
1161     int frame_size,
1162     unsigned char *data,
1163     opus_int32 max_data_bytes
1164 )
1165 {
1166    return opus_multistream_encode_native(st, opus_copy_channel_in_float,
1167       pcm, frame_size, data, max_data_bytes, 16, downmix_float, 1);
1168 }
1169 #endif
1170 
1171 #else
1172 
opus_multistream_encode_float(OpusMSEncoder * st,const opus_val16 * pcm,int frame_size,unsigned char * data,opus_int32 max_data_bytes)1173 int opus_multistream_encode_float
1174 (
1175     OpusMSEncoder *st,
1176     const opus_val16 *pcm,
1177     int frame_size,
1178     unsigned char *data,
1179     opus_int32 max_data_bytes
1180 )
1181 {
1182    return opus_multistream_encode_native(st, opus_copy_channel_in_float,
1183       pcm, frame_size, data, max_data_bytes, 24, downmix_float, 1);
1184 }
1185 
opus_multistream_encode(OpusMSEncoder * st,const opus_int16 * pcm,int frame_size,unsigned char * data,opus_int32 max_data_bytes)1186 int opus_multistream_encode(
1187     OpusMSEncoder *st,
1188     const opus_int16 *pcm,
1189     int frame_size,
1190     unsigned char *data,
1191     opus_int32 max_data_bytes
1192 )
1193 {
1194    return opus_multistream_encode_native(st, opus_copy_channel_in_short,
1195       pcm, frame_size, data, max_data_bytes, 16, downmix_int, 0);
1196 }
1197 #endif
1198 
opus_multistream_encoder_ctl(OpusMSEncoder * st,int request,...)1199 int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
1200 {
1201    va_list ap;
1202    int coupled_size, mono_size;
1203    char *ptr;
1204    int ret = OPUS_OK;
1205 
1206    va_start(ap, request);
1207 
1208    coupled_size = opus_encoder_get_size(2);
1209    mono_size = opus_encoder_get_size(1);
1210    ptr = (char*)st + align(sizeof(OpusMSEncoder));
1211    switch (request)
1212    {
1213    case OPUS_SET_BITRATE_REQUEST:
1214    {
1215       opus_int32 value = va_arg(ap, opus_int32);
1216       if (value != OPUS_AUTO && value != OPUS_BITRATE_MAX)
1217       {
1218          if (value <= 0)
1219             goto bad_arg;
1220          value = IMIN(300000*st->layout.nb_channels, IMAX(500*st->layout.nb_channels, value));
1221       }
1222       st->bitrate_bps = value;
1223    }
1224    break;
1225    case OPUS_GET_BITRATE_REQUEST:
1226    {
1227       int s;
1228       opus_int32 *value = va_arg(ap, opus_int32*);
1229       if (!value)
1230       {
1231          goto bad_arg;
1232       }
1233       *value = 0;
1234       for (s=0;s<st->layout.nb_streams;s++)
1235       {
1236          opus_int32 rate;
1237          OpusEncoder *enc;
1238          enc = (OpusEncoder*)ptr;
1239          if (s < st->layout.nb_coupled_streams)
1240             ptr += align(coupled_size);
1241          else
1242             ptr += align(mono_size);
1243          opus_encoder_ctl(enc, request, &rate);
1244          *value += rate;
1245       }
1246    }
1247    break;
1248    case OPUS_GET_LSB_DEPTH_REQUEST:
1249    case OPUS_GET_VBR_REQUEST:
1250    case OPUS_GET_APPLICATION_REQUEST:
1251    case OPUS_GET_BANDWIDTH_REQUEST:
1252    case OPUS_GET_COMPLEXITY_REQUEST:
1253    case OPUS_GET_PACKET_LOSS_PERC_REQUEST:
1254    case OPUS_GET_DTX_REQUEST:
1255    case OPUS_GET_VOICE_RATIO_REQUEST:
1256    case OPUS_GET_VBR_CONSTRAINT_REQUEST:
1257    case OPUS_GET_SIGNAL_REQUEST:
1258    case OPUS_GET_LOOKAHEAD_REQUEST:
1259    case OPUS_GET_SAMPLE_RATE_REQUEST:
1260    case OPUS_GET_INBAND_FEC_REQUEST:
1261    case OPUS_GET_FORCE_CHANNELS_REQUEST:
1262    case OPUS_GET_PREDICTION_DISABLED_REQUEST:
1263    case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST:
1264    {
1265       OpusEncoder *enc;
1266       /* For int32* GET params, just query the first stream */
1267       opus_int32 *value = va_arg(ap, opus_int32*);
1268       enc = (OpusEncoder*)ptr;
1269       ret = opus_encoder_ctl(enc, request, value);
1270    }
1271    break;
1272    case OPUS_GET_FINAL_RANGE_REQUEST:
1273    {
1274       int s;
1275       opus_uint32 *value = va_arg(ap, opus_uint32*);
1276       opus_uint32 tmp;
1277       if (!value)
1278       {
1279          goto bad_arg;
1280       }
1281       *value=0;
1282       for (s=0;s<st->layout.nb_streams;s++)
1283       {
1284          OpusEncoder *enc;
1285          enc = (OpusEncoder*)ptr;
1286          if (s < st->layout.nb_coupled_streams)
1287             ptr += align(coupled_size);
1288          else
1289             ptr += align(mono_size);
1290          ret = opus_encoder_ctl(enc, request, &tmp);
1291          if (ret != OPUS_OK) break;
1292          *value ^= tmp;
1293       }
1294    }
1295    break;
1296    case OPUS_SET_LSB_DEPTH_REQUEST:
1297    case OPUS_SET_COMPLEXITY_REQUEST:
1298    case OPUS_SET_VBR_REQUEST:
1299    case OPUS_SET_VBR_CONSTRAINT_REQUEST:
1300    case OPUS_SET_MAX_BANDWIDTH_REQUEST:
1301    case OPUS_SET_BANDWIDTH_REQUEST:
1302    case OPUS_SET_SIGNAL_REQUEST:
1303    case OPUS_SET_APPLICATION_REQUEST:
1304    case OPUS_SET_INBAND_FEC_REQUEST:
1305    case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
1306    case OPUS_SET_DTX_REQUEST:
1307    case OPUS_SET_FORCE_MODE_REQUEST:
1308    case OPUS_SET_FORCE_CHANNELS_REQUEST:
1309    case OPUS_SET_PREDICTION_DISABLED_REQUEST:
1310    case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST:
1311    {
1312       int s;
1313       /* This works for int32 params */
1314       opus_int32 value = va_arg(ap, opus_int32);
1315       for (s=0;s<st->layout.nb_streams;s++)
1316       {
1317          OpusEncoder *enc;
1318 
1319          enc = (OpusEncoder*)ptr;
1320          if (s < st->layout.nb_coupled_streams)
1321             ptr += align(coupled_size);
1322          else
1323             ptr += align(mono_size);
1324          ret = opus_encoder_ctl(enc, request, value);
1325          if (ret != OPUS_OK)
1326             break;
1327       }
1328    }
1329    break;
1330    case OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST:
1331    {
1332       int s;
1333       opus_int32 stream_id;
1334       OpusEncoder **value;
1335       stream_id = va_arg(ap, opus_int32);
1336       if (stream_id<0 || stream_id >= st->layout.nb_streams)
1337          ret = OPUS_BAD_ARG;
1338       value = va_arg(ap, OpusEncoder**);
1339       if (!value)
1340       {
1341          goto bad_arg;
1342       }
1343       for (s=0;s<stream_id;s++)
1344       {
1345          if (s < st->layout.nb_coupled_streams)
1346             ptr += align(coupled_size);
1347          else
1348             ptr += align(mono_size);
1349       }
1350       *value = (OpusEncoder*)ptr;
1351    }
1352    break;
1353    case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST:
1354    {
1355        opus_int32 value = va_arg(ap, opus_int32);
1356        st->variable_duration = value;
1357    }
1358    break;
1359    case OPUS_GET_EXPERT_FRAME_DURATION_REQUEST:
1360    {
1361        opus_int32 *value = va_arg(ap, opus_int32*);
1362        if (!value)
1363        {
1364           goto bad_arg;
1365        }
1366        *value = st->variable_duration;
1367    }
1368    break;
1369    case OPUS_RESET_STATE:
1370    {
1371       int s;
1372       if (st->mapping_type == MAPPING_TYPE_SURROUND)
1373       {
1374          OPUS_CLEAR(ms_get_preemph_mem(st), st->layout.nb_channels);
1375          OPUS_CLEAR(ms_get_window_mem(st), st->layout.nb_channels*120);
1376       }
1377       for (s=0;s<st->layout.nb_streams;s++)
1378       {
1379          OpusEncoder *enc;
1380          enc = (OpusEncoder*)ptr;
1381          if (s < st->layout.nb_coupled_streams)
1382             ptr += align(coupled_size);
1383          else
1384             ptr += align(mono_size);
1385          ret = opus_encoder_ctl(enc, OPUS_RESET_STATE);
1386          if (ret != OPUS_OK)
1387             break;
1388       }
1389    }
1390    break;
1391    default:
1392       ret = OPUS_UNIMPLEMENTED;
1393       break;
1394    }
1395 
1396    va_end(ap);
1397    return ret;
1398 bad_arg:
1399    va_end(ap);
1400    return OPUS_BAD_ARG;
1401 }
1402 
opus_multistream_encoder_destroy(OpusMSEncoder * st)1403 void opus_multistream_encoder_destroy(OpusMSEncoder *st)
1404 {
1405     opus_free(st);
1406 }
1407