blob: f08789edbec21ee3442237cd6bee3c914d9083b9 [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 Graczyk39256682016-05-02 21:42:18 -0700515 int mapping_type;
Jean-Marc Valin337f34c2013-07-01 16:17:01 -0400516 if ((channels>255) || (channels<1))
517 return OPUS_BAD_ARG;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400518 st->lfe_stream = -1;
Jean-Marc Valin7a8b1392013-04-29 18:32:27 -0400519 if (mapping_family==0)
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400520 {
Jean-Marc Valin7a8b1392013-04-29 18:32:27 -0400521 if (channels==1)
522 {
523 *streams=1;
524 *coupled_streams=0;
525 mapping[0]=0;
526 } else if (channels==2)
527 {
528 *streams=1;
529 *coupled_streams=1;
530 mapping[0]=0;
531 mapping[1]=1;
532 } else
533 return OPUS_UNIMPLEMENTED;
534 } else if (mapping_family==1 && channels<=8 && channels>=1)
535 {
536 int i;
537 *streams=vorbis_mappings[channels-1].nb_streams;
538 *coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams;
539 for (i=0;i<channels;i++)
540 mapping[i] = vorbis_mappings[channels-1].mapping[i];
541 if (channels>=6)
542 st->lfe_stream = *streams-1;
543 } else if (mapping_family==255)
544 {
545 int i;
546 *streams=channels;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400547 *coupled_streams=0;
Jean-Marc Valin7a8b1392013-04-29 18:32:27 -0400548 for(i=0;i<channels;i++)
549 mapping[i] = i;
Michael Graczyk39256682016-05-02 21:42:18 -0700550#ifdef ENABLE_EXPERIMENTAL_AMBISONICS
551 } else if (mapping_family==254)
552 {
553 int i;
554 *streams=channels;
555 *coupled_streams=0;
556 for(i=0;i<channels;i++)
557 mapping[i] = i;
558#endif
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400559 } else
Jean-Marc Valin7a8b1392013-04-29 18:32:27 -0400560 return OPUS_UNIMPLEMENTED;
Michael Graczyk39256682016-05-02 21:42:18 -0700561
562 if (channels>2 && mapping_family==1) {
563 mapping_type = MAPPING_TYPE_SURROUND;
564#ifdef ENABLE_EXPERIMENTAL_AMBISONICS
565 } else if (mapping_family==254)
566 {
567 mapping_type = MAPPING_TYPE_AMBISONICS;
568#endif
569 } else
570 {
571 mapping_type = MAPPING_TYPE_NONE;
572 }
573 return opus_multistream_encoder_init_impl(st, Fs, channels, *streams,
574 *coupled_streams, mapping,
575 application, mapping_type);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400576}
577
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500578OpusMSEncoder *opus_multistream_encoder_create(
579 opus_int32 Fs,
580 int channels,
581 int streams,
582 int coupled_streams,
583 const unsigned char *mapping,
584 int application,
585 int *error
586)
587{
588 int ret;
589 OpusMSEncoder *st;
590 if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
Mark Harris25b27a92014-11-27 08:48:09 -0800591 (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams))
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500592 {
593 if (error)
594 *error = OPUS_BAD_ARG;
595 return NULL;
596 }
597 st = (OpusMSEncoder *)opus_alloc(opus_multistream_encoder_get_size(streams, coupled_streams));
598 if (st==NULL)
599 {
600 if (error)
601 *error = OPUS_ALLOC_FAIL;
602 return NULL;
603 }
604 ret = opus_multistream_encoder_init(st, Fs, channels, streams, coupled_streams, mapping, application);
605 if (ret != OPUS_OK)
606 {
607 opus_free(st);
608 st = NULL;
609 }
610 if (error)
611 *error = ret;
612 return st;
613}
614
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400615OpusMSEncoder *opus_multistream_surround_encoder_create(
616 opus_int32 Fs,
617 int channels,
618 int mapping_family,
619 int *streams,
620 int *coupled_streams,
621 unsigned char *mapping,
622 int application,
623 int *error
624)
625{
626 int ret;
Mark Harris25b27a92014-11-27 08:48:09 -0800627 opus_int32 size;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400628 OpusMSEncoder *st;
629 if ((channels>255) || (channels<1))
630 {
631 if (error)
632 *error = OPUS_BAD_ARG;
633 return NULL;
634 }
Mark Harris25b27a92014-11-27 08:48:09 -0800635 size = opus_multistream_surround_encoder_get_size(channels, mapping_family);
636 if (!size)
637 {
638 if (error)
639 *error = OPUS_UNIMPLEMENTED;
640 return NULL;
641 }
642 st = (OpusMSEncoder *)opus_alloc(size);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400643 if (st==NULL)
644 {
645 if (error)
646 *error = OPUS_ALLOC_FAIL;
647 return NULL;
648 }
649 ret = opus_multistream_surround_encoder_init(st, Fs, channels, mapping_family, streams, coupled_streams, mapping, application);
650 if (ret != OPUS_OK)
651 {
652 opus_free(st);
653 st = NULL;
654 }
655 if (error)
656 *error = ret;
657 return st;
658}
659
Jean-Marc Valin8dc91de2014-06-21 01:16:46 -0400660static opus_int32 surround_rate_allocation(
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400661 OpusMSEncoder *st,
662 opus_int32 *rate,
663 int frame_size
664 )
665{
666 int i;
667 opus_int32 channel_rate;
668 opus_int32 Fs;
669 char *ptr;
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 Valin8dc91de2014-06-21 01:16:46 -0400674 opus_int32 rate_sum=0;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400675
676 ptr = (char*)st + align(sizeof(OpusMSEncoder));
677 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
678
Jean-Marc Valin49587512013-07-07 02:50:18 -0400679 if (st->bitrate_bps > st->layout.nb_channels*40000)
680 stream_offset = 20000;
681 else
682 stream_offset = st->bitrate_bps/st->layout.nb_channels/2;
Jean-Marc Valin87ca6c02013-11-13 22:58:10 -0500683 stream_offset += 60*(Fs/frame_size-50);
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400684 /* We start by giving each stream (coupled or uncoupled) the same bitrate.
685 This models the main saving of coupled channels over uncoupled. */
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400686 /* The LFE stream is an exception to the above and gets fewer bits. */
Jean-Marc Valin87ca6c02013-11-13 22:58:10 -0500687 lfe_offset = 3500 + 60*(Fs/frame_size-50);
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400688 /* Coupled streams get twice the mono rate after the first 20 kb/s. */
689 coupled_ratio = 512;
690 /* 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 -0400691 lfe_ratio = 32;
692
693 /* Compute bitrate allocation between streams */
694 if (st->bitrate_bps==OPUS_AUTO)
695 {
696 channel_rate = Fs+60*Fs/frame_size;
697 } else if (st->bitrate_bps==OPUS_BITRATE_MAX)
698 {
699 channel_rate = 300000;
700 } else {
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400701 int nb_lfe;
702 int nb_uncoupled;
703 int nb_coupled;
704 int total;
705 nb_lfe = (st->lfe_stream!=-1);
706 nb_coupled = st->layout.nb_coupled_streams;
707 nb_uncoupled = st->layout.nb_streams-nb_coupled-nb_lfe;
708 total = (nb_uncoupled<<8) /* mono */
709 + coupled_ratio*nb_coupled /* stereo */
710 + nb_lfe*lfe_ratio;
711 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 -0400712 }
713#ifndef FIXED_POINT
714 if (st->variable_duration==OPUS_FRAMESIZE_VARIABLE && frame_size != Fs/50)
715 {
716 opus_int32 bonus;
717 bonus = 60*(Fs/frame_size-50);
718 channel_rate += bonus;
719 }
720#endif
721
722 for (i=0;i<st->layout.nb_streams;i++)
723 {
724 if (i<st->layout.nb_coupled_streams)
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400725 rate[i] = stream_offset+(channel_rate*coupled_ratio>>8);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400726 else if (i!=st->lfe_stream)
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400727 rate[i] = stream_offset+channel_rate;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400728 else
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400729 rate[i] = lfe_offset+(channel_rate*lfe_ratio>>8);
Jean-Marc Valin8dc91de2014-06-21 01:16:46 -0400730 rate[i] = IMAX(rate[i], 500);
731 rate_sum += rate[i];
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400732 }
Jean-Marc Valin8dc91de2014-06-21 01:16:46 -0400733 return rate_sum;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400734}
735
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500736/* Max size in case the encoder decides to return three frames */
737#define MS_FRAME_TMP (3*1275+7)
738static int opus_multistream_encode_native
739(
740 OpusMSEncoder *st,
741 opus_copy_channel_in_func copy_channel_in,
742 const void *pcm,
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -0400743 int analysis_frame_size,
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500744 unsigned char *data,
Jean-Marc Valinb3eba242012-12-20 23:11:53 -0500745 opus_int32 max_data_bytes,
Jean-Marc Valin91904a42013-09-05 21:34:43 -0400746 int lsb_depth,
Jean-Marc Valinc94e4bb2013-12-08 03:31:50 -0500747 downmix_func downmix,
748 int float_api
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500749)
750{
751 opus_int32 Fs;
752 int coupled_size;
753 int mono_size;
754 int s;
755 char *ptr;
756 int tot_size;
757 VARDECL(opus_val16, buf);
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400758 VARDECL(opus_val16, bandSMR);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500759 unsigned char tmp_data[MS_FRAME_TMP];
760 OpusRepacketizer rp;
Jean-Marc Valineab134c2013-10-14 15:01:36 -0400761 opus_int32 vbr;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500762 const CELTMode *celt_mode;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400763 opus_int32 bitrates[256];
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400764 opus_val16 bandLogE[42];
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400765 opus_val32 *mem = NULL;
766 opus_val32 *preemph_mem=NULL;
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -0400767 int frame_size;
Jean-Marc Valin8dc91de2014-06-21 01:16:46 -0400768 opus_int32 rate_sum;
769 opus_int32 smallest_packet;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500770 ALLOC_STACK;
771
Michael Graczyk39256682016-05-02 21:42:18 -0700772 if (st->mapping_type == MAPPING_TYPE_SURROUND)
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400773 {
774 preemph_mem = ms_get_preemph_mem(st);
775 mem = ms_get_window_mem(st);
776 }
777
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500778 ptr = (char*)st + align(sizeof(OpusMSEncoder));
779 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
Jean-Marc Valineab134c2013-10-14 15:01:36 -0400780 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_VBR(&vbr));
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500781 opus_encoder_ctl((OpusEncoder*)ptr, CELT_GET_MODE(&celt_mode));
Jean-Marc Valin74483662012-12-17 16:23:42 -0500782
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -0400783 {
784 opus_int32 delay_compensation;
785 int channels;
786
787 channels = st->layout.nb_streams + st->layout.nb_coupled_streams;
788 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_LOOKAHEAD(&delay_compensation));
789 delay_compensation -= Fs/400;
790 frame_size = compute_frame_size(pcm, analysis_frame_size,
791 st->variable_duration, channels, Fs, st->bitrate_bps,
Jean-Marc Valinc2b34412013-10-28 21:48:50 -0400792 delay_compensation, downmix
793#ifndef DISABLE_FLOAT_API
794 , st->subframe_mem
795#endif
796 );
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -0400797 }
798
Jean-Marc Valin74483662012-12-17 16:23:42 -0500799 if (400*frame_size < Fs)
800 {
801 RESTORE_STACK;
802 return OPUS_BAD_ARG;
803 }
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500804 /* Validate frame_size before using it to allocate stack space.
805 This mirrors the checks in opus_encode[_float](). */
806 if (400*frame_size != Fs && 200*frame_size != Fs &&
807 100*frame_size != Fs && 50*frame_size != Fs &&
808 25*frame_size != Fs && 50*frame_size != 3*Fs)
809 {
810 RESTORE_STACK;
811 return OPUS_BAD_ARG;
812 }
Jean-Marc Valine1326fe2014-09-04 01:48:46 -0400813
814 /* Smallest packet the encoder can produce. */
815 smallest_packet = st->layout.nb_streams*2-1;
Jean-Marc Valin8dc91de2014-06-21 01:16:46 -0400816 if (max_data_bytes < smallest_packet)
817 {
818 RESTORE_STACK;
Jean-Marc Valine1326fe2014-09-04 01:48:46 -0400819 return OPUS_BUFFER_TOO_SMALL;
Jean-Marc Valin8dc91de2014-06-21 01:16:46 -0400820 }
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500821 ALLOC(buf, 2*frame_size, opus_val16);
822 coupled_size = opus_encoder_get_size(2);
823 mono_size = opus_encoder_get_size(1);
824
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400825 ALLOC(bandSMR, 21*st->layout.nb_channels, opus_val16);
Michael Graczyk39256682016-05-02 21:42:18 -0700826 if (st->mapping_type == MAPPING_TYPE_SURROUND)
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400827 {
Viswanath Puttaguntaf48abe82015-05-15 12:42:19 -0500828 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 -0400829 }
830
Jean-Marc Valin74483662012-12-17 16:23:42 -0500831 /* Compute bitrate allocation between streams (this could be a lot better) */
Jean-Marc Valin8dc91de2014-06-21 01:16:46 -0400832 rate_sum = surround_rate_allocation(st, bitrates, frame_size);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400833
Jean-Marc Valineab134c2013-10-14 15:01:36 -0400834 if (!vbr)
Jean-Marc Valin8dc91de2014-06-21 01:16:46 -0400835 {
836 if (st->bitrate_bps == OPUS_AUTO)
837 {
838 max_data_bytes = IMIN(max_data_bytes, 3*rate_sum/(3*8*Fs/frame_size));
839 } else if (st->bitrate_bps != OPUS_BITRATE_MAX)
840 {
841 max_data_bytes = IMIN(max_data_bytes, IMAX(smallest_packet,
842 3*st->bitrate_bps/(3*8*Fs/frame_size)));
843 }
844 }
Jean-Marc Valin74483662012-12-17 16:23:42 -0500845 ptr = (char*)st + align(sizeof(OpusMSEncoder));
846 for (s=0;s<st->layout.nb_streams;s++)
847 {
848 OpusEncoder *enc;
849 enc = (OpusEncoder*)ptr;
850 if (s < st->layout.nb_coupled_streams)
851 ptr += align(coupled_size);
852 else
853 ptr += align(mono_size);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400854 opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrates[s]));
Michael Graczyk39256682016-05-02 21:42:18 -0700855 if (st->mapping_type == MAPPING_TYPE_SURROUND)
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400856 {
Jean-Marc Valin6fbfed62013-09-13 17:16:38 -0400857 opus_int32 equiv_rate;
858 equiv_rate = st->bitrate_bps;
859 if (frame_size*50 < Fs)
860 equiv_rate -= 60*(Fs/frame_size - 50)*st->layout.nb_channels;
Jean-Marc Valinccf7d9b2013-11-24 01:57:52 -0500861 if (equiv_rate > 10000*st->layout.nb_channels)
Jean-Marc Valin6fbfed62013-09-13 17:16:38 -0400862 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
Jean-Marc Valinccf7d9b2013-11-24 01:57:52 -0500863 else if (equiv_rate > 7000*st->layout.nb_channels)
Jean-Marc Valin6fbfed62013-09-13 17:16:38 -0400864 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_SUPERWIDEBAND));
Jean-Marc Valinccf7d9b2013-11-24 01:57:52 -0500865 else if (equiv_rate > 5000*st->layout.nb_channels)
Jean-Marc Valin6fbfed62013-09-13 17:16:38 -0400866 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_WIDEBAND));
867 else
868 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND));
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400869 if (s < st->layout.nb_coupled_streams)
Jean-Marc Valin8824fdb2013-09-10 01:15:19 -0400870 {
871 /* To preserve the spatial image, force stereo CELT on coupled streams */
872 opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY));
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400873 opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(2));
Jean-Marc Valin8824fdb2013-09-10 01:15:19 -0400874 }
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400875 }
Jean-Marc Valin74483662012-12-17 16:23:42 -0500876 }
877
878 ptr = (char*)st + align(sizeof(OpusMSEncoder));
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500879 /* Counting ToC */
880 tot_size = 0;
881 for (s=0;s<st->layout.nb_streams;s++)
882 {
883 OpusEncoder *enc;
884 int len;
885 int curr_max;
Jean-Marc Valin91904a42013-09-05 21:34:43 -0400886 int c1, c2;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500887
888 opus_repacketizer_init(&rp);
889 enc = (OpusEncoder*)ptr;
890 if (s < st->layout.nb_coupled_streams)
891 {
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400892 int i;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500893 int left, right;
894 left = get_left_channel(&st->layout, s, -1);
895 right = get_right_channel(&st->layout, s, -1);
896 (*copy_channel_in)(buf, 2,
897 pcm, st->layout.nb_channels, left, frame_size);
898 (*copy_channel_in)(buf+1, 2,
899 pcm, st->layout.nb_channels, right, frame_size);
900 ptr += align(coupled_size);
Michael Graczyk39256682016-05-02 21:42:18 -0700901 if (st->mapping_type == MAPPING_TYPE_SURROUND)
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400902 {
903 for (i=0;i<21;i++)
904 {
905 bandLogE[i] = bandSMR[21*left+i];
906 bandLogE[21+i] = bandSMR[21*right+i];
907 }
908 }
Jean-Marc Valin91904a42013-09-05 21:34:43 -0400909 c1 = left;
910 c2 = right;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500911 } else {
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400912 int i;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500913 int chan = get_mono_channel(&st->layout, s, -1);
914 (*copy_channel_in)(buf, 1,
915 pcm, st->layout.nb_channels, chan, frame_size);
916 ptr += align(mono_size);
Michael Graczyk39256682016-05-02 21:42:18 -0700917 if (st->mapping_type == MAPPING_TYPE_SURROUND)
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400918 {
919 for (i=0;i<21;i++)
920 bandLogE[i] = bandSMR[21*chan+i];
921 }
Jean-Marc Valin91904a42013-09-05 21:34:43 -0400922 c1 = chan;
923 c2 = -1;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500924 }
Michael Graczyk39256682016-05-02 21:42:18 -0700925 if (st->mapping_type == MAPPING_TYPE_SURROUND)
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400926 opus_encoder_ctl(enc, OPUS_SET_ENERGY_MASK(bandLogE));
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500927 /* number of bytes left (+Toc) */
928 curr_max = max_data_bytes - tot_size;
Jean-Marc Valinda97db12014-09-04 02:48:21 -0400929 /* Reserve one byte for the last stream and two for the others */
Jean-Marc Valine1326fe2014-09-04 01:48:46 -0400930 curr_max -= IMAX(0,2*(st->layout.nb_streams-s-1)-1);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500931 curr_max = IMIN(curr_max,MS_FRAME_TMP);
Jean-Marc Valinda97db12014-09-04 02:48:21 -0400932 /* Repacketizer will add one or two bytes for self-delimited frames */
Jean-Marc Valin648eb9a2014-09-04 02:44:09 -0400933 if (s != st->layout.nb_streams-1) curr_max -= curr_max>253 ? 2 : 1;
Jean-Marc Valin2e653a72013-10-14 17:47:18 -0400934 if (!vbr && s == st->layout.nb_streams-1)
935 opus_encoder_ctl(enc, OPUS_SET_BITRATE(curr_max*(8*Fs/frame_size)));
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -0400936 len = opus_encode_native(enc, buf, frame_size, tmp_data, curr_max, lsb_depth,
Jean-Marc Valinc94e4bb2013-12-08 03:31:50 -0500937 pcm, analysis_frame_size, c1, c2, st->layout.nb_channels, downmix, float_api);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500938 if (len<0)
939 {
940 RESTORE_STACK;
941 return len;
942 }
943 /* We need to use the repacketizer to add the self-delimiting lengths
944 while taking into account the fact that the encoder can now return
945 more than one frame at a time (e.g. 60 ms CELT-only) */
946 opus_repacketizer_cat(&rp, tmp_data, len);
Jean-Marc Valinc5635d22013-11-13 14:08:22 -0500947 len = opus_repacketizer_out_range_impl(&rp, 0, opus_repacketizer_get_nb_frames(&rp),
948 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 -0500949 data += len;
950 tot_size += len;
951 }
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400952 /*printf("\n");*/
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500953 RESTORE_STACK;
954 return tot_size;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500955}
956
Pedro Becerra1af7f952013-07-11 00:00:47 -0400957#if !defined(DISABLE_FLOAT_API)
958static void opus_copy_channel_in_float(
959 opus_val16 *dst,
960 int dst_stride,
961 const void *src,
962 int src_stride,
963 int src_channel,
964 int frame_size
965)
966{
967 const float *float_src;
968 opus_int32 i;
969 float_src = (const float *)src;
970 for (i=0;i<frame_size;i++)
971#if defined(FIXED_POINT)
972 dst[i*dst_stride] = FLOAT2INT16(float_src[i*src_stride+src_channel]);
973#else
974 dst[i*dst_stride] = float_src[i*src_stride+src_channel];
975#endif
976}
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500977#endif
978
979static void opus_copy_channel_in_short(
980 opus_val16 *dst,
981 int dst_stride,
982 const void *src,
983 int src_stride,
984 int src_channel,
985 int frame_size
986)
987{
988 const opus_int16 *short_src;
Timothy B. Terriberrya8f04b22013-03-18 14:42:44 -0700989 opus_int32 i;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500990 short_src = (const opus_int16 *)src;
991 for (i=0;i<frame_size;i++)
992#if defined(FIXED_POINT)
993 dst[i*dst_stride] = short_src[i*src_stride+src_channel];
994#else
995 dst[i*dst_stride] = (1/32768.f)*short_src[i*src_stride+src_channel];
996#endif
997}
998
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400999
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001000#ifdef FIXED_POINT
1001int opus_multistream_encode(
1002 OpusMSEncoder *st,
1003 const opus_val16 *pcm,
1004 int frame_size,
1005 unsigned char *data,
1006 opus_int32 max_data_bytes
1007)
1008{
1009 return opus_multistream_encode_native(st, opus_copy_channel_in_short,
Jean-Marc Valinc94e4bb2013-12-08 03:31:50 -05001010 pcm, frame_size, data, max_data_bytes, 16, downmix_int, 0);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001011}
1012
1013#ifndef DISABLE_FLOAT_API
1014int opus_multistream_encode_float(
1015 OpusMSEncoder *st,
1016 const float *pcm,
1017 int frame_size,
1018 unsigned char *data,
1019 opus_int32 max_data_bytes
1020)
1021{
1022 return opus_multistream_encode_native(st, opus_copy_channel_in_float,
Jean-Marc Valinc94e4bb2013-12-08 03:31:50 -05001023 pcm, frame_size, data, max_data_bytes, 16, downmix_float, 1);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001024}
1025#endif
1026
1027#else
1028
1029int opus_multistream_encode_float
1030(
1031 OpusMSEncoder *st,
1032 const opus_val16 *pcm,
1033 int frame_size,
1034 unsigned char *data,
1035 opus_int32 max_data_bytes
1036)
1037{
1038 return opus_multistream_encode_native(st, opus_copy_channel_in_float,
Jean-Marc Valinc94e4bb2013-12-08 03:31:50 -05001039 pcm, frame_size, data, max_data_bytes, 24, downmix_float, 1);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001040}
1041
1042int opus_multistream_encode(
1043 OpusMSEncoder *st,
1044 const opus_int16 *pcm,
1045 int frame_size,
1046 unsigned char *data,
1047 opus_int32 max_data_bytes
1048)
1049{
1050 return opus_multistream_encode_native(st, opus_copy_channel_in_short,
Jean-Marc Valinc94e4bb2013-12-08 03:31:50 -05001051 pcm, frame_size, data, max_data_bytes, 16, downmix_int, 0);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001052}
1053#endif
1054
1055int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
1056{
1057 va_list ap;
1058 int coupled_size, mono_size;
1059 char *ptr;
1060 int ret = OPUS_OK;
1061
1062 va_start(ap, request);
1063
1064 coupled_size = opus_encoder_get_size(2);
1065 mono_size = opus_encoder_get_size(1);
1066 ptr = (char*)st + align(sizeof(OpusMSEncoder));
1067 switch (request)
1068 {
1069 case OPUS_SET_BITRATE_REQUEST:
1070 {
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001071 opus_int32 value = va_arg(ap, opus_int32);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07001072 if (value<0 && value!=OPUS_AUTO && value!=OPUS_BITRATE_MAX)
1073 {
Jean-Marc Valin95561be2012-12-17 17:54:01 -05001074 goto bad_arg;
Gregory Maxwellb271dae2013-06-29 20:25:55 -07001075 }
Jean-Marc Valin74483662012-12-17 16:23:42 -05001076 st->bitrate_bps = value;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001077 }
1078 break;
1079 case OPUS_GET_BITRATE_REQUEST:
1080 {
1081 int s;
1082 opus_int32 *value = va_arg(ap, opus_int32*);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07001083 if (!value)
1084 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07001085 goto bad_arg;
1086 }
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001087 *value = 0;
1088 for (s=0;s<st->layout.nb_streams;s++)
1089 {
1090 opus_int32 rate;
1091 OpusEncoder *enc;
1092 enc = (OpusEncoder*)ptr;
1093 if (s < st->layout.nb_coupled_streams)
1094 ptr += align(coupled_size);
1095 else
1096 ptr += align(mono_size);
1097 opus_encoder_ctl(enc, request, &rate);
1098 *value += rate;
1099 }
1100 }
1101 break;
1102 case OPUS_GET_LSB_DEPTH_REQUEST:
1103 case OPUS_GET_VBR_REQUEST:
1104 case OPUS_GET_APPLICATION_REQUEST:
1105 case OPUS_GET_BANDWIDTH_REQUEST:
1106 case OPUS_GET_COMPLEXITY_REQUEST:
1107 case OPUS_GET_PACKET_LOSS_PERC_REQUEST:
1108 case OPUS_GET_DTX_REQUEST:
1109 case OPUS_GET_VOICE_RATIO_REQUEST:
1110 case OPUS_GET_VBR_CONSTRAINT_REQUEST:
1111 case OPUS_GET_SIGNAL_REQUEST:
1112 case OPUS_GET_LOOKAHEAD_REQUEST:
1113 case OPUS_GET_SAMPLE_RATE_REQUEST:
1114 case OPUS_GET_INBAND_FEC_REQUEST:
1115 case OPUS_GET_FORCE_CHANNELS_REQUEST:
Jean-Marc Valincbe93e22013-11-15 13:50:38 -05001116 case OPUS_GET_PREDICTION_DISABLED_REQUEST:
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001117 {
1118 OpusEncoder *enc;
1119 /* For int32* GET params, just query the first stream */
1120 opus_int32 *value = va_arg(ap, opus_int32*);
1121 enc = (OpusEncoder*)ptr;
1122 ret = opus_encoder_ctl(enc, request, value);
1123 }
1124 break;
1125 case OPUS_GET_FINAL_RANGE_REQUEST:
1126 {
1127 int s;
1128 opus_uint32 *value = va_arg(ap, opus_uint32*);
1129 opus_uint32 tmp;
Gregory Maxwella0d096f2013-06-29 20:33:32 -07001130 if (!value)
1131 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07001132 goto bad_arg;
1133 }
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001134 *value=0;
1135 for (s=0;s<st->layout.nb_streams;s++)
1136 {
1137 OpusEncoder *enc;
1138 enc = (OpusEncoder*)ptr;
1139 if (s < st->layout.nb_coupled_streams)
1140 ptr += align(coupled_size);
1141 else
1142 ptr += align(mono_size);
1143 ret = opus_encoder_ctl(enc, request, &tmp);
1144 if (ret != OPUS_OK) break;
1145 *value ^= tmp;
1146 }
1147 }
1148 break;
1149 case OPUS_SET_LSB_DEPTH_REQUEST:
1150 case OPUS_SET_COMPLEXITY_REQUEST:
1151 case OPUS_SET_VBR_REQUEST:
1152 case OPUS_SET_VBR_CONSTRAINT_REQUEST:
Daniel Jensenc0c0ef62013-07-22 16:31:31 -06001153 case OPUS_SET_MAX_BANDWIDTH_REQUEST:
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001154 case OPUS_SET_BANDWIDTH_REQUEST:
1155 case OPUS_SET_SIGNAL_REQUEST:
1156 case OPUS_SET_APPLICATION_REQUEST:
1157 case OPUS_SET_INBAND_FEC_REQUEST:
1158 case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
1159 case OPUS_SET_DTX_REQUEST:
1160 case OPUS_SET_FORCE_MODE_REQUEST:
1161 case OPUS_SET_FORCE_CHANNELS_REQUEST:
Jean-Marc Valincbe93e22013-11-15 13:50:38 -05001162 case OPUS_SET_PREDICTION_DISABLED_REQUEST:
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001163 {
1164 int s;
1165 /* This works for int32 params */
1166 opus_int32 value = va_arg(ap, opus_int32);
1167 for (s=0;s<st->layout.nb_streams;s++)
1168 {
1169 OpusEncoder *enc;
1170
1171 enc = (OpusEncoder*)ptr;
1172 if (s < st->layout.nb_coupled_streams)
1173 ptr += align(coupled_size);
1174 else
1175 ptr += align(mono_size);
1176 ret = opus_encoder_ctl(enc, request, value);
1177 if (ret != OPUS_OK)
1178 break;
1179 }
1180 }
1181 break;
1182 case OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST:
1183 {
1184 int s;
1185 opus_int32 stream_id;
1186 OpusEncoder **value;
1187 stream_id = va_arg(ap, opus_int32);
1188 if (stream_id<0 || stream_id >= st->layout.nb_streams)
1189 ret = OPUS_BAD_ARG;
1190 value = va_arg(ap, OpusEncoder**);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07001191 if (!value)
1192 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07001193 goto bad_arg;
1194 }
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001195 for (s=0;s<stream_id;s++)
1196 {
1197 if (s < st->layout.nb_coupled_streams)
1198 ptr += align(coupled_size);
1199 else
1200 ptr += align(mono_size);
1201 }
1202 *value = (OpusEncoder*)ptr;
1203 }
Jean-Marc Valin74483662012-12-17 16:23:42 -05001204 break;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -05001205 case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST:
Jean-Marc Valin74483662012-12-17 16:23:42 -05001206 {
1207 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin74483662012-12-17 16:23:42 -05001208 st->variable_duration = value;
1209 }
1210 break;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -05001211 case OPUS_GET_EXPERT_FRAME_DURATION_REQUEST:
Jean-Marc Valin74483662012-12-17 16:23:42 -05001212 {
1213 opus_int32 *value = va_arg(ap, opus_int32*);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07001214 if (!value)
1215 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07001216 goto bad_arg;
1217 }
Jean-Marc Valin74483662012-12-17 16:23:42 -05001218 *value = st->variable_duration;
1219 }
1220 break;
Jean-Marc Valin811db622013-10-28 16:11:53 -04001221 case OPUS_RESET_STATE:
1222 {
1223 int s;
1224 st->subframe_mem[0] = st->subframe_mem[1] = st->subframe_mem[2] = 0;
Michael Graczyk39256682016-05-02 21:42:18 -07001225 if (st->mapping_type == MAPPING_TYPE_SURROUND)
Jean-Marc Valin811db622013-10-28 16:11:53 -04001226 {
1227 OPUS_CLEAR(ms_get_preemph_mem(st), st->layout.nb_channels);
1228 OPUS_CLEAR(ms_get_window_mem(st), st->layout.nb_channels*120);
1229 }
1230 for (s=0;s<st->layout.nb_streams;s++)
1231 {
1232 OpusEncoder *enc;
1233 enc = (OpusEncoder*)ptr;
1234 if (s < st->layout.nb_coupled_streams)
1235 ptr += align(coupled_size);
1236 else
1237 ptr += align(mono_size);
1238 ret = opus_encoder_ctl(enc, OPUS_RESET_STATE);
1239 if (ret != OPUS_OK)
1240 break;
1241 }
1242 }
1243 break;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001244 default:
1245 ret = OPUS_UNIMPLEMENTED;
1246 break;
1247 }
1248
1249 va_end(ap);
1250 return ret;
Jean-Marc Valin74483662012-12-17 16:23:42 -05001251bad_arg:
1252 va_end(ap);
1253 return OPUS_BAD_ARG;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001254}
1255
1256void opus_multistream_encoder_destroy(OpusMSEncoder *st)
1257{
1258 opus_free(st);
1259}