Coverage Report

Created: 2026-10-17 07:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opus/src/opus_multistream_encoder.c
Line
Count
Source
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
#ifdef ENABLE_QEXT
65
7.39k
#define MAX_OVERLAP 240
66
#else
67
#define MAX_OVERLAP 120
68
#endif
69
70
static opus_val32 *ms_get_preemph_mem(OpusMSEncoder *st)
71
4.92k
{
72
4.92k
   int s;
73
4.92k
   char *ptr;
74
4.92k
   int coupled_size, mono_size;
75
76
4.92k
   coupled_size = opus_encoder_init(NULL, st->Fs, 2, st->application);
77
4.92k
   mono_size = opus_encoder_init(NULL, st->Fs, 1, st->application);
78
4.92k
   ptr = (char*)st + align(sizeof(OpusMSEncoder));
79
19.3k
   for (s=0;s<st->layout.nb_streams;s++)
80
14.4k
   {
81
14.4k
      if (s < st->layout.nb_coupled_streams)
82
9.38k
         ptr += align(coupled_size);
83
5.03k
      else
84
5.03k
         ptr += align(mono_size);
85
14.4k
   }
86
   /* void* cast avoids clang -Wcast-align warning */
87
4.92k
   return (opus_val32*)(void*)(ptr+st->layout.nb_channels*MAX_OVERLAP*sizeof(opus_val32));
88
4.92k
}
89
90
static opus_val32 *ms_get_window_mem(OpusMSEncoder *st)
91
4.92k
{
92
4.92k
   int s;
93
4.92k
   char *ptr;
94
4.92k
   int coupled_size, mono_size;
95
96
4.92k
   coupled_size = opus_encoder_init(NULL, st->Fs, 2, st->application);
97
4.92k
   mono_size = opus_encoder_init(NULL, st->Fs, 1, st->application);
98
4.92k
   ptr = (char*)st + align(sizeof(OpusMSEncoder));
99
19.3k
   for (s=0;s<st->layout.nb_streams;s++)
100
14.4k
   {
101
14.4k
      if (s < st->layout.nb_coupled_streams)
102
9.38k
         ptr += align(coupled_size);
103
5.03k
      else
104
5.03k
         ptr += align(mono_size);
105
14.4k
   }
106
   /* void* cast avoids clang -Wcast-align warning */
107
4.92k
   return (opus_val32*)(void*)ptr;
108
4.92k
}
109
110
static int validate_ambisonics(int nb_channels, int *nb_streams, int *nb_coupled_streams)
111
11.2k
{
112
11.2k
   int order_plus_one;
113
11.2k
   int acn_channels;
114
11.2k
   int nondiegetic_channels;
115
116
11.2k
   if (nb_channels < 1 || nb_channels > 227)
117
8
      return 0;
118
119
11.2k
   order_plus_one = isqrt32(nb_channels);
120
11.2k
   acn_channels = order_plus_one * order_plus_one;
121
11.2k
   nondiegetic_channels = nb_channels - acn_channels;
122
123
11.2k
   if (nondiegetic_channels != 0 && nondiegetic_channels != 2)
124
93
      return 0;
125
126
11.1k
   if (nb_streams)
127
7.46k
      *nb_streams = acn_channels + (nondiegetic_channels != 0);
128
11.1k
   if (nb_coupled_streams)
129
7.46k
      *nb_coupled_streams = nondiegetic_channels != 0;
130
11.1k
   return 1;
131
11.2k
}
132
133
static int validate_encoder_layout(const ChannelLayout *layout)
134
69.9k
{
135
69.9k
   int s;
136
593k
   for (s=0;s<layout->nb_streams;s++)
137
523k
   {
138
523k
      if (s < layout->nb_coupled_streams)
139
167k
      {
140
167k
         if (get_left_channel(layout, s, -1)==-1)
141
63
            return 0;
142
167k
         if (get_right_channel(layout, s, -1)==-1)
143
131
            return 0;
144
355k
      } else {
145
355k
         if (get_mono_channel(layout, s, -1)==-1)
146
141
            return 0;
147
355k
      }
148
523k
   }
149
69.5k
   return 1;
150
69.9k
}
151
152
static void channel_pos(int channels, int pos[8])
153
2.44k
{
154
   /* Position in the mix: 0 don't mix, 1: left, 2: center, 3:right */
155
2.44k
   if (channels==4)
156
449
   {
157
449
      pos[0]=1;
158
449
      pos[1]=3;
159
449
      pos[2]=1;
160
449
      pos[3]=3;
161
1.99k
   } else if (channels==3||channels==5||channels==6)
162
1.32k
   {
163
1.32k
      pos[0]=1;
164
1.32k
      pos[1]=2;
165
1.32k
      pos[2]=3;
166
1.32k
      pos[3]=1;
167
1.32k
      pos[4]=3;
168
1.32k
      pos[5]=0;
169
1.32k
   } else if (channels==7)
170
410
   {
171
410
      pos[0]=1;
172
410
      pos[1]=2;
173
410
      pos[2]=3;
174
410
      pos[3]=1;
175
410
      pos[4]=3;
176
410
      pos[5]=2;
177
410
      pos[6]=0;
178
410
   } else if (channels==8)
179
255
   {
180
255
      pos[0]=1;
181
255
      pos[1]=2;
182
255
      pos[2]=3;
183
255
      pos[3]=1;
184
255
      pos[4]=3;
185
255
      pos[5]=1;
186
255
      pos[6]=3;
187
255
      pos[7]=0;
188
255
   }
189
2.44k
}
190
191
#if 1
192
/* Computes a rough approximation of log2(2^a + 2^b) */
193
static opus_val16 logSum(celt_glog a, celt_glog b)
194
279k
{
195
279k
   celt_glog max;
196
279k
   celt_glog diff;
197
279k
   celt_glog frac;
198
279k
   static const celt_glog diff_table[17] = {
199
279k
         GCONST(0.5000000f), GCONST(0.2924813f), GCONST(0.1609640f), GCONST(0.0849625f),
200
279k
         GCONST(0.0437314f), GCONST(0.0221971f), GCONST(0.0111839f), GCONST(0.0056136f),
201
279k
         GCONST(0.0028123f)
202
279k
   };
203
279k
   int low;
204
279k
   if (a>b)
205
82.3k
   {
206
82.3k
      max = a;
207
82.3k
      diff = SUB32(a,b);
208
197k
   } else {
209
197k
      max = b;
210
197k
      diff = SUB32(b,a);
211
197k
   }
212
279k
   if (!(diff < GCONST(8.f)))  /* inverted to catch NaNs */
213
115k
      return max;
214
#ifdef FIXED_POINT
215
96.5k
   low = SHR32(diff, DB_SHIFT-1);
216
96.5k
   frac = VSHR32(diff - SHL32(low, DB_SHIFT-1), DB_SHIFT-16);
217
#else
218
67.2k
   low = (int)floor(2*diff);
219
67.2k
   frac = 2*diff - low;
220
67.2k
#endif
221
163k
   return max + diff_table[low] + MULT16_32_Q15(frac, SUB32(diff_table[low+1], diff_table[low]));
222
279k
}
opus_multistream_encoder.c:logSum
Line
Count
Source
194
166k
{
195
166k
   celt_glog max;
196
166k
   celt_glog diff;
197
166k
   celt_glog frac;
198
166k
   static const celt_glog diff_table[17] = {
199
166k
         GCONST(0.5000000f), GCONST(0.2924813f), GCONST(0.1609640f), GCONST(0.0849625f),
200
166k
         GCONST(0.0437314f), GCONST(0.0221971f), GCONST(0.0111839f), GCONST(0.0056136f),
201
166k
         GCONST(0.0028123f)
202
166k
   };
203
166k
   int low;
204
166k
   if (a>b)
205
37.3k
   {
206
37.3k
      max = a;
207
37.3k
      diff = SUB32(a,b);
208
128k
   } else {
209
128k
      max = b;
210
128k
      diff = SUB32(b,a);
211
128k
   }
212
166k
   if (!(diff < GCONST(8.f)))  /* inverted to catch NaNs */
213
69.4k
      return max;
214
96.5k
#ifdef FIXED_POINT
215
96.5k
   low = SHR32(diff, DB_SHIFT-1);
216
96.5k
   frac = VSHR32(diff - SHL32(low, DB_SHIFT-1), DB_SHIFT-16);
217
#else
218
   low = (int)floor(2*diff);
219
   frac = 2*diff - low;
220
#endif
221
96.5k
   return max + diff_table[low] + MULT16_32_Q15(frac, SUB32(diff_table[low+1], diff_table[low]));
222
166k
}
opus_multistream_encoder.c:logSum
Line
Count
Source
194
113k
{
195
113k
   celt_glog max;
196
113k
   celt_glog diff;
197
113k
   celt_glog frac;
198
113k
   static const celt_glog diff_table[17] = {
199
113k
         GCONST(0.5000000f), GCONST(0.2924813f), GCONST(0.1609640f), GCONST(0.0849625f),
200
113k
         GCONST(0.0437314f), GCONST(0.0221971f), GCONST(0.0111839f), GCONST(0.0056136f),
201
113k
         GCONST(0.0028123f)
202
113k
   };
203
113k
   int low;
204
113k
   if (a>b)
205
44.9k
   {
206
44.9k
      max = a;
207
44.9k
      diff = SUB32(a,b);
208
68.3k
   } else {
209
68.3k
      max = b;
210
68.3k
      diff = SUB32(b,a);
211
68.3k
   }
212
113k
   if (!(diff < GCONST(8.f)))  /* inverted to catch NaNs */
213
46.0k
      return max;
214
#ifdef FIXED_POINT
215
   low = SHR32(diff, DB_SHIFT-1);
216
   frac = VSHR32(diff - SHL32(low, DB_SHIFT-1), DB_SHIFT-16);
217
#else
218
67.2k
   low = (int)floor(2*diff);
219
67.2k
   frac = 2*diff - low;
220
67.2k
#endif
221
67.2k
   return max + diff_table[low] + MULT16_32_Q15(frac, SUB32(diff_table[low+1], diff_table[low]));
222
113k
}
223
#else
224
opus_val16 logSum(opus_val16 a, opus_val16 b)
225
{
226
   return log2(pow(4, a)+ pow(4, b))/2;
227
}
228
#endif
229
230
void surround_analysis(const CELTMode *celt_mode, const void *pcm, celt_glog *bandLogE, opus_val32 *mem, opus_val32 *preemph_mem,
231
      int len, int overlap, int channels, int rate, opus_copy_channel_in_func copy_channel_in, int arch
232
)
233
2.44k
{
234
2.44k
   int c;
235
2.44k
   int i;
236
2.44k
   int LM;
237
2.44k
   int pos[8] = {0};
238
2.44k
   int upsample;
239
2.44k
   int frame_size;
240
2.44k
   int freq_size;
241
2.44k
   opus_val16 channel_offset;
242
2.44k
   opus_val32 bandE[21];
243
2.44k
   celt_glog maskLogE[3][21];
244
2.44k
   VARDECL(opus_val32, in);
245
2.44k
   VARDECL(opus_res, x);
246
2.44k
   VARDECL(opus_val32, freq);
247
2.44k
   SAVE_STACK;
248
249
2.44k
   upsample = resampling_factor(rate);
250
2.44k
   frame_size = len*upsample;
251
252
   /* LM = log2(frame_size / 120) */
253
5.95k
   for (LM=0;LM<celt_mode->maxLM;LM++)
254
5.08k
      if (celt_mode->shortMdctSize<<LM==frame_size)
255
1.56k
         break;
256
257
2.44k
   freq_size = celt_mode->shortMdctSize<<LM;
258
259
2.44k
   ALLOC(in, frame_size+overlap, opus_val32);
260
2.44k
   ALLOC(x, len, opus_res);
261
2.44k
   ALLOC(freq, freq_size, opus_val32);
262
263
2.44k
   channel_pos(channels, pos);
264
265
9.76k
   for (c=0;c<3;c++)
266
161k
      for (i=0;i<21;i++)
267
153k
         maskLogE[c][i] = -GCONST(28.f);
268
269
14.2k
   for (c=0;c<channels;c++)
270
11.8k
   {
271
11.8k
      int frame;
272
11.8k
      int nb_frames = frame_size/freq_size;
273
11.8k
      celt_assert(nb_frames*freq_size == frame_size);
274
11.8k
      OPUS_COPY(in, mem+c*overlap, overlap);
275
11.8k
      (*copy_channel_in)(x, 1, pcm, channels, c, len, NULL);
276
11.8k
      celt_preemphasis(x, in+overlap, frame_size, 1, upsample, celt_mode->preemph, preemph_mem+c, 0);
277
#ifndef FIXED_POINT
278
      {
279
         opus_val32 sum;
280
4.81k
         sum = celt_inner_prod(in, in, frame_size+overlap, 0);
281
         /* This should filter out both NaNs and ridiculous signals that could
282
            cause NaNs further down. */
283
4.81k
         if (!(sum < 1e18f) || celt_isnan(sum))
284
0
         {
285
0
            OPUS_CLEAR(in, frame_size+overlap);
286
0
            preemph_mem[c] = 0;
287
0
         }
288
      }
289
#endif
290
11.8k
      OPUS_CLEAR(bandE, 21);
291
37.6k
      for (frame=0;frame<nb_frames;frame++)
292
25.8k
      {
293
25.8k
         opus_val32 tmpE[21];
294
25.8k
         clt_mdct_forward(&celt_mode->mdct, in+freq_size*frame, freq, celt_mode->window,
295
25.8k
               overlap, celt_mode->maxLM-LM, 1, arch);
296
25.8k
         if (upsample != 1)
297
24.0k
         {
298
24.0k
            int bound = freq_size/upsample;
299
3.57M
            for (i=0;i<bound;i++)
300
3.55M
               freq[i] *= upsample;
301
14.4M
            for (;i<freq_size;i++)
302
14.4M
               freq[i] = 0;
303
24.0k
         }
304
305
25.8k
         compute_band_energies(celt_mode, freq, tmpE, 21, 1, LM, arch);
306
         /* If we have multiple frames, take the max energy. */
307
569k
         for (i=0;i<21;i++)
308
543k
            bandE[i] = MAX32(bandE[i], tmpE[i]);
309
25.8k
      }
310
11.8k
      amp2Log2(celt_mode, 21, 21, bandE, bandLogE+21*c, 1);
311
      /* Apply spreading function with -6 dB/band going up and -12 dB/band going down. */
312
248k
      for (i=1;i<21;i++)
313
236k
         bandLogE[21*c+i] = MAXG(bandLogE[21*c+i], bandLogE[21*c+i-1]-GCONST(1.f));
314
248k
      for (i=19;i>=0;i--)
315
236k
         bandLogE[21*c+i] = MAXG(bandLogE[21*c+i], bandLogE[21*c+i+1]-GCONST(2.f));
316
11.8k
      if (pos[c]==1)
317
4.24k
      {
318
93.4k
         for (i=0;i<21;i++)
319
89.2k
            maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]);
320
7.56k
      } else if (pos[c]==3)
321
4.24k
      {
322
93.4k
         for (i=0;i<21;i++)
323
89.2k
            maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]);
324
4.24k
      } else if (pos[c]==2)
325
2.40k
      {
326
52.8k
         for (i=0;i<21;i++)
327
50.4k
         {
328
50.4k
            maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]-GCONST(.5f));
329
50.4k
            maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]-GCONST(.5f));
330
50.4k
         }
331
2.40k
      }
332
#if 0
333
      for (i=0;i<21;i++)
334
         printf("%f ", bandLogE[21*c+i]);
335
      float sum=0;
336
      for (i=0;i<21;i++)
337
         sum += bandLogE[21*c+i];
338
      printf("%f ", sum/21);
339
#endif
340
11.8k
      OPUS_COPY(mem+c*overlap, in+frame_size, overlap);
341
11.8k
   }
342
53.7k
   for (i=0;i<21;i++)
343
51.2k
      maskLogE[1][i] = MIN32(maskLogE[0][i],maskLogE[2][i]);
344
2.44k
   channel_offset = HALF16(celt_log2(QCONST32(2.f,14)/(channels-1)));
345
9.76k
   for (c=0;c<3;c++)
346
161k
      for (i=0;i<21;i++)
347
153k
         maskLogE[c][i] += channel_offset;
348
#if 0
349
   for (c=0;c<3;c++)
350
   {
351
      for (i=0;i<21;i++)
352
         printf("%f ", maskLogE[c][i]);
353
   }
354
#endif
355
14.2k
   for (c=0;c<channels;c++)
356
11.8k
   {
357
11.8k
      celt_glog *mask;
358
11.8k
      if (pos[c]!=0)
359
10.9k
      {
360
10.9k
         mask = &maskLogE[pos[c]-1][0];
361
239k
         for (i=0;i<21;i++)
362
228k
            bandLogE[21*c+i] = bandLogE[21*c+i] - mask[i];
363
10.9k
      } else {
364
20.1k
         for (i=0;i<21;i++)
365
19.2k
            bandLogE[21*c+i] = 0;
366
915
      }
367
#if 0
368
      for (i=0;i<21;i++)
369
         printf("%f ", bandLogE[21*c+i]);
370
      printf("\n");
371
#endif
372
#if 0
373
      float sum=0;
374
      for (i=0;i<21;i++)
375
         sum += bandLogE[21*c+i];
376
      printf("%f ", sum/(float)QCONST32(21.f, DB_SHIFT));
377
      printf("\n");
378
#endif
379
11.8k
   }
380
2.44k
   RESTORE_STACK;
381
2.44k
}
surround_analysis
Line
Count
Source
233
1.45k
{
234
1.45k
   int c;
235
1.45k
   int i;
236
1.45k
   int LM;
237
1.45k
   int pos[8] = {0};
238
1.45k
   int upsample;
239
1.45k
   int frame_size;
240
1.45k
   int freq_size;
241
1.45k
   opus_val16 channel_offset;
242
1.45k
   opus_val32 bandE[21];
243
1.45k
   celt_glog maskLogE[3][21];
244
1.45k
   VARDECL(opus_val32, in);
245
1.45k
   VARDECL(opus_res, x);
246
1.45k
   VARDECL(opus_val32, freq);
247
1.45k
   SAVE_STACK;
248
249
1.45k
   upsample = resampling_factor(rate);
250
1.45k
   frame_size = len*upsample;
251
252
   /* LM = log2(frame_size / 120) */
253
3.34k
   for (LM=0;LM<celt_mode->maxLM;LM++)
254
2.89k
      if (celt_mode->shortMdctSize<<LM==frame_size)
255
1.00k
         break;
256
257
1.45k
   freq_size = celt_mode->shortMdctSize<<LM;
258
259
1.45k
   ALLOC(in, frame_size+overlap, opus_val32);
260
1.45k
   ALLOC(x, len, opus_res);
261
1.45k
   ALLOC(freq, freq_size, opus_val32);
262
263
1.45k
   channel_pos(channels, pos);
264
265
5.83k
   for (c=0;c<3;c++)
266
96.2k
      for (i=0;i<21;i++)
267
91.9k
         maskLogE[c][i] = -GCONST(28.f);
268
269
8.46k
   for (c=0;c<channels;c++)
270
7.00k
   {
271
7.00k
      int frame;
272
7.00k
      int nb_frames = frame_size/freq_size;
273
7.00k
      celt_assert(nb_frames*freq_size == frame_size);
274
7.00k
      OPUS_COPY(in, mem+c*overlap, overlap);
275
7.00k
      (*copy_channel_in)(x, 1, pcm, channels, c, len, NULL);
276
7.00k
      celt_preemphasis(x, in+overlap, frame_size, 1, upsample, celt_mode->preemph, preemph_mem+c, 0);
277
#ifndef FIXED_POINT
278
      {
279
         opus_val32 sum;
280
         sum = celt_inner_prod(in, in, frame_size+overlap, 0);
281
         /* This should filter out both NaNs and ridiculous signals that could
282
            cause NaNs further down. */
283
         if (!(sum < 1e18f) || celt_isnan(sum))
284
         {
285
            OPUS_CLEAR(in, frame_size+overlap);
286
            preemph_mem[c] = 0;
287
         }
288
      }
289
#endif
290
7.00k
      OPUS_CLEAR(bandE, 21);
291
21.7k
      for (frame=0;frame<nb_frames;frame++)
292
14.7k
      {
293
14.7k
         opus_val32 tmpE[21];
294
14.7k
         clt_mdct_forward(&celt_mode->mdct, in+freq_size*frame, freq, celt_mode->window,
295
14.7k
               overlap, celt_mode->maxLM-LM, 1, arch);
296
14.7k
         if (upsample != 1)
297
13.5k
         {
298
13.5k
            int bound = freq_size/upsample;
299
1.91M
            for (i=0;i<bound;i++)
300
1.90M
               freq[i] *= upsample;
301
7.79M
            for (;i<freq_size;i++)
302
7.78M
               freq[i] = 0;
303
13.5k
         }
304
305
14.7k
         compute_band_energies(celt_mode, freq, tmpE, 21, 1, LM, arch);
306
         /* If we have multiple frames, take the max energy. */
307
323k
         for (i=0;i<21;i++)
308
308k
            bandE[i] = MAX32(bandE[i], tmpE[i]);
309
14.7k
      }
310
7.00k
      amp2Log2(celt_mode, 21, 21, bandE, bandLogE+21*c, 1);
311
      /* Apply spreading function with -6 dB/band going up and -12 dB/band going down. */
312
147k
      for (i=1;i<21;i++)
313
140k
         bandLogE[21*c+i] = MAXG(bandLogE[21*c+i], bandLogE[21*c+i-1]-GCONST(1.f));
314
147k
      for (i=19;i>=0;i--)
315
140k
         bandLogE[21*c+i] = MAXG(bandLogE[21*c+i], bandLogE[21*c+i+1]-GCONST(2.f));
316
7.00k
      if (pos[c]==1)
317
2.51k
      {
318
55.3k
         for (i=0;i<21;i++)
319
52.7k
            maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]);
320
4.48k
      } else if (pos[c]==3)
321
2.51k
      {
322
55.3k
         for (i=0;i<21;i++)
323
52.7k
            maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]);
324
2.51k
      } else if (pos[c]==2)
325
1.44k
      {
326
31.6k
         for (i=0;i<21;i++)
327
30.2k
         {
328
30.2k
            maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]-GCONST(.5f));
329
30.2k
            maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]-GCONST(.5f));
330
30.2k
         }
331
1.44k
      }
332
#if 0
333
      for (i=0;i<21;i++)
334
         printf("%f ", bandLogE[21*c+i]);
335
      float sum=0;
336
      for (i=0;i<21;i++)
337
         sum += bandLogE[21*c+i];
338
      printf("%f ", sum/21);
339
#endif
340
7.00k
      OPUS_COPY(mem+c*overlap, in+frame_size, overlap);
341
7.00k
   }
342
32.0k
   for (i=0;i<21;i++)
343
30.6k
      maskLogE[1][i] = MIN32(maskLogE[0][i],maskLogE[2][i]);
344
1.45k
   channel_offset = HALF16(celt_log2(QCONST32(2.f,14)/(channels-1)));
345
5.83k
   for (c=0;c<3;c++)
346
96.2k
      for (i=0;i<21;i++)
347
91.9k
         maskLogE[c][i] += channel_offset;
348
#if 0
349
   for (c=0;c<3;c++)
350
   {
351
      for (i=0;i<21;i++)
352
         printf("%f ", maskLogE[c][i]);
353
   }
354
#endif
355
8.46k
   for (c=0;c<channels;c++)
356
7.00k
   {
357
7.00k
      celt_glog *mask;
358
7.00k
      if (pos[c]!=0)
359
6.46k
      {
360
6.46k
         mask = &maskLogE[pos[c]-1][0];
361
142k
         for (i=0;i<21;i++)
362
135k
            bandLogE[21*c+i] = bandLogE[21*c+i] - mask[i];
363
6.46k
      } else {
364
11.7k
         for (i=0;i<21;i++)
365
11.2k
            bandLogE[21*c+i] = 0;
366
534
      }
367
#if 0
368
      for (i=0;i<21;i++)
369
         printf("%f ", bandLogE[21*c+i]);
370
      printf("\n");
371
#endif
372
#if 0
373
      float sum=0;
374
      for (i=0;i<21;i++)
375
         sum += bandLogE[21*c+i];
376
      printf("%f ", sum/(float)QCONST32(21.f, DB_SHIFT));
377
      printf("\n");
378
#endif
379
7.00k
   }
380
1.45k
   RESTORE_STACK;
381
1.45k
}
surround_analysis
Line
Count
Source
233
983
{
234
983
   int c;
235
983
   int i;
236
983
   int LM;
237
983
   int pos[8] = {0};
238
983
   int upsample;
239
983
   int frame_size;
240
983
   int freq_size;
241
983
   opus_val16 channel_offset;
242
983
   opus_val32 bandE[21];
243
983
   celt_glog maskLogE[3][21];
244
983
   VARDECL(opus_val32, in);
245
983
   VARDECL(opus_res, x);
246
983
   VARDECL(opus_val32, freq);
247
983
   SAVE_STACK;
248
249
983
   upsample = resampling_factor(rate);
250
983
   frame_size = len*upsample;
251
252
   /* LM = log2(frame_size / 120) */
253
2.60k
   for (LM=0;LM<celt_mode->maxLM;LM++)
254
2.18k
      if (celt_mode->shortMdctSize<<LM==frame_size)
255
566
         break;
256
257
983
   freq_size = celt_mode->shortMdctSize<<LM;
258
259
983
   ALLOC(in, frame_size+overlap, opus_val32);
260
983
   ALLOC(x, len, opus_res);
261
983
   ALLOC(freq, freq_size, opus_val32);
262
263
983
   channel_pos(channels, pos);
264
265
3.93k
   for (c=0;c<3;c++)
266
64.8k
      for (i=0;i<21;i++)
267
61.9k
         maskLogE[c][i] = -GCONST(28.f);
268
269
5.79k
   for (c=0;c<channels;c++)
270
4.81k
   {
271
4.81k
      int frame;
272
4.81k
      int nb_frames = frame_size/freq_size;
273
4.81k
      celt_assert(nb_frames*freq_size == frame_size);
274
4.81k
      OPUS_COPY(in, mem+c*overlap, overlap);
275
4.81k
      (*copy_channel_in)(x, 1, pcm, channels, c, len, NULL);
276
4.81k
      celt_preemphasis(x, in+overlap, frame_size, 1, upsample, celt_mode->preemph, preemph_mem+c, 0);
277
4.81k
#ifndef FIXED_POINT
278
4.81k
      {
279
4.81k
         opus_val32 sum;
280
4.81k
         sum = celt_inner_prod(in, in, frame_size+overlap, 0);
281
         /* This should filter out both NaNs and ridiculous signals that could
282
            cause NaNs further down. */
283
4.81k
         if (!(sum < 1e18f) || celt_isnan(sum))
284
0
         {
285
0
            OPUS_CLEAR(in, frame_size+overlap);
286
0
            preemph_mem[c] = 0;
287
0
         }
288
4.81k
      }
289
4.81k
#endif
290
4.81k
      OPUS_CLEAR(bandE, 21);
291
15.9k
      for (frame=0;frame<nb_frames;frame++)
292
11.1k
      {
293
11.1k
         opus_val32 tmpE[21];
294
11.1k
         clt_mdct_forward(&celt_mode->mdct, in+freq_size*frame, freq, celt_mode->window,
295
11.1k
               overlap, celt_mode->maxLM-LM, 1, arch);
296
11.1k
         if (upsample != 1)
297
10.5k
         {
298
10.5k
            int bound = freq_size/upsample;
299
1.65M
            for (i=0;i<bound;i++)
300
1.64M
               freq[i] *= upsample;
301
6.67M
            for (;i<freq_size;i++)
302
6.66M
               freq[i] = 0;
303
10.5k
         }
304
305
11.1k
         compute_band_energies(celt_mode, freq, tmpE, 21, 1, LM, arch);
306
         /* If we have multiple frames, take the max energy. */
307
245k
         for (i=0;i<21;i++)
308
234k
            bandE[i] = MAX32(bandE[i], tmpE[i]);
309
11.1k
      }
310
4.81k
      amp2Log2(celt_mode, 21, 21, bandE, bandLogE+21*c, 1);
311
      /* Apply spreading function with -6 dB/band going up and -12 dB/band going down. */
312
101k
      for (i=1;i<21;i++)
313
96.2k
         bandLogE[21*c+i] = MAXG(bandLogE[21*c+i], bandLogE[21*c+i-1]-GCONST(1.f));
314
101k
      for (i=19;i>=0;i--)
315
96.2k
         bandLogE[21*c+i] = MAXG(bandLogE[21*c+i], bandLogE[21*c+i+1]-GCONST(2.f));
316
4.81k
      if (pos[c]==1)
317
1.73k
      {
318
38.1k
         for (i=0;i<21;i++)
319
36.4k
            maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]);
320
3.07k
      } else if (pos[c]==3)
321
1.73k
      {
322
38.1k
         for (i=0;i<21;i++)
323
36.4k
            maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]);
324
1.73k
      } else if (pos[c]==2)
325
963
      {
326
21.1k
         for (i=0;i<21;i++)
327
20.2k
         {
328
20.2k
            maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]-GCONST(.5f));
329
20.2k
            maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]-GCONST(.5f));
330
20.2k
         }
331
963
      }
332
#if 0
333
      for (i=0;i<21;i++)
334
         printf("%f ", bandLogE[21*c+i]);
335
      float sum=0;
336
      for (i=0;i<21;i++)
337
         sum += bandLogE[21*c+i];
338
      printf("%f ", sum/21);
339
#endif
340
4.81k
      OPUS_COPY(mem+c*overlap, in+frame_size, overlap);
341
4.81k
   }
342
21.6k
   for (i=0;i<21;i++)
343
20.6k
      maskLogE[1][i] = MIN32(maskLogE[0][i],maskLogE[2][i]);
344
983
   channel_offset = HALF16(celt_log2(QCONST32(2.f,14)/(channels-1)));
345
3.93k
   for (c=0;c<3;c++)
346
64.8k
      for (i=0;i<21;i++)
347
61.9k
         maskLogE[c][i] += channel_offset;
348
#if 0
349
   for (c=0;c<3;c++)
350
   {
351
      for (i=0;i<21;i++)
352
         printf("%f ", maskLogE[c][i]);
353
   }
354
#endif
355
5.79k
   for (c=0;c<channels;c++)
356
4.81k
   {
357
4.81k
      celt_glog *mask;
358
4.81k
      if (pos[c]!=0)
359
4.43k
      {
360
4.43k
         mask = &maskLogE[pos[c]-1][0];
361
97.5k
         for (i=0;i<21;i++)
362
93.0k
            bandLogE[21*c+i] = bandLogE[21*c+i] - mask[i];
363
4.43k
      } else {
364
8.38k
         for (i=0;i<21;i++)
365
8.00k
            bandLogE[21*c+i] = 0;
366
381
      }
367
#if 0
368
      for (i=0;i<21;i++)
369
         printf("%f ", bandLogE[21*c+i]);
370
      printf("\n");
371
#endif
372
#if 0
373
      float sum=0;
374
      for (i=0;i<21;i++)
375
         sum += bandLogE[21*c+i];
376
      printf("%f ", sum/(float)QCONST32(21.f, DB_SHIFT));
377
      printf("\n");
378
#endif
379
4.81k
   }
380
983
   RESTORE_STACK;
381
983
}
382
383
opus_int32 opus_multistream_encoder_get_size(int nb_streams, int nb_coupled_streams)
384
30.1k
{
385
30.1k
   int coupled_size;
386
30.1k
   int mono_size;
387
388
30.1k
   if(nb_streams<1||nb_coupled_streams>nb_streams||nb_coupled_streams<0)return 0;
389
30.1k
   coupled_size = opus_encoder_get_size(2);
390
30.1k
   mono_size = opus_encoder_get_size(1);
391
30.1k
   return align(sizeof(OpusMSEncoder))
392
30.1k
        + nb_coupled_streams * align(coupled_size)
393
30.1k
        + (nb_streams-nb_coupled_streams) * align(mono_size);
394
30.1k
}
395
396
opus_int32 opus_multistream_surround_encoder_get_size(int channels, int mapping_family)
397
0
{
398
0
   int nb_streams;
399
0
   int nb_coupled_streams;
400
0
   opus_int32 size;
401
402
0
   if (mapping_family==0)
403
0
   {
404
0
      if (channels==1)
405
0
      {
406
0
         nb_streams=1;
407
0
         nb_coupled_streams=0;
408
0
      } else if (channels==2)
409
0
      {
410
0
         nb_streams=1;
411
0
         nb_coupled_streams=1;
412
0
      } else
413
0
         return 0;
414
0
   } else if (mapping_family==1 && channels<=8 && channels>=1)
415
0
   {
416
0
      nb_streams=vorbis_mappings[channels-1].nb_streams;
417
0
      nb_coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams;
418
0
   } else if (mapping_family==255)
419
0
   {
420
0
      nb_streams=channels;
421
0
      nb_coupled_streams=0;
422
0
   } else if (mapping_family==2)
423
0
   {
424
0
      if (!validate_ambisonics(channels, &nb_streams, &nb_coupled_streams))
425
0
         return 0;
426
0
   } else
427
0
      return 0;
428
0
   size = opus_multistream_encoder_get_size(nb_streams, nb_coupled_streams);
429
0
   if (channels>2)
430
0
   {
431
0
      size += channels*(MAX_OVERLAP*sizeof(opus_val32) + sizeof(opus_val32));
432
0
   }
433
0
   return size;
434
0
}
435
436
static int opus_multistream_encoder_init_impl(
437
      OpusMSEncoder *st,
438
      opus_int32 Fs,
439
      int channels,
440
      int streams,
441
      int coupled_streams,
442
      const unsigned char *mapping,
443
      int application,
444
      MappingType mapping_type
445
)
446
109k
{
447
109k
   int coupled_size;
448
109k
   int mono_size;
449
109k
   int i, ret;
450
109k
   char *ptr;
451
452
109k
   if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
453
109k
       (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams) ||
454
109k
       (streams+coupled_streams>channels))
455
0
      return OPUS_BAD_ARG;
456
457
109k
   coupled_size = opus_encoder_init(NULL, Fs, 2, application);
458
109k
   if (coupled_size < 0)
459
0
      return coupled_size;
460
109k
   mono_size = opus_encoder_init(NULL, Fs, 1, application);
461
109k
   if (mono_size < 0)
462
0
      return mono_size;
463
109k
   if (st == NULL)
464
39.7k
   {
465
39.7k
      int surround_size=0;
466
39.7k
      if (mapping_type == MAPPING_TYPE_SURROUND) {
467
2.47k
         surround_size = channels*(MAX_OVERLAP*sizeof(opus_val32) + sizeof(opus_val32));
468
2.47k
      }
469
470
39.7k
      return align(sizeof(OpusMSEncoder)) + coupled_streams*align(coupled_size)
471
39.7k
             + (streams-coupled_streams)*align(mono_size) + surround_size;
472
39.7k
   }
473
474
69.9k
   st->arch = opus_select_arch();
475
69.9k
   st->layout.nb_channels = channels;
476
69.9k
   st->layout.nb_streams = streams;
477
69.9k
   st->layout.nb_coupled_streams = coupled_streams;
478
69.9k
   if (mapping_type != MAPPING_TYPE_SURROUND)
479
67.4k
      st->lfe_stream = -1;
480
69.9k
   st->bitrate_bps = OPUS_AUTO;
481
69.9k
   st->application = application;
482
69.9k
   st->Fs = Fs;
483
69.9k
   st->variable_duration = OPUS_FRAMESIZE_ARG;
484
859k
   for (i=0;i<st->layout.nb_channels;i++)
485
789k
      st->layout.mapping[i] = mapping[i];
486
69.9k
   if (!validate_layout(&st->layout))
487
25
      return OPUS_BAD_ARG;
488
69.9k
   if (!validate_encoder_layout(&st->layout))
489
335
      return OPUS_BAD_ARG;
490
69.5k
   if (mapping_type == MAPPING_TYPE_AMBISONICS &&
491
3.73k
       !validate_ambisonics(st->layout.nb_channels, NULL, NULL))
492
0
      return OPUS_BAD_ARG;
493
69.5k
   ptr = (char*)st + align(sizeof(OpusMSEncoder));
494
236k
   for (i=0;i<st->layout.nb_coupled_streams;i++)
495
166k
   {
496
166k
      ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 2, application);
497
166k
      if(ret!=OPUS_OK)return ret;
498
166k
      if (i==st->lfe_stream)
499
0
         opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1));
500
166k
      ptr += align(coupled_size);
501
166k
   }
502
424k
   for (;i<st->layout.nb_streams;i++)
503
355k
   {
504
355k
      ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 1, application);
505
355k
      if(ret!=OPUS_OK)return ret;
506
355k
      if (i==st->lfe_stream)
507
927
         opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1));
508
355k
      ptr += align(mono_size);
509
355k
   }
510
69.5k
   if (mapping_type == MAPPING_TYPE_SURROUND)
511
2.47k
   {
512
2.47k
      OPUS_CLEAR(ms_get_preemph_mem(st), channels);
513
2.47k
      OPUS_CLEAR(ms_get_window_mem(st), channels*MAX_OVERLAP);
514
2.47k
   }
515
69.5k
   st->mapping_type = mapping_type;
516
69.5k
   return OPUS_OK;
517
69.5k
}
518
519
int opus_multistream_encoder_init(
520
      OpusMSEncoder *st,
521
      opus_int32 Fs,
522
      int channels,
523
      int streams,
524
      int coupled_streams,
525
      const unsigned char *mapping,
526
      int application
527
)
528
59.7k
{
529
59.7k
   return opus_multistream_encoder_init_impl(st, Fs, channels, streams,
530
59.7k
                                             coupled_streams, mapping,
531
59.7k
                                             application, MAPPING_TYPE_NONE);
532
59.7k
}
533
534
int opus_multistream_surround_encoder_init(
535
      OpusMSEncoder *st,
536
      opus_int32 Fs,
537
      int channels,
538
      int mapping_family,
539
      int *streams,
540
      int *coupled_streams,
541
      unsigned char *mapping,
542
      int application
543
)
544
50.1k
{
545
50.1k
   MappingType mapping_type;
546
50.1k
   int lfe_stream;
547
548
50.1k
   if ((channels>255) || (channels<1))
549
0
      return OPUS_BAD_ARG;
550
50.1k
   lfe_stream = -1;
551
50.1k
   if (mapping_family==0)
552
11.4k
   {
553
11.4k
      if (channels==1)
554
5.76k
      {
555
5.76k
         *streams=1;
556
5.76k
         *coupled_streams=0;
557
5.76k
         mapping[0]=0;
558
5.76k
      } else if (channels==2)
559
5.59k
      {
560
5.59k
         *streams=1;
561
5.59k
         *coupled_streams=1;
562
5.59k
         mapping[0]=0;
563
5.59k
         mapping[1]=1;
564
5.59k
      } else
565
84
         return OPUS_UNIMPLEMENTED;
566
38.7k
   } else if (mapping_family==1 && channels<=8 && channels>=1)
567
8.08k
   {
568
8.08k
      int i;
569
8.08k
      *streams=vorbis_mappings[channels-1].nb_streams;
570
8.08k
      *coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams;
571
36.7k
      for (i=0;i<channels;i++)
572
28.6k
         mapping[i] = vorbis_mappings[channels-1].mapping[i];
573
8.08k
      if (channels>=6)
574
1.85k
         lfe_stream = *streams-1;
575
30.6k
   } else if (mapping_family==255)
576
23.0k
   {
577
23.0k
      int i;
578
23.0k
      *streams=channels;
579
23.0k
      *coupled_streams=0;
580
581k
      for(i=0;i<channels;i++)
581
558k
         mapping[i] = i;
582
23.0k
   } else if (mapping_family==2)
583
7.56k
   {
584
7.56k
      int i;
585
7.56k
      if (!validate_ambisonics(channels, streams, coupled_streams))
586
101
         return OPUS_BAD_ARG;
587
112k
      for(i = 0; i < (*streams - *coupled_streams); i++)
588
104k
         mapping[i] = i + (*coupled_streams * 2);
589
10.3k
      for(i = 0; i < *coupled_streams * 2; i++)
590
2.87k
         mapping[i + (*streams - *coupled_streams)] = i;
591
7.46k
   } else
592
29
      return OPUS_UNIMPLEMENTED;
593
594
49.9k
   if (channels>2 && mapping_family==1) {
595
4.95k
      mapping_type = MAPPING_TYPE_SURROUND;
596
45.0k
   } else if (mapping_family==2)
597
7.46k
   {
598
7.46k
      mapping_type = MAPPING_TYPE_AMBISONICS;
599
7.46k
   } else
600
37.5k
   {
601
37.5k
      mapping_type = MAPPING_TYPE_NONE;
602
37.5k
   }
603
49.9k
   if (st != NULL) {
604
24.9k
      st->lfe_stream = lfe_stream;
605
24.9k
   }
606
49.9k
   return opus_multistream_encoder_init_impl(st, Fs, channels, *streams,
607
49.9k
                                             *coupled_streams, mapping,
608
49.9k
                                             application, mapping_type);
609
50.1k
}
610
611
OpusMSEncoder *opus_multistream_encoder_create(
612
      opus_int32 Fs,
613
      int channels,
614
      int streams,
615
      int coupled_streams,
616
      const unsigned char *mapping,
617
      int application,
618
      int *error
619
)
620
14.9k
{
621
14.9k
   int ret;
622
14.9k
   OpusMSEncoder *st;
623
14.9k
   opus_int32 size;
624
14.9k
   if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
625
14.9k
       (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams) ||
626
14.7k
       (streams+coupled_streams>channels))
627
240
   {
628
240
      if (error)
629
240
         *error = OPUS_BAD_ARG;
630
240
      return NULL;
631
240
   }
632
14.7k
   size = opus_multistream_encoder_init(NULL, Fs, channels, streams, coupled_streams, mapping, application);
633
14.7k
   if (size < 0)
634
0
   {
635
0
      if (error)
636
0
         *error = size;
637
0
      return NULL;
638
0
   }
639
14.7k
   st = (OpusMSEncoder *)opus_alloc(size);
640
14.7k
   if (st==NULL)
641
0
   {
642
0
      if (error)
643
0
         *error = OPUS_ALLOC_FAIL;
644
0
      return NULL;
645
0
   }
646
14.7k
   ret = opus_multistream_encoder_init(st, Fs, channels, streams, coupled_streams, mapping, application);
647
14.7k
   if (ret != OPUS_OK)
648
360
   {
649
360
      opus_free(st);
650
360
      st = NULL;
651
360
   }
652
14.7k
   if (error)
653
14.7k
      *error = ret;
654
14.7k
   return st;
655
14.7k
}
656
657
OpusMSEncoder *opus_multistream_surround_encoder_create(
658
      opus_int32 Fs,
659
      int channels,
660
      int mapping_family,
661
      int *streams,
662
      int *coupled_streams,
663
      unsigned char *mapping,
664
      int application,
665
      int *error
666
)
667
25.2k
{
668
25.2k
   int ret;
669
25.2k
   opus_int32 size;
670
25.2k
   OpusMSEncoder *st;
671
25.2k
   if ((channels>255) || (channels<1))
672
46
   {
673
46
      if (error)
674
46
         *error = OPUS_BAD_ARG;
675
46
      return NULL;
676
46
   }
677
25.2k
   size = opus_multistream_surround_encoder_init(NULL, Fs, channels, mapping_family, streams, coupled_streams, mapping, application);
678
25.2k
   if (size < 0)
679
214
   {
680
214
      if (error)
681
214
         *error = size;
682
214
      return NULL;
683
214
   }
684
24.9k
   st = (OpusMSEncoder *)opus_alloc(size);
685
24.9k
   if (st==NULL)
686
0
   {
687
0
      if (error)
688
0
         *error = OPUS_ALLOC_FAIL;
689
0
      return NULL;
690
0
   }
691
24.9k
   ret = opus_multistream_surround_encoder_init(st, Fs, channels, mapping_family, streams, coupled_streams, mapping, application);
692
24.9k
   if (ret != OPUS_OK)
693
0
   {
694
0
      opus_free(st);
695
0
      st = NULL;
696
0
   }
697
24.9k
   if (error)
698
24.9k
      *error = ret;
699
24.9k
   return st;
700
24.9k
}
701
702
static void surround_rate_allocation(
703
      OpusMSEncoder *st,
704
      opus_int32 *rate,
705
      int frame_size,
706
      opus_int32 Fs
707
      )
708
64.0k
{
709
64.0k
   int i;
710
64.0k
   opus_int32 channel_rate;
711
64.0k
   int stream_offset;
712
64.0k
   int lfe_offset;
713
64.0k
   int coupled_ratio; /* Q8 */
714
64.0k
   int lfe_ratio;     /* Q8 */
715
64.0k
   int nb_lfe;
716
64.0k
   int nb_uncoupled;
717
64.0k
   int nb_coupled;
718
64.0k
   int nb_normal;
719
64.0k
   opus_int32 channel_offset;
720
64.0k
   opus_int32 bitrate;
721
64.0k
   int total;
722
723
64.0k
   nb_lfe = (st->lfe_stream!=-1);
724
64.0k
   nb_coupled = st->layout.nb_coupled_streams;
725
64.0k
   nb_uncoupled = st->layout.nb_streams-nb_coupled-nb_lfe;
726
64.0k
   nb_normal = 2*nb_coupled + nb_uncoupled;
727
728
   /* Give each non-LFE channel enough bits per channel for coding band energy. */
729
64.0k
   channel_offset = 40*IMAX(50, Fs/frame_size);
730
731
64.0k
   if (st->bitrate_bps==OPUS_AUTO)
732
64.0k
   {
733
64.0k
      bitrate = nb_normal*(channel_offset + Fs + 10000) + 8000*nb_lfe;
734
64.0k
   } else if (st->bitrate_bps==OPUS_BITRATE_MAX)
735
0
   {
736
0
      bitrate = nb_normal*750000 + nb_lfe*128000;
737
0
   } else {
738
0
      bitrate = st->bitrate_bps;
739
0
   }
740
741
   /* Give LFE some basic stream_channel allocation but never exceed 1/20 of the
742
      total rate for the non-energy part to avoid problems at really low rate. */
743
64.0k
   lfe_offset = IMIN(bitrate/20, 3000) + 15*IMAX(50, Fs/frame_size);
744
745
   /* We give each stream (coupled or uncoupled) a starting bitrate.
746
      This models the main saving of coupled channels over uncoupled. */
747
64.0k
   stream_offset = (bitrate - channel_offset*nb_normal - lfe_offset*nb_lfe)/nb_normal/2;
748
64.0k
   stream_offset = IMAX(0, IMIN(20000, stream_offset));
749
750
   /* Coupled streams get twice the mono rate after the offset is allocated. */
751
64.0k
   coupled_ratio = 512;
752
   /* Should depend on the bitrate, for now we assume LFE gets 1/8 the bits of mono */
753
64.0k
   lfe_ratio = 32;
754
755
64.0k
   total = (nb_uncoupled<<8)         /* mono */
756
64.0k
         + coupled_ratio*nb_coupled /* stereo */
757
64.0k
         + nb_lfe*lfe_ratio;
758
64.0k
   channel_rate = 256*(opus_int64)(bitrate - lfe_offset*nb_lfe - stream_offset*(nb_coupled+nb_uncoupled) - channel_offset*nb_normal)/total;
759
760
479k
   for (i=0;i<st->layout.nb_streams;i++)
761
415k
   {
762
415k
      if (i<st->layout.nb_coupled_streams)
763
161k
         rate[i] = 2*channel_offset + IMAX(0, stream_offset+(channel_rate*coupled_ratio>>8));
764
254k
      else if (i!=st->lfe_stream)
765
253k
         rate[i] = channel_offset + IMAX(0, stream_offset + channel_rate);
766
915
      else
767
915
         rate[i] = IMAX(0, lfe_offset+(channel_rate*lfe_ratio>>8));
768
415k
   }
769
64.0k
}
770
771
static void ambisonics_rate_allocation(
772
      OpusMSEncoder *st,
773
      opus_int32 *rate,
774
      int frame_size,
775
      opus_int32 Fs
776
      )
777
3.61k
{
778
3.61k
   int i;
779
3.61k
   opus_int32 total_rate;
780
3.61k
   opus_int32 per_stream_rate;
781
782
3.61k
   const int nb_channels = st->layout.nb_streams + st->layout.nb_coupled_streams;
783
784
3.61k
   if (st->bitrate_bps==OPUS_AUTO)
785
3.61k
   {
786
3.61k
      total_rate = (st->layout.nb_coupled_streams + st->layout.nb_streams) *
787
3.61k
         (Fs+60*Fs/frame_size) + st->layout.nb_streams * (opus_int32)15000;
788
3.61k
   } else if (st->bitrate_bps==OPUS_BITRATE_MAX)
789
0
   {
790
0
      total_rate = nb_channels * 750000;
791
0
   } else
792
0
   {
793
0
      total_rate = st->bitrate_bps;
794
0
   }
795
796
   /* Allocate equal number of bits to Ambisonic (uncoupled) and non-diegetic
797
    * (coupled) streams */
798
3.61k
   per_stream_rate = total_rate / st->layout.nb_streams;
799
50.1k
   for (i = 0; i < st->layout.nb_streams; i++)
800
46.5k
   {
801
46.5k
     rate[i] = per_stream_rate;
802
46.5k
   }
803
3.61k
}
804
805
static opus_int32 rate_allocation(
806
      OpusMSEncoder *st,
807
      opus_int32 *rate,
808
      int frame_size
809
      )
810
67.6k
{
811
67.6k
   int i;
812
67.6k
   opus_int32 rate_sum=0;
813
67.6k
   opus_int32 Fs;
814
67.6k
   char *ptr;
815
816
67.6k
   ptr = (char*)st + align(sizeof(OpusMSEncoder));
817
67.6k
   opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
818
819
67.6k
   if (st->mapping_type == MAPPING_TYPE_AMBISONICS) {
820
3.61k
     ambisonics_rate_allocation(st, rate, frame_size, Fs);
821
3.61k
   } else
822
64.0k
   {
823
64.0k
     surround_rate_allocation(st, rate, frame_size, Fs);
824
64.0k
   }
825
826
529k
   for (i=0;i<st->layout.nb_streams;i++)
827
461k
   {
828
461k
      rate[i] = IMAX(rate[i], 500);
829
461k
      rate_sum += rate[i];
830
461k
   }
831
67.6k
   return rate_sum;
832
67.6k
}
833
834
/* Max size in case the encoder decides to return six frames (6 x 20 ms = 120 ms) */
835
#ifdef ENABLE_QEXT
836
#define MS_FRAME_TMP (6*QEXT_PACKET_SIZE_CAP+12)
837
#else
838
#define MS_FRAME_TMP (6*1275+12)
839
#endif
840
841
int opus_multistream_encode_native
842
(
843
    OpusMSEncoder *st,
844
    opus_copy_channel_in_func copy_channel_in,
845
    const void *pcm,
846
    int analysis_frame_size,
847
    unsigned char *data,
848
    opus_int32 max_data_bytes,
849
    int lsb_depth,
850
    downmix_func downmix,
851
    int float_api,
852
    void *user_data
853
)
854
67.6k
{
855
67.6k
   opus_int32 Fs;
856
67.6k
   int coupled_size;
857
67.6k
   int mono_size;
858
67.6k
   int s;
859
67.6k
   char *ptr;
860
67.6k
   int tot_size;
861
67.6k
   VARDECL(opus_res, buf);
862
67.6k
   VARDECL(celt_glog, bandSMR);
863
67.6k
   unsigned char tmp_data[MS_FRAME_TMP];
864
67.6k
   OpusRepacketizer rp;
865
67.6k
   opus_int32 vbr;
866
67.6k
   const CELTMode *celt_mode=NULL;
867
67.6k
   opus_int32 bitrates[256];
868
67.6k
   celt_glog bandLogE[42];
869
67.6k
   opus_val32 *mem = NULL;
870
67.6k
   opus_val32 *preemph_mem=NULL;
871
67.6k
   int frame_size;
872
67.6k
   opus_int32 rate_sum;
873
67.6k
   opus_int32 smallest_packet;
874
67.6k
   ALLOC_STACK;
875
876
67.6k
   if (st->mapping_type == MAPPING_TYPE_SURROUND)
877
2.44k
   {
878
2.44k
      preemph_mem = ms_get_preemph_mem(st);
879
2.44k
      mem = ms_get_window_mem(st);
880
2.44k
   }
881
882
67.6k
   ptr = (char*)st + align(sizeof(OpusMSEncoder));
883
67.6k
   opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
884
67.6k
   opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_VBR(&vbr));
885
67.6k
   if (st->application != OPUS_APPLICATION_RESTRICTED_SILK)
886
67.6k
      opus_encoder_ctl((OpusEncoder*)ptr, CELT_GET_MODE(&celt_mode));
887
888
67.6k
   frame_size = frame_size_select(st->application, analysis_frame_size, st->variable_duration, Fs);
889
67.6k
   if (frame_size <= 0)
890
0
   {
891
0
      RESTORE_STACK;
892
0
      return OPUS_BAD_ARG;
893
0
   }
894
895
   /* Smallest packet the encoder can produce. */
896
67.6k
   smallest_packet = st->layout.nb_streams*2-1;
897
   /* 100 ms needs an extra byte per stream for the ToC. */
898
67.6k
   if (Fs/frame_size == 10)
899
4.43k
     smallest_packet += st->layout.nb_streams;
900
67.6k
   if (max_data_bytes < smallest_packet)
901
0
   {
902
0
      RESTORE_STACK;
903
0
      return OPUS_BUFFER_TOO_SMALL;
904
0
   }
905
67.6k
   ALLOC(buf, 2*frame_size, opus_res);
906
67.6k
   coupled_size = opus_encoder_init(NULL, st->Fs, 2, st->application);
907
67.6k
   mono_size = opus_encoder_init(NULL, st->Fs, 1, st->application);
908
909
67.6k
   ALLOC(bandSMR, 21*st->layout.nb_channels, celt_glog);
910
67.6k
   if (st->mapping_type == MAPPING_TYPE_SURROUND && st->application != OPUS_APPLICATION_RESTRICTED_SILK)
911
2.44k
   {
912
2.44k
      surround_analysis(celt_mode, pcm, bandSMR, mem, preemph_mem, frame_size, celt_mode->overlap, st->layout.nb_channels, Fs, copy_channel_in, st->arch);
913
2.44k
   }
914
915
   /* Compute bitrate allocation between streams (this could be a lot better) */
916
67.6k
   rate_sum = rate_allocation(st, bitrates, frame_size);
917
918
67.6k
   if (!vbr)
919
34.8k
   {
920
34.8k
      if (st->bitrate_bps == OPUS_AUTO)
921
34.8k
      {
922
34.8k
         max_data_bytes = IMIN(max_data_bytes, (bitrate_to_bits(rate_sum, Fs, frame_size)+4)/8);
923
34.8k
      } else if (st->bitrate_bps != OPUS_BITRATE_MAX)
924
0
      {
925
0
         max_data_bytes = IMIN(max_data_bytes, IMAX(smallest_packet,
926
0
                          (bitrate_to_bits(st->bitrate_bps, Fs, frame_size)+4)/8));
927
0
      }
928
34.8k
   }
929
67.6k
   ptr = (char*)st + align(sizeof(OpusMSEncoder));
930
529k
   for (s=0;s<st->layout.nb_streams;s++)
931
461k
   {
932
461k
      OpusEncoder *enc;
933
461k
      enc = (OpusEncoder*)ptr;
934
461k
      if (s < st->layout.nb_coupled_streams)
935
161k
         ptr += align(coupled_size);
936
299k
      else
937
299k
         ptr += align(mono_size);
938
461k
      opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrates[s]));
939
461k
      if (st->mapping_type == MAPPING_TYPE_SURROUND)
940
7.15k
      {
941
7.15k
         opus_int32 equiv_rate;
942
7.15k
         equiv_rate = st->bitrate_bps;
943
7.15k
         if (frame_size*50 < Fs)
944
4.35k
            equiv_rate -= 60*(Fs/frame_size - 50)*st->layout.nb_channels;
945
7.15k
         if (equiv_rate > 10000*st->layout.nb_channels)
946
0
            opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
947
7.15k
         else if (equiv_rate > 7000*st->layout.nb_channels)
948
0
            opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_SUPERWIDEBAND));
949
7.15k
         else if (equiv_rate > 5000*st->layout.nb_channels)
950
0
            opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_WIDEBAND));
951
7.15k
         else
952
7.15k
            opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND));
953
7.15k
         if (s < st->layout.nb_coupled_streams)
954
4.65k
         {
955
            /* To preserve the spatial image, force stereo CELT on coupled streams */
956
4.65k
            opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY));
957
4.65k
            opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(2));
958
4.65k
         }
959
7.15k
      }
960
454k
      else if (st->mapping_type == MAPPING_TYPE_AMBISONICS) {
961
46.5k
        opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY));
962
46.5k
      }
963
461k
   }
964
965
67.6k
   ptr = (char*)st + align(sizeof(OpusMSEncoder));
966
   /* Counting ToC */
967
67.6k
   tot_size = 0;
968
529k
   for (s=0;s<st->layout.nb_streams;s++)
969
461k
   {
970
461k
      OpusEncoder *enc;
971
461k
      int len;
972
461k
      int curr_max;
973
461k
      int c1, c2;
974
461k
      int ret;
975
976
461k
      opus_repacketizer_init(&rp);
977
461k
      enc = (OpusEncoder*)ptr;
978
461k
      if (s < st->layout.nb_coupled_streams)
979
161k
      {
980
161k
         int i;
981
161k
         int left, right;
982
161k
         left = get_left_channel(&st->layout, s, -1);
983
161k
         right = get_right_channel(&st->layout, s, -1);
984
161k
         (*copy_channel_in)(buf, 2,
985
161k
            pcm, st->layout.nb_channels, left, frame_size, user_data);
986
161k
         (*copy_channel_in)(buf+1, 2,
987
161k
            pcm, st->layout.nb_channels, right, frame_size, user_data);
988
161k
         ptr += align(coupled_size);
989
161k
         if (st->mapping_type == MAPPING_TYPE_SURROUND && st->application != OPUS_APPLICATION_RESTRICTED_SILK)
990
4.65k
         {
991
102k
            for (i=0;i<21;i++)
992
97.8k
            {
993
97.8k
               bandLogE[i] = bandSMR[21*left+i];
994
97.8k
               bandLogE[21+i] = bandSMR[21*right+i];
995
97.8k
            }
996
4.65k
         }
997
161k
         c1 = left;
998
161k
         c2 = right;
999
299k
      } else {
1000
299k
         int i;
1001
299k
         int chan = get_mono_channel(&st->layout, s, -1);
1002
299k
         (*copy_channel_in)(buf, 1,
1003
299k
            pcm, st->layout.nb_channels, chan, frame_size, user_data);
1004
299k
         ptr += align(mono_size);
1005
299k
         if (st->mapping_type == MAPPING_TYPE_SURROUND && st->application != OPUS_APPLICATION_RESTRICTED_SILK)
1006
2.49k
         {
1007
54.9k
            for (i=0;i<21;i++)
1008
52.4k
               bandLogE[i] = bandSMR[21*chan+i];
1009
2.49k
         }
1010
299k
         c1 = chan;
1011
299k
         c2 = -1;
1012
299k
      }
1013
461k
      if (st->mapping_type == MAPPING_TYPE_SURROUND && st->application != OPUS_APPLICATION_RESTRICTED_SILK)
1014
7.15k
         opus_encoder_ctl(enc, OPUS_SET_ENERGY_MASK(bandLogE));
1015
      /* number of bytes left (+Toc) */
1016
461k
      curr_max = max_data_bytes - tot_size;
1017
      /* Reserve one byte for the last stream and two for the others */
1018
461k
      curr_max -= IMAX(0,2*(st->layout.nb_streams-s-1)-1);
1019
      /* For 100 ms, reserve an extra byte per stream for the ToC */
1020
461k
      if (Fs/frame_size == 10)
1021
26.5k
        curr_max -= st->layout.nb_streams-s-1;
1022
461k
      curr_max = IMIN(curr_max,MS_FRAME_TMP);
1023
      /* Repacketizer will add one or two bytes for self-delimited frames */
1024
461k
      if (s != st->layout.nb_streams-1) curr_max -=  curr_max>253 ? 2 : 1;
1025
461k
      if (!vbr && s == st->layout.nb_streams-1)
1026
34.8k
         opus_encoder_ctl(enc, OPUS_SET_BITRATE(bits_to_bitrate(curr_max*8, Fs, frame_size)));
1027
461k
      len = opus_encode_native(enc, buf, frame_size, tmp_data, curr_max, lsb_depth,
1028
461k
            pcm, analysis_frame_size, c1, c2, st->layout.nb_channels, downmix, float_api);
1029
461k
      if (len<0)
1030
0
      {
1031
0
         RESTORE_STACK;
1032
0
         return len;
1033
0
      }
1034
      /* We need to use the repacketizer to add the self-delimiting lengths
1035
         while taking into account the fact that the encoder can now return
1036
         more than one frame at a time (e.g. 60 ms CELT-only) */
1037
461k
      ret = opus_repacketizer_cat(&rp, tmp_data, len);
1038
      /* If the opus_repacketizer_cat() fails, then something's seriously wrong
1039
         with the encoder. */
1040
461k
      if (ret != OPUS_OK)
1041
0
      {
1042
0
         RESTORE_STACK;
1043
0
         return OPUS_INTERNAL_ERROR;
1044
0
      }
1045
461k
      len = opus_repacketizer_out_range_impl(&rp, 0, opus_repacketizer_get_nb_frames(&rp),
1046
461k
            data, max_data_bytes-tot_size, s != st->layout.nb_streams-1, !vbr && s == st->layout.nb_streams-1, NULL, 0);
1047
461k
      data += len;
1048
461k
      tot_size += len;
1049
461k
   }
1050
   /*printf("\n");*/
1051
67.6k
   RESTORE_STACK;
1052
67.6k
   return tot_size;
1053
67.6k
}
1054
1055
#if !defined(DISABLE_FLOAT_API)
1056
static void opus_copy_channel_in_float(
1057
  opus_res *dst,
1058
  int dst_stride,
1059
  const void *src,
1060
  int src_stride,
1061
  int src_channel,
1062
  int frame_size,
1063
  void *user_data
1064
)
1065
0
{
1066
0
   const float *float_src;
1067
0
   opus_int32 i;
1068
0
   (void)user_data;
1069
0
   float_src = (const float *)src;
1070
0
   for (i=0;i<frame_size;i++)
1071
0
      dst[i*dst_stride] = FLOAT2RES(float_src[i*src_stride+src_channel]);
1072
0
}
1073
#endif
1074
1075
static void opus_copy_channel_in_short(
1076
  opus_res *dst,
1077
  int dst_stride,
1078
  const void *src,
1079
  int src_stride,
1080
  int src_channel,
1081
  int frame_size,
1082
  void *user_data
1083
)
1084
722k
{
1085
722k
   const opus_int16 *short_src;
1086
722k
   opus_int32 i;
1087
722k
   (void)user_data;
1088
722k
   short_src = (const opus_int16 *)src;
1089
222M
   for (i=0;i<frame_size;i++)
1090
221M
      dst[i*dst_stride] = INT16TORES(short_src[i*src_stride+src_channel]);
1091
722k
}
opus_multistream_encoder.c:opus_copy_channel_in_short
Line
Count
Source
1084
361k
{
1085
361k
   const opus_int16 *short_src;
1086
361k
   opus_int32 i;
1087
361k
   (void)user_data;
1088
361k
   short_src = (const opus_int16 *)src;
1089
111M
   for (i=0;i<frame_size;i++)
1090
110M
      dst[i*dst_stride] = INT16TORES(short_src[i*src_stride+src_channel]);
1091
361k
}
opus_multistream_encoder.c:opus_copy_channel_in_short
Line
Count
Source
1084
361k
{
1085
361k
   const opus_int16 *short_src;
1086
361k
   opus_int32 i;
1087
361k
   (void)user_data;
1088
361k
   short_src = (const opus_int16 *)src;
1089
111M
   for (i=0;i<frame_size;i++)
1090
110M
      dst[i*dst_stride] = INT16TORES(short_src[i*src_stride+src_channel]);
1091
361k
}
1092
1093
static void opus_copy_channel_in_int24(
1094
  opus_res *dst,
1095
  int dst_stride,
1096
  const void *src,
1097
  int src_stride,
1098
  int src_channel,
1099
  int frame_size,
1100
  void *user_data
1101
)
1102
0
{
1103
0
   const opus_int32 *short_src;
1104
0
   opus_int32 i;
1105
0
   (void)user_data;
1106
0
   short_src = (const opus_int32 *)src;
1107
0
   for (i=0;i<frame_size;i++)
1108
0
      dst[i*dst_stride] = INT24TORES(short_src[i*src_stride+src_channel]);
1109
0
}
1110
1111
int opus_multistream_encode(
1112
    OpusMSEncoder *st,
1113
    const opus_int16 *pcm,
1114
    int frame_size,
1115
    unsigned char *data,
1116
    opus_int32 max_data_bytes
1117
)
1118
38.2k
{
1119
38.2k
   return opus_multistream_encode_native(st, opus_copy_channel_in_short,
1120
38.2k
      pcm, frame_size, data, max_data_bytes, 16, downmix_int, 0, NULL);
1121
38.2k
}
1122
1123
int opus_multistream_encode24(
1124
    OpusMSEncoder *st,
1125
    const opus_int32 *pcm,
1126
    int frame_size,
1127
    unsigned char *data,
1128
    opus_int32 max_data_bytes
1129
)
1130
0
{
1131
0
   return opus_multistream_encode_native(st, opus_copy_channel_in_int24,
1132
0
      pcm, frame_size, data, max_data_bytes, MAX_ENCODING_DEPTH, downmix_int24, 0, NULL);
1133
0
}
1134
1135
#ifndef DISABLE_FLOAT_API
1136
int opus_multistream_encode_float(
1137
    OpusMSEncoder *st,
1138
    const float *pcm,
1139
    int frame_size,
1140
    unsigned char *data,
1141
    opus_int32 max_data_bytes
1142
)
1143
0
{
1144
0
   return opus_multistream_encode_native(st, opus_copy_channel_in_float,
1145
0
      pcm, frame_size, data, max_data_bytes, MAX_ENCODING_DEPTH, downmix_float, 1, NULL);
1146
0
}
1147
#endif
1148
1149
int opus_multistream_encoder_ctl_va_list(OpusMSEncoder *st, int request,
1150
                                         va_list ap)
1151
834k
{
1152
834k
   int coupled_size, mono_size;
1153
834k
   char *ptr;
1154
834k
   int ret = OPUS_OK;
1155
1156
834k
   coupled_size = opus_encoder_init(NULL, st->Fs, 2, st->application);
1157
834k
   mono_size = opus_encoder_init(NULL, st->Fs, 1, st->application);
1158
834k
   ptr = (char*)st + align(sizeof(OpusMSEncoder));
1159
834k
   switch (request)
1160
834k
   {
1161
0
   case OPUS_SET_BITRATE_REQUEST:
1162
0
   {
1163
0
      opus_int32 value = va_arg(ap, opus_int32);
1164
0
      if (value != OPUS_AUTO && value != OPUS_BITRATE_MAX)
1165
0
      {
1166
0
         if (value <= 0)
1167
0
            goto bad_arg;
1168
0
         value = IMIN(750000*st->layout.nb_channels, IMAX(500*st->layout.nb_channels, value));
1169
0
      }
1170
0
      st->bitrate_bps = value;
1171
0
   }
1172
0
   break;
1173
0
   case OPUS_GET_BITRATE_REQUEST:
1174
0
   {
1175
0
      int s;
1176
0
      opus_int32 *value = va_arg(ap, opus_int32*);
1177
0
      if (!value)
1178
0
      {
1179
0
         goto bad_arg;
1180
0
      }
1181
0
      *value = 0;
1182
0
      for (s=0;s<st->layout.nb_streams;s++)
1183
0
      {
1184
0
         opus_int32 rate;
1185
0
         OpusEncoder *enc;
1186
0
         enc = (OpusEncoder*)ptr;
1187
0
         if (s < st->layout.nb_coupled_streams)
1188
0
            ptr += align(coupled_size);
1189
0
         else
1190
0
            ptr += align(mono_size);
1191
0
         opus_encoder_ctl(enc, request, &rate);
1192
0
         *value += rate;
1193
0
      }
1194
0
   }
1195
0
   break;
1196
0
   case OPUS_GET_LSB_DEPTH_REQUEST:
1197
0
   case OPUS_GET_VBR_REQUEST:
1198
0
   case OPUS_GET_APPLICATION_REQUEST:
1199
0
   case OPUS_GET_BANDWIDTH_REQUEST:
1200
0
   case OPUS_GET_COMPLEXITY_REQUEST:
1201
0
   case OPUS_GET_PACKET_LOSS_PERC_REQUEST:
1202
0
   case OPUS_GET_DTX_REQUEST:
1203
0
   case OPUS_GET_VOICE_RATIO_REQUEST:
1204
0
   case OPUS_GET_VBR_CONSTRAINT_REQUEST:
1205
0
   case OPUS_GET_SIGNAL_REQUEST:
1206
0
   case OPUS_GET_LOOKAHEAD_REQUEST:
1207
0
   case OPUS_GET_SAMPLE_RATE_REQUEST:
1208
0
   case OPUS_GET_INBAND_FEC_REQUEST:
1209
0
   case OPUS_GET_FORCE_CHANNELS_REQUEST:
1210
0
   case OPUS_GET_PREDICTION_DISABLED_REQUEST:
1211
0
   case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST:
1212
0
   case OPUS_GET_QEXT_REQUEST:
1213
0
   {
1214
0
      OpusEncoder *enc;
1215
      /* For int32* GET params, just query the first stream */
1216
0
      opus_int32 *value = va_arg(ap, opus_int32*);
1217
0
      enc = (OpusEncoder*)ptr;
1218
0
      ret = opus_encoder_ctl(enc, request, value);
1219
0
   }
1220
0
   break;
1221
0
   case OPUS_GET_FINAL_RANGE_REQUEST:
1222
0
   {
1223
0
      int s;
1224
0
      opus_uint32 *value = va_arg(ap, opus_uint32*);
1225
0
      opus_uint32 tmp;
1226
0
      if (!value)
1227
0
      {
1228
0
         goto bad_arg;
1229
0
      }
1230
0
      *value=0;
1231
0
      for (s=0;s<st->layout.nb_streams;s++)
1232
0
      {
1233
0
         OpusEncoder *enc;
1234
0
         enc = (OpusEncoder*)ptr;
1235
0
         if (s < st->layout.nb_coupled_streams)
1236
0
            ptr += align(coupled_size);
1237
0
         else
1238
0
            ptr += align(mono_size);
1239
0
         ret = opus_encoder_ctl(enc, request, &tmp);
1240
0
         if (ret != OPUS_OK) break;
1241
0
         *value ^= tmp;
1242
0
      }
1243
0
   }
1244
0
   break;
1245
69.5k
   case OPUS_SET_LSB_DEPTH_REQUEST:
1246
139k
   case OPUS_SET_COMPLEXITY_REQUEST:
1247
208k
   case OPUS_SET_VBR_REQUEST:
1248
278k
   case OPUS_SET_VBR_CONSTRAINT_REQUEST:
1249
347k
   case OPUS_SET_MAX_BANDWIDTH_REQUEST:
1250
347k
   case OPUS_SET_BANDWIDTH_REQUEST:
1251
417k
   case OPUS_SET_SIGNAL_REQUEST:
1252
417k
   case OPUS_SET_APPLICATION_REQUEST:
1253
487k
   case OPUS_SET_INBAND_FEC_REQUEST:
1254
556k
   case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
1255
626k
   case OPUS_SET_DTX_REQUEST:
1256
626k
   case OPUS_SET_FORCE_MODE_REQUEST:
1257
695k
   case OPUS_SET_FORCE_CHANNELS_REQUEST:
1258
765k
   case OPUS_SET_PREDICTION_DISABLED_REQUEST:
1259
834k
   case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST:
1260
834k
   case OPUS_SET_QEXT_REQUEST:
1261
834k
   {
1262
834k
      int s;
1263
      /* This works for int32 params */
1264
834k
      opus_int32 value = va_arg(ap, opus_int32);
1265
7.03M
      for (s=0;s<st->layout.nb_streams;s++)
1266
6.20M
      {
1267
6.20M
         OpusEncoder *enc;
1268
1269
6.20M
         enc = (OpusEncoder*)ptr;
1270
6.20M
         if (s < st->layout.nb_coupled_streams)
1271
2.00M
            ptr += align(coupled_size);
1272
4.20M
         else
1273
4.20M
            ptr += align(mono_size);
1274
6.20M
         ret = opus_encoder_ctl(enc, request, value);
1275
6.20M
         if (ret != OPUS_OK)
1276
7.47k
            break;
1277
6.20M
      }
1278
834k
   }
1279
834k
   break;
1280
0
   case OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST:
1281
0
   {
1282
0
      int s;
1283
0
      opus_int32 stream_id;
1284
0
      OpusEncoder **value;
1285
0
      stream_id = va_arg(ap, opus_int32);
1286
0
      if (stream_id<0 || stream_id >= st->layout.nb_streams)
1287
0
         goto bad_arg;
1288
0
      value = va_arg(ap, OpusEncoder**);
1289
0
      if (!value)
1290
0
      {
1291
0
         goto bad_arg;
1292
0
      }
1293
0
      for (s=0;s<stream_id;s++)
1294
0
      {
1295
0
         if (s < st->layout.nb_coupled_streams)
1296
0
            ptr += align(coupled_size);
1297
0
         else
1298
0
            ptr += align(mono_size);
1299
0
      }
1300
0
      *value = (OpusEncoder*)ptr;
1301
0
   }
1302
0
   break;
1303
0
   case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST:
1304
0
   {
1305
0
       opus_int32 value = va_arg(ap, opus_int32);
1306
0
       st->variable_duration = value;
1307
0
   }
1308
0
   break;
1309
0
   case OPUS_GET_EXPERT_FRAME_DURATION_REQUEST:
1310
0
   {
1311
0
       opus_int32 *value = va_arg(ap, opus_int32*);
1312
0
       if (!value)
1313
0
       {
1314
0
          goto bad_arg;
1315
0
       }
1316
0
       *value = st->variable_duration;
1317
0
   }
1318
0
   break;
1319
0
   case OPUS_RESET_STATE:
1320
0
   {
1321
0
      int s;
1322
0
      if (st->mapping_type == MAPPING_TYPE_SURROUND)
1323
0
      {
1324
0
         OPUS_CLEAR(ms_get_preemph_mem(st), st->layout.nb_channels);
1325
0
         OPUS_CLEAR(ms_get_window_mem(st), st->layout.nb_channels*MAX_OVERLAP);
1326
0
      }
1327
0
      for (s=0;s<st->layout.nb_streams;s++)
1328
0
      {
1329
0
         OpusEncoder *enc;
1330
0
         enc = (OpusEncoder*)ptr;
1331
0
         if (s < st->layout.nb_coupled_streams)
1332
0
            ptr += align(coupled_size);
1333
0
         else
1334
0
            ptr += align(mono_size);
1335
0
         ret = opus_encoder_ctl(enc, OPUS_RESET_STATE);
1336
0
         if (ret != OPUS_OK)
1337
0
            break;
1338
0
      }
1339
0
   }
1340
0
   break;
1341
0
   default:
1342
0
      ret = OPUS_UNIMPLEMENTED;
1343
0
      break;
1344
834k
   }
1345
834k
   return ret;
1346
0
bad_arg:
1347
0
   return OPUS_BAD_ARG;
1348
834k
}
1349
1350
int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
1351
472k
{
1352
472k
   int ret;
1353
472k
   va_list ap;
1354
472k
   va_start(ap, request);
1355
472k
   ret = opus_multistream_encoder_ctl_va_list(st, request, ap);
1356
472k
   va_end(ap);
1357
472k
   return ret;
1358
472k
}
1359
1360
void opus_multistream_encoder_destroy(OpusMSEncoder *st)
1361
40.2k
{
1362
40.2k
    opus_free(st);
1363
40.2k
}