blob: a1cd0f5ce294efc491fc16447df980b8d5d78dfc [file] [log] [blame]
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001/* 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"
Jean-Marc Valin49587512013-07-07 02:50:18 -040039#include "mathops.h"
Jean-Marc Valinfdceae82013-08-30 21:58:02 -040040#include "mdct.h"
41#include "modes.h"
42#include "bands.h"
43#include "quant_bands.h"
Jean-Marc Valin7c49ad02015-10-07 09:17:50 -040044#include "pitch.h"
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -050045
Jean-Marc Valin7a8b1392013-04-29 18:32:27 -040046typedef struct {
47 int nb_streams;
48 int nb_coupled_streams;
49 unsigned char mapping[8];
50} VorbisLayout;
51
52/* Index is nb_channel-1*/
53static 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
Jean-Marc Valinfdceae82013-08-30 21:58:02 -040064typedef 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
Michael Graczyk39256682016-05-02 21:42:18 -070073typedef enum {
74 MAPPING_TYPE_NONE,
75 MAPPING_TYPE_SURROUND,
76#ifdef ENABLE_EXPERIMENTAL_AMBISONICS
77 MAPPING_TYPE_AMBISONICS,
78#endif
79} MappingType;
80
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -050081struct OpusMSEncoder {
82 ChannelLayout layout;
Viswanath Puttaguntaf48abe82015-05-15 12:42:19 -050083 int arch;
Jean-Marc Valin1b723862013-04-25 21:34:04 -040084 int lfe_stream;
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -040085 int application;
Jean-Marc Valin74483662012-12-17 16:23:42 -050086 int variable_duration;
Michael Graczyk39256682016-05-02 21:42:18 -070087 MappingType mapping_type;
Jean-Marc Valin74483662012-12-17 16:23:42 -050088 opus_int32 bitrate_bps;
Jean-Marc Valinab86a9c2013-11-13 23:06:25 -050089 float subframe_mem[3];
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -050090 /* Encoder states go here */
Jean-Marc Valinfdceae82013-08-30 21:58:02 -040091 /* then opus_val32 window_mem[channels*120]; */
92 /* then opus_val32 preemph_mem[channels]; */
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -050093};
94
Jean-Marc Valinfdceae82013-08-30 21:58:02 -040095static 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 }
Mark Harris4feb0df2015-08-07 01:24:48 -0700111 /* void* cast avoids clang -Wcast-align warning */
112 return (opus_val32*)(void*)(ptr+st->layout.nb_channels*120*sizeof(opus_val32));
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400113}
114
115static 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 }
Mark Harris4feb0df2015-08-07 01:24:48 -0700131 /* void* cast avoids clang -Wcast-align warning */
132 return (opus_val32*)(void*)ptr;
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400133}
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500134
135static int validate_encoder_layout(const ChannelLayout *layout)
136{
137 int s;
138 for (s=0;s<layout->nb_streams;s++)
139 {
140 if (s < layout->nb_coupled_streams)
141 {
142 if (get_left_channel(layout, s, -1)==-1)
143 return 0;
144 if (get_right_channel(layout, s, -1)==-1)
145 return 0;
146 } else {
147 if (get_mono_channel(layout, s, -1)==-1)
148 return 0;
149 }
150 }
151 return 1;
152}
153
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400154static void channel_pos(int channels, int pos[8])
155{
156 /* Position in the mix: 0 don't mix, 1: left, 2: center, 3:right */
157 if (channels==4)
158 {
159 pos[0]=1;
160 pos[1]=3;
161 pos[2]=1;
162 pos[3]=3;
163 } else if (channels==3||channels==5||channels==6)
164 {
165 pos[0]=1;
166 pos[1]=2;
167 pos[2]=3;
168 pos[3]=1;
169 pos[4]=3;
170 pos[5]=0;
171 } else if (channels==7)
172 {
173 pos[0]=1;
174 pos[1]=2;
175 pos[2]=3;
176 pos[3]=1;
177 pos[4]=3;
178 pos[5]=2;
179 pos[6]=0;
180 } else if (channels==8)
181 {
182 pos[0]=1;
183 pos[1]=2;
184 pos[2]=3;
185 pos[3]=1;
186 pos[4]=3;
187 pos[5]=1;
188 pos[6]=3;
189 pos[7]=0;
190 }
191}
192
Jean-Marc Valina714ae92013-08-31 02:05:32 -0400193#if 1
194/* Computes a rough approximation of log2(2^a + 2^b) */
195static opus_val16 logSum(opus_val16 a, opus_val16 b)
196{
197 opus_val16 max;
198 opus_val32 diff;
199 opus_val16 frac;
200 static const opus_val16 diff_table[17] = {
201 QCONST16(0.5000000f, DB_SHIFT), QCONST16(0.2924813f, DB_SHIFT), QCONST16(0.1609640f, DB_SHIFT), QCONST16(0.0849625f, DB_SHIFT),
202 QCONST16(0.0437314f, DB_SHIFT), QCONST16(0.0221971f, DB_SHIFT), QCONST16(0.0111839f, DB_SHIFT), QCONST16(0.0056136f, DB_SHIFT),
203 QCONST16(0.0028123f, DB_SHIFT)
204 };
205 int low;
206 if (a>b)
207 {
208 max = a;
209 diff = SUB32(EXTEND32(a),EXTEND32(b));
210 } else {
211 max = b;
212 diff = SUB32(EXTEND32(b),EXTEND32(a));
213 }
Mark Harrisa6595e62015-10-07 09:21:23 -0400214 if (!(diff < QCONST16(8.f, DB_SHIFT))) /* inverted to catch NaNs */
Jean-Marc Valina714ae92013-08-31 02:05:32 -0400215 return max;
216#ifdef FIXED_POINT
217 low = SHR32(diff, DB_SHIFT-1);
218 frac = SHL16(diff - SHL16(low, DB_SHIFT-1), 16-DB_SHIFT);
219#else
Jean-Marc Valina71c9ad2013-11-13 12:07:01 -0500220 low = (int)floor(2*diff);
Jean-Marc Valina714ae92013-08-31 02:05:32 -0400221 frac = 2*diff - low;
222#endif
223 return max + diff_table[low] + MULT16_16_Q15(frac, SUB16(diff_table[low+1], diff_table[low]));
224}
225#else
226opus_val16 logSum(opus_val16 a, opus_val16 b)
227{
228 return log2(pow(4, a)+ pow(4, b))/2;
229}
230#endif
231
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400232void surround_analysis(const CELTMode *celt_mode, const void *pcm, opus_val16 *bandLogE, opus_val32 *mem, opus_val32 *preemph_mem,
Viswanath Puttaguntaf48abe82015-05-15 12:42:19 -0500233 int len, int overlap, int channels, int rate, opus_copy_channel_in_func copy_channel_in, int arch
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400234)
235{
236 int c;
237 int i;
Jean-Marc Valin54bddf02013-09-11 23:34:51 -0400238 int LM;
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400239 int pos[8] = {0};
240 int upsample;
Jean-Marc Valin978e4cb2013-09-11 00:51:22 -0400241 int frame_size;
Jean-Marc Valin942fc812013-10-01 19:27:30 -0400242 opus_val16 channel_offset;
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400243 opus_val32 bandE[21];
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400244 opus_val16 maskLogE[3][21];
245 VARDECL(opus_val32, in);
246 VARDECL(opus_val16, x);
Jean-Marc Valine8e5ecb2013-10-01 17:16:33 -0400247 VARDECL(opus_val32, freq);
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400248 SAVE_STACK;
Jean-Marc Valin978e4cb2013-09-11 00:51:22 -0400249
250 upsample = resampling_factor(rate);
251 frame_size = len*upsample;
252
Michael Graczyk39256682016-05-02 21:42:18 -0700253 /* LM = log2(frame_size / 120) */
Jean-Marc Valin2e653a72013-10-14 17:47:18 -0400254 for (LM=0;LM<celt_mode->maxLM;LM++)
Jean-Marc Valin54bddf02013-09-11 23:34:51 -0400255 if (celt_mode->shortMdctSize<<LM==frame_size)
256 break;
257
Jean-Marc Valin978e4cb2013-09-11 00:51:22 -0400258 ALLOC(in, frame_size+overlap, opus_val32);
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400259 ALLOC(x, len, opus_val16);
Jean-Marc Valin978e4cb2013-09-11 00:51:22 -0400260 ALLOC(freq, frame_size, opus_val32);
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400261
262 channel_pos(channels, pos);
263
Jean-Marc Valina714ae92013-08-31 02:05:32 -0400264 for (c=0;c<3;c++)
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400265 for (i=0;i<21;i++)
Jean-Marc Valina714ae92013-08-31 02:05:32 -0400266 maskLogE[c][i] = -QCONST16(28.f, DB_SHIFT);
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400267
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400268 for (c=0;c<channels;c++)
269 {
270 OPUS_COPY(in, mem+c*overlap, overlap);
271 (*copy_channel_in)(x, 1, pcm, channels, c, len);
Jean-Marc Valin2dc27df2013-11-13 19:35:43 -0500272 celt_preemphasis(x, in+overlap, frame_size, 1, upsample, celt_mode->preemph, preemph_mem+c, 0);
Jean-Marc Valin7c49ad02015-10-07 09:17:50 -0400273#ifndef FIXED_POINT
274 {
275 opus_val32 sum;
276 sum = celt_inner_prod(in, in, frame_size+overlap, 0);
277 /* This should filter out both NaNs and ridiculous signals that could
278 cause NaNs further down. */
279 if (!(sum < 1e9f) || celt_isnan(sum))
280 {
281 OPUS_CLEAR(in, frame_size+overlap);
282 preemph_mem[c] = 0;
283 }
284 }
285#endif
Viswanath Puttaguntaf48abe82015-05-15 12:42:19 -0500286 clt_mdct_forward(&celt_mode->mdct, in, freq, celt_mode->window,
287 overlap, celt_mode->maxLM-LM, 1, arch);
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400288 if (upsample != 1)
289 {
Jean-Marc Valin978e4cb2013-09-11 00:51:22 -0400290 int bound = len;
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400291 for (i=0;i<bound;i++)
292 freq[i] *= upsample;
Jean-Marc Valin978e4cb2013-09-11 00:51:22 -0400293 for (;i<frame_size;i++)
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400294 freq[i] = 0;
295 }
296
Mark Harris58107d82014-01-25 16:32:18 -0800297 compute_band_energies(celt_mode, freq, bandE, 21, 1, LM);
Jean-Marc Valina714ae92013-08-31 02:05:32 -0400298 amp2Log2(celt_mode, 21, 21, bandE, bandLogE+21*c, 1);
Jean-Marc Valin0f686962013-09-05 12:49:55 -0400299 /* Apply spreading function with -6 dB/band going up and -12 dB/band going down. */
300 for (i=1;i<21;i++)
301 bandLogE[21*c+i] = MAX16(bandLogE[21*c+i], bandLogE[21*c+i-1]-QCONST16(1.f, DB_SHIFT));
302 for (i=19;i>=0;i--)
303 bandLogE[21*c+i] = MAX16(bandLogE[21*c+i], bandLogE[21*c+i+1]-QCONST16(2.f, DB_SHIFT));
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400304 if (pos[c]==1)
305 {
306 for (i=0;i<21;i++)
Jean-Marc Valina714ae92013-08-31 02:05:32 -0400307 maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]);
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400308 } else if (pos[c]==3)
309 {
310 for (i=0;i<21;i++)
Jean-Marc Valina714ae92013-08-31 02:05:32 -0400311 maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]);
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400312 } else if (pos[c]==2)
313 {
314 for (i=0;i<21;i++)
315 {
Jean-Marc Valina714ae92013-08-31 02:05:32 -0400316 maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]-QCONST16(.5f, DB_SHIFT));
317 maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]-QCONST16(.5f, DB_SHIFT));
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400318 }
319 }
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400320#if 0
321 for (i=0;i<21;i++)
322 printf("%f ", bandLogE[21*c+i]);
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400323 float sum=0;
324 for (i=0;i<21;i++)
325 sum += bandLogE[21*c+i];
326 printf("%f ", sum/21);
327#endif
Jean-Marc Valin978e4cb2013-09-11 00:51:22 -0400328 OPUS_COPY(mem+c*overlap, in+frame_size, overlap);
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400329 }
330 for (i=0;i<21;i++)
Jean-Marc Valina714ae92013-08-31 02:05:32 -0400331 maskLogE[1][i] = MIN32(maskLogE[0][i],maskLogE[2][i]);
Jean-Marc Valin942fc812013-10-01 19:27:30 -0400332 channel_offset = HALF16(celt_log2(QCONST32(2.f,14)/(channels-1)));
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400333 for (c=0;c<3;c++)
334 for (i=0;i<21;i++)
Jean-Marc Valin942fc812013-10-01 19:27:30 -0400335 maskLogE[c][i] += channel_offset;
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400336#if 0
337 for (c=0;c<3;c++)
338 {
339 for (i=0;i<21;i++)
340 printf("%f ", maskLogE[c][i]);
341 }
342#endif
343 for (c=0;c<channels;c++)
344 {
345 opus_val16 *mask;
346 if (pos[c]!=0)
347 {
348 mask = &maskLogE[pos[c]-1][0];
349 for (i=0;i<21;i++)
350 bandLogE[21*c+i] = bandLogE[21*c+i] - mask[i];
351 } else {
352 for (i=0;i<21;i++)
353 bandLogE[21*c+i] = 0;
354 }
355#if 0
356 for (i=0;i<21;i++)
357 printf("%f ", bandLogE[21*c+i]);
358 printf("\n");
359#endif
360#if 0
361 float sum=0;
362 for (i=0;i<21;i++)
363 sum += bandLogE[21*c+i];
Jean-Marc Valin942fc812013-10-01 19:27:30 -0400364 printf("%f ", sum/(float)QCONST32(21.f, DB_SHIFT));
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400365 printf("\n");
366#endif
367 }
368 RESTORE_STACK;
369}
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500370
371opus_int32 opus_multistream_encoder_get_size(int nb_streams, int nb_coupled_streams)
372{
373 int coupled_size;
374 int mono_size;
375
376 if(nb_streams<1||nb_coupled_streams>nb_streams||nb_coupled_streams<0)return 0;
377 coupled_size = opus_encoder_get_size(2);
378 mono_size = opus_encoder_get_size(1);
379 return align(sizeof(OpusMSEncoder))
380 + nb_coupled_streams * align(coupled_size)
381 + (nb_streams-nb_coupled_streams) * align(mono_size);
382}
383
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400384opus_int32 opus_multistream_surround_encoder_get_size(int channels, int mapping_family)
385{
386 int nb_streams;
387 int nb_coupled_streams;
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400388 opus_int32 size;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400389
Jean-Marc Valin7a8b1392013-04-29 18:32:27 -0400390 if (mapping_family==0)
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400391 {
Jean-Marc Valin7a8b1392013-04-29 18:32:27 -0400392 if (channels==1)
393 {
394 nb_streams=1;
395 nb_coupled_streams=0;
396 } else if (channels==2)
397 {
398 nb_streams=1;
399 nb_coupled_streams=1;
400 } else
401 return 0;
402 } else if (mapping_family==1 && channels<=8 && channels>=1)
403 {
404 nb_streams=vorbis_mappings[channels-1].nb_streams;
405 nb_coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams;
406 } else if (mapping_family==255)
407 {
408 nb_streams=channels;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400409 nb_coupled_streams=0;
Michael Graczyk39256682016-05-02 21:42:18 -0700410#ifdef ENABLE_EXPERIMENTAL_AMBISONICS
411 } else if (mapping_family==254)
412 {
413 nb_streams=channels;
414 nb_coupled_streams=0;
415#endif
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400416 } else
417 return 0;
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400418 size = opus_multistream_encoder_get_size(nb_streams, nb_coupled_streams);
419 if (channels>2)
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400420 {
421 size += channels*(120*sizeof(opus_val32) + sizeof(opus_val32));
422 }
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400423 return size;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400424}
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500425
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400426static int opus_multistream_encoder_init_impl(
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500427 OpusMSEncoder *st,
428 opus_int32 Fs,
429 int channels,
430 int streams,
431 int coupled_streams,
432 const unsigned char *mapping,
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400433 int application,
Michael Graczyk39256682016-05-02 21:42:18 -0700434 MappingType mapping_type
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500435)
436{
437 int coupled_size;
438 int mono_size;
439 int i, ret;
440 char *ptr;
441
442 if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
Mark Harris25b27a92014-11-27 08:48:09 -0800443 (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams))
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500444 return OPUS_BAD_ARG;
445
Viswanath Puttaguntaf48abe82015-05-15 12:42:19 -0500446 st->arch = opus_select_arch();
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500447 st->layout.nb_channels = channels;
448 st->layout.nb_streams = streams;
449 st->layout.nb_coupled_streams = coupled_streams;
Jean-Marc Valinb0429352013-05-05 02:22:06 -0400450 st->subframe_mem[0]=st->subframe_mem[1]=st->subframe_mem[2]=0;
Michael Graczyk39256682016-05-02 21:42:18 -0700451 if (mapping_type != MAPPING_TYPE_SURROUND)
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400452 st->lfe_stream = -1;
Jean-Marc Valin95561be2012-12-17 17:54:01 -0500453 st->bitrate_bps = OPUS_AUTO;
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -0400454 st->application = application;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500455 st->variable_duration = OPUS_FRAMESIZE_ARG;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500456 for (i=0;i<st->layout.nb_channels;i++)
457 st->layout.mapping[i] = mapping[i];
458 if (!validate_layout(&st->layout) || !validate_encoder_layout(&st->layout))
459 return OPUS_BAD_ARG;
460 ptr = (char*)st + align(sizeof(OpusMSEncoder));
461 coupled_size = opus_encoder_get_size(2);
462 mono_size = opus_encoder_get_size(1);
463
464 for (i=0;i<st->layout.nb_coupled_streams;i++)
465 {
466 ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 2, application);
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400467 if(ret!=OPUS_OK)return ret;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400468 if (i==st->lfe_stream)
469 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1));
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500470 ptr += align(coupled_size);
471 }
472 for (;i<st->layout.nb_streams;i++)
473 {
474 ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 1, application);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400475 if (i==st->lfe_stream)
476 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1));
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500477 if(ret!=OPUS_OK)return ret;
478 ptr += align(mono_size);
479 }
Michael Graczyk39256682016-05-02 21:42:18 -0700480 if (mapping_type == MAPPING_TYPE_SURROUND)
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400481 {
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400482 OPUS_CLEAR(ms_get_preemph_mem(st), channels);
483 OPUS_CLEAR(ms_get_window_mem(st), channels*120);
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400484 }
Michael Graczyk39256682016-05-02 21:42:18 -0700485 st->mapping_type = mapping_type;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500486 return OPUS_OK;
487}
488
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400489int opus_multistream_encoder_init(
490 OpusMSEncoder *st,
491 opus_int32 Fs,
492 int channels,
493 int streams,
494 int coupled_streams,
495 const unsigned char *mapping,
496 int application
497)
498{
Michael Graczyk39256682016-05-02 21:42:18 -0700499 return opus_multistream_encoder_init_impl(st, Fs, channels, streams,
500 coupled_streams, mapping,
501 application, MAPPING_TYPE_NONE);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400502}
503
504int opus_multistream_surround_encoder_init(
505 OpusMSEncoder *st,
506 opus_int32 Fs,
507 int channels,
508 int mapping_family,
509 int *streams,
510 int *coupled_streams,
511 unsigned char *mapping,
512 int application
513)
514{
Michael Graczyk1ac3a562016-04-04 19:31:04 -0700515 MappingType mapping_type;
516
Jean-Marc Valin337f34c2013-07-01 16:17:01 -0400517 if ((channels>255) || (channels<1))
518 return OPUS_BAD_ARG;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400519 st->lfe_stream = -1;
Jean-Marc Valin7a8b1392013-04-29 18:32:27 -0400520 if (mapping_family==0)
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400521 {
Jean-Marc Valin7a8b1392013-04-29 18:32:27 -0400522 if (channels==1)
523 {
524 *streams=1;
525 *coupled_streams=0;
526 mapping[0]=0;
527 } else if (channels==2)
528 {
529 *streams=1;
530 *coupled_streams=1;
531 mapping[0]=0;
532 mapping[1]=1;
533 } else
534 return OPUS_UNIMPLEMENTED;
535 } else if (mapping_family==1 && channels<=8 && channels>=1)
536 {
537 int i;
538 *streams=vorbis_mappings[channels-1].nb_streams;
539 *coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams;
540 for (i=0;i<channels;i++)
541 mapping[i] = vorbis_mappings[channels-1].mapping[i];
542 if (channels>=6)
543 st->lfe_stream = *streams-1;
544 } else if (mapping_family==255)
545 {
546 int i;
547 *streams=channels;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400548 *coupled_streams=0;
Jean-Marc Valin7a8b1392013-04-29 18:32:27 -0400549 for(i=0;i<channels;i++)
550 mapping[i] = i;
Michael Graczyk39256682016-05-02 21:42:18 -0700551#ifdef ENABLE_EXPERIMENTAL_AMBISONICS
552 } else if (mapping_family==254)
553 {
554 int i;
555 *streams=channels;
556 *coupled_streams=0;
557 for(i=0;i<channels;i++)
558 mapping[i] = i;
559#endif
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400560 } else
Jean-Marc Valin7a8b1392013-04-29 18:32:27 -0400561 return OPUS_UNIMPLEMENTED;
Michael Graczyk39256682016-05-02 21:42:18 -0700562
563 if (channels>2 && mapping_family==1) {
564 mapping_type = MAPPING_TYPE_SURROUND;
565#ifdef ENABLE_EXPERIMENTAL_AMBISONICS
566 } else if (mapping_family==254)
567 {
568 mapping_type = MAPPING_TYPE_AMBISONICS;
569#endif
570 } else
571 {
572 mapping_type = MAPPING_TYPE_NONE;
573 }
574 return opus_multistream_encoder_init_impl(st, Fs, channels, *streams,
575 *coupled_streams, mapping,
576 application, mapping_type);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400577}
578
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500579OpusMSEncoder *opus_multistream_encoder_create(
580 opus_int32 Fs,
581 int channels,
582 int streams,
583 int coupled_streams,
584 const unsigned char *mapping,
585 int application,
586 int *error
587)
588{
589 int ret;
590 OpusMSEncoder *st;
591 if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
Mark Harris25b27a92014-11-27 08:48:09 -0800592 (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams))
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500593 {
594 if (error)
595 *error = OPUS_BAD_ARG;
596 return NULL;
597 }
598 st = (OpusMSEncoder *)opus_alloc(opus_multistream_encoder_get_size(streams, coupled_streams));
599 if (st==NULL)
600 {
601 if (error)
602 *error = OPUS_ALLOC_FAIL;
603 return NULL;
604 }
605 ret = opus_multistream_encoder_init(st, Fs, channels, streams, coupled_streams, mapping, application);
606 if (ret != OPUS_OK)
607 {
608 opus_free(st);
609 st = NULL;
610 }
611 if (error)
612 *error = ret;
613 return st;
614}
615
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400616OpusMSEncoder *opus_multistream_surround_encoder_create(
617 opus_int32 Fs,
618 int channels,
619 int mapping_family,
620 int *streams,
621 int *coupled_streams,
622 unsigned char *mapping,
623 int application,
624 int *error
625)
626{
627 int ret;
Mark Harris25b27a92014-11-27 08:48:09 -0800628 opus_int32 size;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400629 OpusMSEncoder *st;
630 if ((channels>255) || (channels<1))
631 {
632 if (error)
633 *error = OPUS_BAD_ARG;
634 return NULL;
635 }
Mark Harris25b27a92014-11-27 08:48:09 -0800636 size = opus_multistream_surround_encoder_get_size(channels, mapping_family);
637 if (!size)
638 {
639 if (error)
640 *error = OPUS_UNIMPLEMENTED;
641 return NULL;
642 }
643 st = (OpusMSEncoder *)opus_alloc(size);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400644 if (st==NULL)
645 {
646 if (error)
647 *error = OPUS_ALLOC_FAIL;
648 return NULL;
649 }
650 ret = opus_multistream_surround_encoder_init(st, Fs, channels, mapping_family, 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
Michael Graczyk1ac3a562016-04-04 19:31:04 -0700661static void surround_rate_allocation(
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400662 OpusMSEncoder *st,
663 opus_int32 *rate,
Michael Graczyk1ac3a562016-04-04 19:31:04 -0700664 int frame_size,
665 opus_int32 Fs
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400666 )
667{
668 int i;
669 opus_int32 channel_rate;
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400670 int stream_offset;
671 int lfe_offset;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400672 int coupled_ratio; /* Q8 */
673 int lfe_ratio; /* Q8 */
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400674
Jean-Marc Valin49587512013-07-07 02:50:18 -0400675 if (st->bitrate_bps > st->layout.nb_channels*40000)
676 stream_offset = 20000;
677 else
678 stream_offset = st->bitrate_bps/st->layout.nb_channels/2;
Jean-Marc Valin87ca6c02013-11-13 22:58:10 -0500679 stream_offset += 60*(Fs/frame_size-50);
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400680 /* We start by giving each stream (coupled or uncoupled) the same bitrate.
681 This models the main saving of coupled channels over uncoupled. */
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400682 /* The LFE stream is an exception to the above and gets fewer bits. */
Jean-Marc Valin87ca6c02013-11-13 22:58:10 -0500683 lfe_offset = 3500 + 60*(Fs/frame_size-50);
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400684 /* Coupled streams get twice the mono rate after the first 20 kb/s. */
685 coupled_ratio = 512;
686 /* Should depend on the bitrate, for now we assume LFE gets 1/8 the bits of mono */
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400687 lfe_ratio = 32;
688
689 /* Compute bitrate allocation between streams */
690 if (st->bitrate_bps==OPUS_AUTO)
691 {
692 channel_rate = Fs+60*Fs/frame_size;
693 } else if (st->bitrate_bps==OPUS_BITRATE_MAX)
694 {
695 channel_rate = 300000;
696 } else {
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400697 int nb_lfe;
698 int nb_uncoupled;
699 int nb_coupled;
700 int total;
701 nb_lfe = (st->lfe_stream!=-1);
702 nb_coupled = st->layout.nb_coupled_streams;
703 nb_uncoupled = st->layout.nb_streams-nb_coupled-nb_lfe;
704 total = (nb_uncoupled<<8) /* mono */
705 + coupled_ratio*nb_coupled /* stereo */
706 + nb_lfe*lfe_ratio;
707 channel_rate = 256*(st->bitrate_bps-lfe_offset*nb_lfe-stream_offset*(nb_coupled+nb_uncoupled))/total;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400708 }
709#ifndef FIXED_POINT
710 if (st->variable_duration==OPUS_FRAMESIZE_VARIABLE && frame_size != Fs/50)
711 {
712 opus_int32 bonus;
713 bonus = 60*(Fs/frame_size-50);
714 channel_rate += bonus;
715 }
716#endif
717
718 for (i=0;i<st->layout.nb_streams;i++)
719 {
720 if (i<st->layout.nb_coupled_streams)
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400721 rate[i] = stream_offset+(channel_rate*coupled_ratio>>8);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400722 else if (i!=st->lfe_stream)
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400723 rate[i] = stream_offset+channel_rate;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400724 else
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400725 rate[i] = lfe_offset+(channel_rate*lfe_ratio>>8);
Michael Graczyk1ac3a562016-04-04 19:31:04 -0700726 }
727}
728
729#ifdef ENABLE_EXPERIMENTAL_AMBISONICS
730static void ambisonics_rate_allocation(
731 OpusMSEncoder *st,
732 opus_int32 *rate,
733 int frame_size,
734 opus_int32 Fs
735 )
736{
737 int i;
738 int non_mono_rate;
739 int total_rate;
740
741 /* The mono channel gets (rate_ratio_num / rate_ratio_den) times as many bits
742 * as all other channels */
743 const int rate_ratio_num = 4;
744 const int rate_ratio_den = 3;
745 const int num_channels = st->layout.nb_streams;
746
747 if (st->bitrate_bps==OPUS_AUTO)
748 {
749 total_rate = num_channels * (20000 + st->layout.nb_streams*(Fs+60*Fs/frame_size));
750 } else if (st->bitrate_bps==OPUS_BITRATE_MAX)
751 {
752 total_rate = num_channels * 320000;
753 } else {
754 total_rate = st->bitrate_bps;
755 }
756
757 /* Let y be the non-mono rate and let p, q be integers such that the mono
758 * channel rate is (p/q) * y.
759 * Also let T be the total bitrate to allocate. Then
760 * (n - 1) y + (p/q) y = T
761 * y = (T q) / (qn - q + p)
762 */
763 non_mono_rate =
764 total_rate * rate_ratio_den
765 / (rate_ratio_den*num_channels + rate_ratio_num - rate_ratio_den);
766
767#ifndef FIXED_POINT
768 if (st->variable_duration==OPUS_FRAMESIZE_VARIABLE && frame_size != Fs/50)
769 {
770 opus_int32 bonus = 60*(Fs/frame_size-50);
771 non_mono_rate += bonus;
772 }
773#endif
774
775 rate[0] = total_rate - (num_channels - 1) * non_mono_rate;
776 for (i=1;i<st->layout.nb_streams;i++)
777 {
778 rate[i] = non_mono_rate;
779 }
780}
781#endif /* ENABLE_EXPERIMENTAL_AMBISONICS */
782
783static opus_int32 rate_allocation(
784 OpusMSEncoder *st,
785 opus_int32 *rate,
786 int frame_size
787 )
788{
789 int i;
790 opus_int32 rate_sum=0;
791 opus_int32 Fs;
792 char *ptr;
793
794 ptr = (char*)st + align(sizeof(OpusMSEncoder));
795 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
796
797#ifdef ENABLE_EXPERIMENTAL_AMBISONICS
798 if (st->mapping_type == MAPPING_TYPE_AMBISONICS) {
799 ambisonics_rate_allocation(st, rate, frame_size, Fs);
800 } else
801#endif
802 {
803 surround_rate_allocation(st, rate, frame_size, Fs);
804 }
805
806 for (i=0;i<st->layout.nb_streams;i++)
807 {
Jean-Marc Valin8dc91de2014-06-21 01:16:46 -0400808 rate[i] = IMAX(rate[i], 500);
809 rate_sum += rate[i];
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400810 }
Jean-Marc Valin8dc91de2014-06-21 01:16:46 -0400811 return rate_sum;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400812}
813
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500814/* Max size in case the encoder decides to return three frames */
815#define MS_FRAME_TMP (3*1275+7)
816static int opus_multistream_encode_native
817(
818 OpusMSEncoder *st,
819 opus_copy_channel_in_func copy_channel_in,
820 const void *pcm,
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -0400821 int analysis_frame_size,
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500822 unsigned char *data,
Jean-Marc Valinb3eba242012-12-20 23:11:53 -0500823 opus_int32 max_data_bytes,
Jean-Marc Valin91904a42013-09-05 21:34:43 -0400824 int lsb_depth,
Jean-Marc Valinc94e4bb2013-12-08 03:31:50 -0500825 downmix_func downmix,
826 int float_api
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500827)
828{
829 opus_int32 Fs;
830 int coupled_size;
831 int mono_size;
832 int s;
833 char *ptr;
834 int tot_size;
835 VARDECL(opus_val16, buf);
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400836 VARDECL(opus_val16, bandSMR);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500837 unsigned char tmp_data[MS_FRAME_TMP];
838 OpusRepacketizer rp;
Jean-Marc Valineab134c2013-10-14 15:01:36 -0400839 opus_int32 vbr;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500840 const CELTMode *celt_mode;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400841 opus_int32 bitrates[256];
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400842 opus_val16 bandLogE[42];
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400843 opus_val32 *mem = NULL;
844 opus_val32 *preemph_mem=NULL;
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -0400845 int frame_size;
Jean-Marc Valin8dc91de2014-06-21 01:16:46 -0400846 opus_int32 rate_sum;
847 opus_int32 smallest_packet;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500848 ALLOC_STACK;
849
Michael Graczyk39256682016-05-02 21:42:18 -0700850 if (st->mapping_type == MAPPING_TYPE_SURROUND)
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400851 {
852 preemph_mem = ms_get_preemph_mem(st);
853 mem = ms_get_window_mem(st);
854 }
855
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500856 ptr = (char*)st + align(sizeof(OpusMSEncoder));
857 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
Jean-Marc Valineab134c2013-10-14 15:01:36 -0400858 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_VBR(&vbr));
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500859 opus_encoder_ctl((OpusEncoder*)ptr, CELT_GET_MODE(&celt_mode));
Jean-Marc Valin74483662012-12-17 16:23:42 -0500860
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -0400861 {
862 opus_int32 delay_compensation;
863 int channels;
864
865 channels = st->layout.nb_streams + st->layout.nb_coupled_streams;
866 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_LOOKAHEAD(&delay_compensation));
867 delay_compensation -= Fs/400;
868 frame_size = compute_frame_size(pcm, analysis_frame_size,
869 st->variable_duration, channels, Fs, st->bitrate_bps,
Jean-Marc Valinc2b34412013-10-28 21:48:50 -0400870 delay_compensation, downmix
871#ifndef DISABLE_FLOAT_API
872 , st->subframe_mem
873#endif
874 );
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -0400875 }
876
Jean-Marc Valin74483662012-12-17 16:23:42 -0500877 if (400*frame_size < Fs)
878 {
879 RESTORE_STACK;
880 return OPUS_BAD_ARG;
881 }
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500882 /* Validate frame_size before using it to allocate stack space.
883 This mirrors the checks in opus_encode[_float](). */
884 if (400*frame_size != Fs && 200*frame_size != Fs &&
885 100*frame_size != Fs && 50*frame_size != Fs &&
886 25*frame_size != Fs && 50*frame_size != 3*Fs)
887 {
888 RESTORE_STACK;
889 return OPUS_BAD_ARG;
890 }
Jean-Marc Valine1326fe2014-09-04 01:48:46 -0400891
892 /* Smallest packet the encoder can produce. */
893 smallest_packet = st->layout.nb_streams*2-1;
Jean-Marc Valin8dc91de2014-06-21 01:16:46 -0400894 if (max_data_bytes < smallest_packet)
895 {
896 RESTORE_STACK;
Jean-Marc Valine1326fe2014-09-04 01:48:46 -0400897 return OPUS_BUFFER_TOO_SMALL;
Jean-Marc Valin8dc91de2014-06-21 01:16:46 -0400898 }
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500899 ALLOC(buf, 2*frame_size, opus_val16);
900 coupled_size = opus_encoder_get_size(2);
901 mono_size = opus_encoder_get_size(1);
902
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400903 ALLOC(bandSMR, 21*st->layout.nb_channels, opus_val16);
Michael Graczyk39256682016-05-02 21:42:18 -0700904 if (st->mapping_type == MAPPING_TYPE_SURROUND)
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400905 {
Viswanath Puttaguntaf48abe82015-05-15 12:42:19 -0500906 surround_analysis(celt_mode, pcm, bandSMR, mem, preemph_mem, frame_size, 120, st->layout.nb_channels, Fs, copy_channel_in, st->arch);
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400907 }
908
Jean-Marc Valin74483662012-12-17 16:23:42 -0500909 /* Compute bitrate allocation between streams (this could be a lot better) */
Michael Graczyk1ac3a562016-04-04 19:31:04 -0700910 rate_sum = rate_allocation(st, bitrates, frame_size);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400911
Jean-Marc Valineab134c2013-10-14 15:01:36 -0400912 if (!vbr)
Jean-Marc Valin8dc91de2014-06-21 01:16:46 -0400913 {
914 if (st->bitrate_bps == OPUS_AUTO)
915 {
916 max_data_bytes = IMIN(max_data_bytes, 3*rate_sum/(3*8*Fs/frame_size));
917 } else if (st->bitrate_bps != OPUS_BITRATE_MAX)
918 {
919 max_data_bytes = IMIN(max_data_bytes, IMAX(smallest_packet,
920 3*st->bitrate_bps/(3*8*Fs/frame_size)));
921 }
922 }
Jean-Marc Valin74483662012-12-17 16:23:42 -0500923 ptr = (char*)st + align(sizeof(OpusMSEncoder));
924 for (s=0;s<st->layout.nb_streams;s++)
925 {
926 OpusEncoder *enc;
927 enc = (OpusEncoder*)ptr;
928 if (s < st->layout.nb_coupled_streams)
929 ptr += align(coupled_size);
930 else
931 ptr += align(mono_size);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400932 opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrates[s]));
Michael Graczyk39256682016-05-02 21:42:18 -0700933 if (st->mapping_type == MAPPING_TYPE_SURROUND)
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400934 {
Jean-Marc Valin6fbfed62013-09-13 17:16:38 -0400935 opus_int32 equiv_rate;
936 equiv_rate = st->bitrate_bps;
937 if (frame_size*50 < Fs)
938 equiv_rate -= 60*(Fs/frame_size - 50)*st->layout.nb_channels;
Jean-Marc Valinccf7d9b2013-11-24 01:57:52 -0500939 if (equiv_rate > 10000*st->layout.nb_channels)
Jean-Marc Valin6fbfed62013-09-13 17:16:38 -0400940 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
Jean-Marc Valinccf7d9b2013-11-24 01:57:52 -0500941 else if (equiv_rate > 7000*st->layout.nb_channels)
Jean-Marc Valin6fbfed62013-09-13 17:16:38 -0400942 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_SUPERWIDEBAND));
Jean-Marc Valinccf7d9b2013-11-24 01:57:52 -0500943 else if (equiv_rate > 5000*st->layout.nb_channels)
Jean-Marc Valin6fbfed62013-09-13 17:16:38 -0400944 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_WIDEBAND));
945 else
946 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND));
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400947 if (s < st->layout.nb_coupled_streams)
Jean-Marc Valin8824fdb2013-09-10 01:15:19 -0400948 {
949 /* To preserve the spatial image, force stereo CELT on coupled streams */
950 opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY));
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400951 opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(2));
Jean-Marc Valin8824fdb2013-09-10 01:15:19 -0400952 }
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400953 }
Michael Graczyk1ac3a562016-04-04 19:31:04 -0700954#ifdef ENABLE_EXPERIMENTAL_AMBISONICS
955 else if (st->mapping_type == MAPPING_TYPE_AMBISONICS) {
956 opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY));
957 }
958#endif
Jean-Marc Valin74483662012-12-17 16:23:42 -0500959 }
960
961 ptr = (char*)st + align(sizeof(OpusMSEncoder));
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500962 /* Counting ToC */
963 tot_size = 0;
964 for (s=0;s<st->layout.nb_streams;s++)
965 {
966 OpusEncoder *enc;
967 int len;
968 int curr_max;
Jean-Marc Valin91904a42013-09-05 21:34:43 -0400969 int c1, c2;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500970
971 opus_repacketizer_init(&rp);
972 enc = (OpusEncoder*)ptr;
973 if (s < st->layout.nb_coupled_streams)
974 {
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400975 int i;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500976 int left, right;
977 left = get_left_channel(&st->layout, s, -1);
978 right = get_right_channel(&st->layout, s, -1);
979 (*copy_channel_in)(buf, 2,
980 pcm, st->layout.nb_channels, left, frame_size);
981 (*copy_channel_in)(buf+1, 2,
982 pcm, st->layout.nb_channels, right, frame_size);
983 ptr += align(coupled_size);
Michael Graczyk39256682016-05-02 21:42:18 -0700984 if (st->mapping_type == MAPPING_TYPE_SURROUND)
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400985 {
986 for (i=0;i<21;i++)
987 {
988 bandLogE[i] = bandSMR[21*left+i];
989 bandLogE[21+i] = bandSMR[21*right+i];
990 }
991 }
Jean-Marc Valin91904a42013-09-05 21:34:43 -0400992 c1 = left;
993 c2 = right;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500994 } else {
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400995 int i;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500996 int chan = get_mono_channel(&st->layout, s, -1);
997 (*copy_channel_in)(buf, 1,
998 pcm, st->layout.nb_channels, chan, frame_size);
999 ptr += align(mono_size);
Michael Graczyk39256682016-05-02 21:42:18 -07001000 if (st->mapping_type == MAPPING_TYPE_SURROUND)
Jean-Marc Valinfdceae82013-08-30 21:58:02 -04001001 {
1002 for (i=0;i<21;i++)
1003 bandLogE[i] = bandSMR[21*chan+i];
1004 }
Jean-Marc Valin91904a42013-09-05 21:34:43 -04001005 c1 = chan;
1006 c2 = -1;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001007 }
Michael Graczyk39256682016-05-02 21:42:18 -07001008 if (st->mapping_type == MAPPING_TYPE_SURROUND)
Jean-Marc Valinfdceae82013-08-30 21:58:02 -04001009 opus_encoder_ctl(enc, OPUS_SET_ENERGY_MASK(bandLogE));
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001010 /* number of bytes left (+Toc) */
1011 curr_max = max_data_bytes - tot_size;
Jean-Marc Valinda97db12014-09-04 02:48:21 -04001012 /* Reserve one byte for the last stream and two for the others */
Jean-Marc Valine1326fe2014-09-04 01:48:46 -04001013 curr_max -= IMAX(0,2*(st->layout.nb_streams-s-1)-1);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001014 curr_max = IMIN(curr_max,MS_FRAME_TMP);
Jean-Marc Valinda97db12014-09-04 02:48:21 -04001015 /* Repacketizer will add one or two bytes for self-delimited frames */
Jean-Marc Valin648eb9a2014-09-04 02:44:09 -04001016 if (s != st->layout.nb_streams-1) curr_max -= curr_max>253 ? 2 : 1;
Jean-Marc Valin2e653a72013-10-14 17:47:18 -04001017 if (!vbr && s == st->layout.nb_streams-1)
1018 opus_encoder_ctl(enc, OPUS_SET_BITRATE(curr_max*(8*Fs/frame_size)));
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -04001019 len = opus_encode_native(enc, buf, frame_size, tmp_data, curr_max, lsb_depth,
Jean-Marc Valinc94e4bb2013-12-08 03:31:50 -05001020 pcm, analysis_frame_size, c1, c2, st->layout.nb_channels, downmix, float_api);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001021 if (len<0)
1022 {
1023 RESTORE_STACK;
1024 return len;
1025 }
1026 /* We need to use the repacketizer to add the self-delimiting lengths
1027 while taking into account the fact that the encoder can now return
1028 more than one frame at a time (e.g. 60 ms CELT-only) */
1029 opus_repacketizer_cat(&rp, tmp_data, len);
Jean-Marc Valinc5635d22013-11-13 14:08:22 -05001030 len = opus_repacketizer_out_range_impl(&rp, 0, opus_repacketizer_get_nb_frames(&rp),
1031 data, max_data_bytes-tot_size, s != st->layout.nb_streams-1, !vbr && s == st->layout.nb_streams-1);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001032 data += len;
1033 tot_size += len;
1034 }
Jean-Marc Valinfdceae82013-08-30 21:58:02 -04001035 /*printf("\n");*/
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001036 RESTORE_STACK;
1037 return tot_size;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001038}
1039
Pedro Becerra1af7f952013-07-11 00:00:47 -04001040#if !defined(DISABLE_FLOAT_API)
1041static void opus_copy_channel_in_float(
1042 opus_val16 *dst,
1043 int dst_stride,
1044 const void *src,
1045 int src_stride,
1046 int src_channel,
1047 int frame_size
1048)
1049{
1050 const float *float_src;
1051 opus_int32 i;
1052 float_src = (const float *)src;
1053 for (i=0;i<frame_size;i++)
1054#if defined(FIXED_POINT)
1055 dst[i*dst_stride] = FLOAT2INT16(float_src[i*src_stride+src_channel]);
1056#else
1057 dst[i*dst_stride] = float_src[i*src_stride+src_channel];
1058#endif
1059}
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001060#endif
1061
1062static void opus_copy_channel_in_short(
1063 opus_val16 *dst,
1064 int dst_stride,
1065 const void *src,
1066 int src_stride,
1067 int src_channel,
1068 int frame_size
1069)
1070{
1071 const opus_int16 *short_src;
Timothy B. Terriberrya8f04b22013-03-18 14:42:44 -07001072 opus_int32 i;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001073 short_src = (const opus_int16 *)src;
1074 for (i=0;i<frame_size;i++)
1075#if defined(FIXED_POINT)
1076 dst[i*dst_stride] = short_src[i*src_stride+src_channel];
1077#else
1078 dst[i*dst_stride] = (1/32768.f)*short_src[i*src_stride+src_channel];
1079#endif
1080}
1081
Jean-Marc Valina4dccd32013-05-04 23:54:20 -04001082
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001083#ifdef FIXED_POINT
1084int opus_multistream_encode(
1085 OpusMSEncoder *st,
1086 const opus_val16 *pcm,
1087 int frame_size,
1088 unsigned char *data,
1089 opus_int32 max_data_bytes
1090)
1091{
1092 return opus_multistream_encode_native(st, opus_copy_channel_in_short,
Jean-Marc Valinc94e4bb2013-12-08 03:31:50 -05001093 pcm, frame_size, data, max_data_bytes, 16, downmix_int, 0);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001094}
1095
1096#ifndef DISABLE_FLOAT_API
1097int opus_multistream_encode_float(
1098 OpusMSEncoder *st,
1099 const float *pcm,
1100 int frame_size,
1101 unsigned char *data,
1102 opus_int32 max_data_bytes
1103)
1104{
1105 return opus_multistream_encode_native(st, opus_copy_channel_in_float,
Jean-Marc Valinc94e4bb2013-12-08 03:31:50 -05001106 pcm, frame_size, data, max_data_bytes, 16, downmix_float, 1);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001107}
1108#endif
1109
1110#else
1111
1112int opus_multistream_encode_float
1113(
1114 OpusMSEncoder *st,
1115 const opus_val16 *pcm,
1116 int frame_size,
1117 unsigned char *data,
1118 opus_int32 max_data_bytes
1119)
1120{
1121 return opus_multistream_encode_native(st, opus_copy_channel_in_float,
Jean-Marc Valinc94e4bb2013-12-08 03:31:50 -05001122 pcm, frame_size, data, max_data_bytes, 24, downmix_float, 1);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001123}
1124
1125int opus_multistream_encode(
1126 OpusMSEncoder *st,
1127 const opus_int16 *pcm,
1128 int frame_size,
1129 unsigned char *data,
1130 opus_int32 max_data_bytes
1131)
1132{
1133 return opus_multistream_encode_native(st, opus_copy_channel_in_short,
Jean-Marc Valinc94e4bb2013-12-08 03:31:50 -05001134 pcm, frame_size, data, max_data_bytes, 16, downmix_int, 0);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001135}
1136#endif
1137
1138int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
1139{
1140 va_list ap;
1141 int coupled_size, mono_size;
1142 char *ptr;
1143 int ret = OPUS_OK;
1144
1145 va_start(ap, request);
1146
1147 coupled_size = opus_encoder_get_size(2);
1148 mono_size = opus_encoder_get_size(1);
1149 ptr = (char*)st + align(sizeof(OpusMSEncoder));
1150 switch (request)
1151 {
1152 case OPUS_SET_BITRATE_REQUEST:
1153 {
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001154 opus_int32 value = va_arg(ap, opus_int32);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07001155 if (value<0 && value!=OPUS_AUTO && value!=OPUS_BITRATE_MAX)
1156 {
Jean-Marc Valin95561be2012-12-17 17:54:01 -05001157 goto bad_arg;
Gregory Maxwellb271dae2013-06-29 20:25:55 -07001158 }
Jean-Marc Valin74483662012-12-17 16:23:42 -05001159 st->bitrate_bps = value;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001160 }
1161 break;
1162 case OPUS_GET_BITRATE_REQUEST:
1163 {
1164 int s;
1165 opus_int32 *value = va_arg(ap, opus_int32*);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07001166 if (!value)
1167 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07001168 goto bad_arg;
1169 }
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001170 *value = 0;
1171 for (s=0;s<st->layout.nb_streams;s++)
1172 {
1173 opus_int32 rate;
1174 OpusEncoder *enc;
1175 enc = (OpusEncoder*)ptr;
1176 if (s < st->layout.nb_coupled_streams)
1177 ptr += align(coupled_size);
1178 else
1179 ptr += align(mono_size);
1180 opus_encoder_ctl(enc, request, &rate);
1181 *value += rate;
1182 }
1183 }
1184 break;
1185 case OPUS_GET_LSB_DEPTH_REQUEST:
1186 case OPUS_GET_VBR_REQUEST:
1187 case OPUS_GET_APPLICATION_REQUEST:
1188 case OPUS_GET_BANDWIDTH_REQUEST:
1189 case OPUS_GET_COMPLEXITY_REQUEST:
1190 case OPUS_GET_PACKET_LOSS_PERC_REQUEST:
1191 case OPUS_GET_DTX_REQUEST:
1192 case OPUS_GET_VOICE_RATIO_REQUEST:
1193 case OPUS_GET_VBR_CONSTRAINT_REQUEST:
1194 case OPUS_GET_SIGNAL_REQUEST:
1195 case OPUS_GET_LOOKAHEAD_REQUEST:
1196 case OPUS_GET_SAMPLE_RATE_REQUEST:
1197 case OPUS_GET_INBAND_FEC_REQUEST:
1198 case OPUS_GET_FORCE_CHANNELS_REQUEST:
Jean-Marc Valincbe93e22013-11-15 13:50:38 -05001199 case OPUS_GET_PREDICTION_DISABLED_REQUEST:
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001200 {
1201 OpusEncoder *enc;
1202 /* For int32* GET params, just query the first stream */
1203 opus_int32 *value = va_arg(ap, opus_int32*);
1204 enc = (OpusEncoder*)ptr;
1205 ret = opus_encoder_ctl(enc, request, value);
1206 }
1207 break;
1208 case OPUS_GET_FINAL_RANGE_REQUEST:
1209 {
1210 int s;
1211 opus_uint32 *value = va_arg(ap, opus_uint32*);
1212 opus_uint32 tmp;
Gregory Maxwella0d096f2013-06-29 20:33:32 -07001213 if (!value)
1214 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07001215 goto bad_arg;
1216 }
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001217 *value=0;
1218 for (s=0;s<st->layout.nb_streams;s++)
1219 {
1220 OpusEncoder *enc;
1221 enc = (OpusEncoder*)ptr;
1222 if (s < st->layout.nb_coupled_streams)
1223 ptr += align(coupled_size);
1224 else
1225 ptr += align(mono_size);
1226 ret = opus_encoder_ctl(enc, request, &tmp);
1227 if (ret != OPUS_OK) break;
1228 *value ^= tmp;
1229 }
1230 }
1231 break;
1232 case OPUS_SET_LSB_DEPTH_REQUEST:
1233 case OPUS_SET_COMPLEXITY_REQUEST:
1234 case OPUS_SET_VBR_REQUEST:
1235 case OPUS_SET_VBR_CONSTRAINT_REQUEST:
Daniel Jensenc0c0ef62013-07-22 16:31:31 -06001236 case OPUS_SET_MAX_BANDWIDTH_REQUEST:
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001237 case OPUS_SET_BANDWIDTH_REQUEST:
1238 case OPUS_SET_SIGNAL_REQUEST:
1239 case OPUS_SET_APPLICATION_REQUEST:
1240 case OPUS_SET_INBAND_FEC_REQUEST:
1241 case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
1242 case OPUS_SET_DTX_REQUEST:
1243 case OPUS_SET_FORCE_MODE_REQUEST:
1244 case OPUS_SET_FORCE_CHANNELS_REQUEST:
Jean-Marc Valincbe93e22013-11-15 13:50:38 -05001245 case OPUS_SET_PREDICTION_DISABLED_REQUEST:
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001246 {
1247 int s;
1248 /* This works for int32 params */
1249 opus_int32 value = va_arg(ap, opus_int32);
1250 for (s=0;s<st->layout.nb_streams;s++)
1251 {
1252 OpusEncoder *enc;
1253
1254 enc = (OpusEncoder*)ptr;
1255 if (s < st->layout.nb_coupled_streams)
1256 ptr += align(coupled_size);
1257 else
1258 ptr += align(mono_size);
1259 ret = opus_encoder_ctl(enc, request, value);
1260 if (ret != OPUS_OK)
1261 break;
1262 }
1263 }
1264 break;
1265 case OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST:
1266 {
1267 int s;
1268 opus_int32 stream_id;
1269 OpusEncoder **value;
1270 stream_id = va_arg(ap, opus_int32);
1271 if (stream_id<0 || stream_id >= st->layout.nb_streams)
1272 ret = OPUS_BAD_ARG;
1273 value = va_arg(ap, OpusEncoder**);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07001274 if (!value)
1275 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07001276 goto bad_arg;
1277 }
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001278 for (s=0;s<stream_id;s++)
1279 {
1280 if (s < st->layout.nb_coupled_streams)
1281 ptr += align(coupled_size);
1282 else
1283 ptr += align(mono_size);
1284 }
1285 *value = (OpusEncoder*)ptr;
1286 }
Jean-Marc Valin74483662012-12-17 16:23:42 -05001287 break;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -05001288 case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST:
Jean-Marc Valin74483662012-12-17 16:23:42 -05001289 {
1290 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin74483662012-12-17 16:23:42 -05001291 st->variable_duration = value;
1292 }
1293 break;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -05001294 case OPUS_GET_EXPERT_FRAME_DURATION_REQUEST:
Jean-Marc Valin74483662012-12-17 16:23:42 -05001295 {
1296 opus_int32 *value = va_arg(ap, opus_int32*);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07001297 if (!value)
1298 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07001299 goto bad_arg;
1300 }
Jean-Marc Valin74483662012-12-17 16:23:42 -05001301 *value = st->variable_duration;
1302 }
1303 break;
Jean-Marc Valin811db622013-10-28 16:11:53 -04001304 case OPUS_RESET_STATE:
1305 {
1306 int s;
1307 st->subframe_mem[0] = st->subframe_mem[1] = st->subframe_mem[2] = 0;
Michael Graczyk39256682016-05-02 21:42:18 -07001308 if (st->mapping_type == MAPPING_TYPE_SURROUND)
Jean-Marc Valin811db622013-10-28 16:11:53 -04001309 {
1310 OPUS_CLEAR(ms_get_preemph_mem(st), st->layout.nb_channels);
1311 OPUS_CLEAR(ms_get_window_mem(st), st->layout.nb_channels*120);
1312 }
1313 for (s=0;s<st->layout.nb_streams;s++)
1314 {
1315 OpusEncoder *enc;
1316 enc = (OpusEncoder*)ptr;
1317 if (s < st->layout.nb_coupled_streams)
1318 ptr += align(coupled_size);
1319 else
1320 ptr += align(mono_size);
1321 ret = opus_encoder_ctl(enc, OPUS_RESET_STATE);
1322 if (ret != OPUS_OK)
1323 break;
1324 }
1325 }
1326 break;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001327 default:
1328 ret = OPUS_UNIMPLEMENTED;
1329 break;
1330 }
1331
1332 va_end(ap);
1333 return ret;
Jean-Marc Valin74483662012-12-17 16:23:42 -05001334bad_arg:
1335 va_end(ap);
1336 return OPUS_BAD_ARG;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001337}
1338
1339void opus_multistream_encoder_destroy(OpusMSEncoder *st)
1340{
1341 opus_free(st);
1342}