blob: aa464f5906d39ae1d6b9d3166b2f7caca7a4d8cb [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 Valinae0e2ca2012-11-07 19:57:33 -050044
Jean-Marc Valin7a8b1392013-04-29 18:32:27 -040045typedef struct {
46 int nb_streams;
47 int nb_coupled_streams;
48 unsigned char mapping[8];
49} VorbisLayout;
50
51/* Index is nb_channel-1*/
52static const VorbisLayout vorbis_mappings[8] = {
53 {1, 0, {0}}, /* 1: mono */
54 {1, 1, {0, 1}}, /* 2: stereo */
55 {2, 1, {0, 2, 1}}, /* 3: 1-d surround */
56 {2, 2, {0, 1, 2, 3}}, /* 4: quadraphonic surround */
57 {3, 2, {0, 4, 1, 2, 3}}, /* 5: 5-channel surround */
58 {4, 2, {0, 4, 1, 2, 3, 5}}, /* 6: 5.1 surround */
59 {4, 3, {0, 4, 1, 2, 3, 5, 6}}, /* 7: 6.1 surround */
60 {5, 3, {0, 6, 1, 2, 3, 4, 5, 7}}, /* 8: 7.1 surround */
61};
62
Jean-Marc Valinfdceae82013-08-30 21:58:02 -040063typedef void (*opus_copy_channel_in_func)(
64 opus_val16 *dst,
65 int dst_stride,
66 const void *src,
67 int src_stride,
68 int src_channel,
69 int frame_size
70);
71
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -050072struct OpusMSEncoder {
73 ChannelLayout layout;
Jean-Marc Valin1b723862013-04-25 21:34:04 -040074 int lfe_stream;
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -040075 int application;
Jean-Marc Valin74483662012-12-17 16:23:42 -050076 int variable_duration;
Jean-Marc Valina4dccd32013-05-04 23:54:20 -040077 int surround;
Jean-Marc Valin74483662012-12-17 16:23:42 -050078 opus_int32 bitrate_bps;
Jean-Marc Valinab86a9c2013-11-13 23:06:25 -050079 float subframe_mem[3];
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -050080 /* Encoder states go here */
Jean-Marc Valinfdceae82013-08-30 21:58:02 -040081 /* then opus_val32 window_mem[channels*120]; */
82 /* then opus_val32 preemph_mem[channels]; */
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -050083};
84
Jean-Marc Valinfdceae82013-08-30 21:58:02 -040085static opus_val32 *ms_get_preemph_mem(OpusMSEncoder *st)
86{
87 int s;
88 char *ptr;
89 int coupled_size, mono_size;
90
91 coupled_size = opus_encoder_get_size(2);
92 mono_size = opus_encoder_get_size(1);
93 ptr = (char*)st + align(sizeof(OpusMSEncoder));
94 for (s=0;s<st->layout.nb_streams;s++)
95 {
96 if (s < st->layout.nb_coupled_streams)
97 ptr += align(coupled_size);
98 else
99 ptr += align(mono_size);
100 }
101 return (opus_val32*)(ptr+st->layout.nb_channels*120*sizeof(opus_val32));
102}
103
104static opus_val32 *ms_get_window_mem(OpusMSEncoder *st)
105{
106 int s;
107 char *ptr;
108 int coupled_size, mono_size;
109
110 coupled_size = opus_encoder_get_size(2);
111 mono_size = opus_encoder_get_size(1);
112 ptr = (char*)st + align(sizeof(OpusMSEncoder));
113 for (s=0;s<st->layout.nb_streams;s++)
114 {
115 if (s < st->layout.nb_coupled_streams)
116 ptr += align(coupled_size);
117 else
118 ptr += align(mono_size);
119 }
120 return (opus_val32*)ptr;
121}
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500122
123static int validate_encoder_layout(const ChannelLayout *layout)
124{
125 int s;
126 for (s=0;s<layout->nb_streams;s++)
127 {
128 if (s < layout->nb_coupled_streams)
129 {
130 if (get_left_channel(layout, s, -1)==-1)
131 return 0;
132 if (get_right_channel(layout, s, -1)==-1)
133 return 0;
134 } else {
135 if (get_mono_channel(layout, s, -1)==-1)
136 return 0;
137 }
138 }
139 return 1;
140}
141
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400142static void channel_pos(int channels, int pos[8])
143{
144 /* Position in the mix: 0 don't mix, 1: left, 2: center, 3:right */
145 if (channels==4)
146 {
147 pos[0]=1;
148 pos[1]=3;
149 pos[2]=1;
150 pos[3]=3;
151 } else if (channels==3||channels==5||channels==6)
152 {
153 pos[0]=1;
154 pos[1]=2;
155 pos[2]=3;
156 pos[3]=1;
157 pos[4]=3;
158 pos[5]=0;
159 } else if (channels==7)
160 {
161 pos[0]=1;
162 pos[1]=2;
163 pos[2]=3;
164 pos[3]=1;
165 pos[4]=3;
166 pos[5]=2;
167 pos[6]=0;
168 } else if (channels==8)
169 {
170 pos[0]=1;
171 pos[1]=2;
172 pos[2]=3;
173 pos[3]=1;
174 pos[4]=3;
175 pos[5]=1;
176 pos[6]=3;
177 pos[7]=0;
178 }
179}
180
Jean-Marc Valina714ae92013-08-31 02:05:32 -0400181#if 1
182/* Computes a rough approximation of log2(2^a + 2^b) */
183static opus_val16 logSum(opus_val16 a, opus_val16 b)
184{
185 opus_val16 max;
186 opus_val32 diff;
187 opus_val16 frac;
188 static const opus_val16 diff_table[17] = {
189 QCONST16(0.5000000f, DB_SHIFT), QCONST16(0.2924813f, DB_SHIFT), QCONST16(0.1609640f, DB_SHIFT), QCONST16(0.0849625f, DB_SHIFT),
190 QCONST16(0.0437314f, DB_SHIFT), QCONST16(0.0221971f, DB_SHIFT), QCONST16(0.0111839f, DB_SHIFT), QCONST16(0.0056136f, DB_SHIFT),
191 QCONST16(0.0028123f, DB_SHIFT)
192 };
193 int low;
194 if (a>b)
195 {
196 max = a;
197 diff = SUB32(EXTEND32(a),EXTEND32(b));
198 } else {
199 max = b;
200 diff = SUB32(EXTEND32(b),EXTEND32(a));
201 }
202 if (diff >= QCONST16(8.f, DB_SHIFT))
203 return max;
204#ifdef FIXED_POINT
205 low = SHR32(diff, DB_SHIFT-1);
206 frac = SHL16(diff - SHL16(low, DB_SHIFT-1), 16-DB_SHIFT);
207#else
Jean-Marc Valina71c9ad2013-11-13 12:07:01 -0500208 low = (int)floor(2*diff);
Jean-Marc Valina714ae92013-08-31 02:05:32 -0400209 frac = 2*diff - low;
210#endif
211 return max + diff_table[low] + MULT16_16_Q15(frac, SUB16(diff_table[low+1], diff_table[low]));
212}
213#else
214opus_val16 logSum(opus_val16 a, opus_val16 b)
215{
216 return log2(pow(4, a)+ pow(4, b))/2;
217}
218#endif
219
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400220void surround_analysis(const CELTMode *celt_mode, const void *pcm, opus_val16 *bandLogE, opus_val32 *mem, opus_val32 *preemph_mem,
221 int len, int overlap, int channels, int rate, opus_copy_channel_in_func copy_channel_in
222)
223{
224 int c;
225 int i;
Jean-Marc Valin54bddf02013-09-11 23:34:51 -0400226 int LM;
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400227 int pos[8] = {0};
228 int upsample;
Jean-Marc Valin978e4cb2013-09-11 00:51:22 -0400229 int frame_size;
Jean-Marc Valin942fc812013-10-01 19:27:30 -0400230 opus_val16 channel_offset;
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400231 opus_val32 bandE[21];
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400232 opus_val16 maskLogE[3][21];
233 VARDECL(opus_val32, in);
234 VARDECL(opus_val16, x);
Jean-Marc Valine8e5ecb2013-10-01 17:16:33 -0400235 VARDECL(opus_val32, freq);
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400236 SAVE_STACK;
Jean-Marc Valin978e4cb2013-09-11 00:51:22 -0400237
238 upsample = resampling_factor(rate);
239 frame_size = len*upsample;
240
Jean-Marc Valin2e653a72013-10-14 17:47:18 -0400241 for (LM=0;LM<celt_mode->maxLM;LM++)
Jean-Marc Valin54bddf02013-09-11 23:34:51 -0400242 if (celt_mode->shortMdctSize<<LM==frame_size)
243 break;
244
Jean-Marc Valin978e4cb2013-09-11 00:51:22 -0400245 ALLOC(in, frame_size+overlap, opus_val32);
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400246 ALLOC(x, len, opus_val16);
Jean-Marc Valin978e4cb2013-09-11 00:51:22 -0400247 ALLOC(freq, frame_size, opus_val32);
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400248
249 channel_pos(channels, pos);
250
Jean-Marc Valina714ae92013-08-31 02:05:32 -0400251 for (c=0;c<3;c++)
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400252 for (i=0;i<21;i++)
Jean-Marc Valina714ae92013-08-31 02:05:32 -0400253 maskLogE[c][i] = -QCONST16(28.f, DB_SHIFT);
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400254
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400255 for (c=0;c<channels;c++)
256 {
257 OPUS_COPY(in, mem+c*overlap, overlap);
258 (*copy_channel_in)(x, 1, pcm, channels, c, len);
Jean-Marc Valin2dc27df2013-11-13 19:35:43 -0500259 celt_preemphasis(x, in+overlap, frame_size, 1, upsample, celt_mode->preemph, preemph_mem+c, 0);
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400260 clt_mdct_forward(&celt_mode->mdct, in, freq, celt_mode->window, overlap, celt_mode->maxLM-LM, 1);
261 if (upsample != 1)
262 {
Jean-Marc Valin978e4cb2013-09-11 00:51:22 -0400263 int bound = len;
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400264 for (i=0;i<bound;i++)
265 freq[i] *= upsample;
Jean-Marc Valin978e4cb2013-09-11 00:51:22 -0400266 for (;i<frame_size;i++)
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400267 freq[i] = 0;
268 }
269
Mark Harris58107d82014-01-25 16:32:18 -0800270 compute_band_energies(celt_mode, freq, bandE, 21, 1, LM);
Jean-Marc Valina714ae92013-08-31 02:05:32 -0400271 amp2Log2(celt_mode, 21, 21, bandE, bandLogE+21*c, 1);
Jean-Marc Valin0f686962013-09-05 12:49:55 -0400272 /* Apply spreading function with -6 dB/band going up and -12 dB/band going down. */
273 for (i=1;i<21;i++)
274 bandLogE[21*c+i] = MAX16(bandLogE[21*c+i], bandLogE[21*c+i-1]-QCONST16(1.f, DB_SHIFT));
275 for (i=19;i>=0;i--)
276 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 -0400277 if (pos[c]==1)
278 {
279 for (i=0;i<21;i++)
Jean-Marc Valina714ae92013-08-31 02:05:32 -0400280 maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]);
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400281 } else if (pos[c]==3)
282 {
283 for (i=0;i<21;i++)
Jean-Marc Valina714ae92013-08-31 02:05:32 -0400284 maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]);
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400285 } else if (pos[c]==2)
286 {
287 for (i=0;i<21;i++)
288 {
Jean-Marc Valina714ae92013-08-31 02:05:32 -0400289 maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]-QCONST16(.5f, DB_SHIFT));
290 maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]-QCONST16(.5f, DB_SHIFT));
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400291 }
292 }
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400293#if 0
294 for (i=0;i<21;i++)
295 printf("%f ", bandLogE[21*c+i]);
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400296 float sum=0;
297 for (i=0;i<21;i++)
298 sum += bandLogE[21*c+i];
299 printf("%f ", sum/21);
300#endif
Jean-Marc Valin978e4cb2013-09-11 00:51:22 -0400301 OPUS_COPY(mem+c*overlap, in+frame_size, overlap);
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400302 }
303 for (i=0;i<21;i++)
Jean-Marc Valina714ae92013-08-31 02:05:32 -0400304 maskLogE[1][i] = MIN32(maskLogE[0][i],maskLogE[2][i]);
Jean-Marc Valin942fc812013-10-01 19:27:30 -0400305 channel_offset = HALF16(celt_log2(QCONST32(2.f,14)/(channels-1)));
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400306 for (c=0;c<3;c++)
307 for (i=0;i<21;i++)
Jean-Marc Valin942fc812013-10-01 19:27:30 -0400308 maskLogE[c][i] += channel_offset;
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400309#if 0
310 for (c=0;c<3;c++)
311 {
312 for (i=0;i<21;i++)
313 printf("%f ", maskLogE[c][i]);
314 }
315#endif
316 for (c=0;c<channels;c++)
317 {
318 opus_val16 *mask;
319 if (pos[c]!=0)
320 {
321 mask = &maskLogE[pos[c]-1][0];
322 for (i=0;i<21;i++)
323 bandLogE[21*c+i] = bandLogE[21*c+i] - mask[i];
324 } else {
325 for (i=0;i<21;i++)
326 bandLogE[21*c+i] = 0;
327 }
328#if 0
329 for (i=0;i<21;i++)
330 printf("%f ", bandLogE[21*c+i]);
331 printf("\n");
332#endif
333#if 0
334 float sum=0;
335 for (i=0;i<21;i++)
336 sum += bandLogE[21*c+i];
Jean-Marc Valin942fc812013-10-01 19:27:30 -0400337 printf("%f ", sum/(float)QCONST32(21.f, DB_SHIFT));
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400338 printf("\n");
339#endif
340 }
341 RESTORE_STACK;
342}
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500343
344opus_int32 opus_multistream_encoder_get_size(int nb_streams, int nb_coupled_streams)
345{
346 int coupled_size;
347 int mono_size;
348
349 if(nb_streams<1||nb_coupled_streams>nb_streams||nb_coupled_streams<0)return 0;
350 coupled_size = opus_encoder_get_size(2);
351 mono_size = opus_encoder_get_size(1);
352 return align(sizeof(OpusMSEncoder))
353 + nb_coupled_streams * align(coupled_size)
354 + (nb_streams-nb_coupled_streams) * align(mono_size);
355}
356
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400357opus_int32 opus_multistream_surround_encoder_get_size(int channels, int mapping_family)
358{
359 int nb_streams;
360 int nb_coupled_streams;
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400361 opus_int32 size;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400362
Jean-Marc Valin7a8b1392013-04-29 18:32:27 -0400363 if (mapping_family==0)
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400364 {
Jean-Marc Valin7a8b1392013-04-29 18:32:27 -0400365 if (channels==1)
366 {
367 nb_streams=1;
368 nb_coupled_streams=0;
369 } else if (channels==2)
370 {
371 nb_streams=1;
372 nb_coupled_streams=1;
373 } else
374 return 0;
375 } else if (mapping_family==1 && channels<=8 && channels>=1)
376 {
377 nb_streams=vorbis_mappings[channels-1].nb_streams;
378 nb_coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams;
379 } else if (mapping_family==255)
380 {
381 nb_streams=channels;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400382 nb_coupled_streams=0;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400383 } else
384 return 0;
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400385 size = opus_multistream_encoder_get_size(nb_streams, nb_coupled_streams);
386 if (channels>2)
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400387 {
388 size += channels*(120*sizeof(opus_val32) + sizeof(opus_val32));
389 }
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400390 return size;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400391}
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500392
393
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400394static int opus_multistream_encoder_init_impl(
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500395 OpusMSEncoder *st,
396 opus_int32 Fs,
397 int channels,
398 int streams,
399 int coupled_streams,
400 const unsigned char *mapping,
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400401 int application,
402 int surround
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500403)
404{
405 int coupled_size;
406 int mono_size;
407 int i, ret;
408 char *ptr;
409
410 if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
411 (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0))
412 return OPUS_BAD_ARG;
413
414 st->layout.nb_channels = channels;
415 st->layout.nb_streams = streams;
416 st->layout.nb_coupled_streams = coupled_streams;
Jean-Marc Valinb0429352013-05-05 02:22:06 -0400417 st->subframe_mem[0]=st->subframe_mem[1]=st->subframe_mem[2]=0;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400418 if (!surround)
419 st->lfe_stream = -1;
Jean-Marc Valin95561be2012-12-17 17:54:01 -0500420 st->bitrate_bps = OPUS_AUTO;
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -0400421 st->application = application;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500422 st->variable_duration = OPUS_FRAMESIZE_ARG;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500423 for (i=0;i<st->layout.nb_channels;i++)
424 st->layout.mapping[i] = mapping[i];
425 if (!validate_layout(&st->layout) || !validate_encoder_layout(&st->layout))
426 return OPUS_BAD_ARG;
427 ptr = (char*)st + align(sizeof(OpusMSEncoder));
428 coupled_size = opus_encoder_get_size(2);
429 mono_size = opus_encoder_get_size(1);
430
431 for (i=0;i<st->layout.nb_coupled_streams;i++)
432 {
433 ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 2, application);
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400434 if(ret!=OPUS_OK)return ret;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400435 if (i==st->lfe_stream)
436 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1));
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500437 ptr += align(coupled_size);
438 }
439 for (;i<st->layout.nb_streams;i++)
440 {
441 ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 1, application);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400442 if (i==st->lfe_stream)
443 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1));
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500444 if(ret!=OPUS_OK)return ret;
445 ptr += align(mono_size);
446 }
Jean-Marc Valin58d80ab2013-05-27 20:47:47 -0400447 if (surround)
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400448 {
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400449 OPUS_CLEAR(ms_get_preemph_mem(st), channels);
450 OPUS_CLEAR(ms_get_window_mem(st), channels*120);
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400451 }
452 st->surround = surround;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500453 return OPUS_OK;
454}
455
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400456int opus_multistream_encoder_init(
457 OpusMSEncoder *st,
458 opus_int32 Fs,
459 int channels,
460 int streams,
461 int coupled_streams,
462 const unsigned char *mapping,
463 int application
464)
465{
466 return opus_multistream_encoder_init_impl(st, Fs, channels, streams, coupled_streams, mapping, application, 0);
467}
468
469int opus_multistream_surround_encoder_init(
470 OpusMSEncoder *st,
471 opus_int32 Fs,
472 int channels,
473 int mapping_family,
474 int *streams,
475 int *coupled_streams,
476 unsigned char *mapping,
477 int application
478)
479{
Jean-Marc Valin337f34c2013-07-01 16:17:01 -0400480 if ((channels>255) || (channels<1))
481 return OPUS_BAD_ARG;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400482 st->lfe_stream = -1;
Jean-Marc Valin7a8b1392013-04-29 18:32:27 -0400483 if (mapping_family==0)
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400484 {
Jean-Marc Valin7a8b1392013-04-29 18:32:27 -0400485 if (channels==1)
486 {
487 *streams=1;
488 *coupled_streams=0;
489 mapping[0]=0;
490 } else if (channels==2)
491 {
492 *streams=1;
493 *coupled_streams=1;
494 mapping[0]=0;
495 mapping[1]=1;
496 } else
497 return OPUS_UNIMPLEMENTED;
498 } else if (mapping_family==1 && channels<=8 && channels>=1)
499 {
500 int i;
501 *streams=vorbis_mappings[channels-1].nb_streams;
502 *coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams;
503 for (i=0;i<channels;i++)
504 mapping[i] = vorbis_mappings[channels-1].mapping[i];
505 if (channels>=6)
506 st->lfe_stream = *streams-1;
507 } else if (mapping_family==255)
508 {
509 int i;
510 *streams=channels;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400511 *coupled_streams=0;
Jean-Marc Valin7a8b1392013-04-29 18:32:27 -0400512 for(i=0;i<channels;i++)
513 mapping[i] = i;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400514 } else
Jean-Marc Valin7a8b1392013-04-29 18:32:27 -0400515 return OPUS_UNIMPLEMENTED;
Jean-Marc Valin337f34c2013-07-01 16:17:01 -0400516 return opus_multistream_encoder_init_impl(st, Fs, channels, *streams, *coupled_streams,
Jean-Marc Valin58d80ab2013-05-27 20:47:47 -0400517 mapping, application, channels>2&&mapping_family==1);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400518}
519
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500520OpusMSEncoder *opus_multistream_encoder_create(
521 opus_int32 Fs,
522 int channels,
523 int streams,
524 int coupled_streams,
525 const unsigned char *mapping,
526 int application,
527 int *error
528)
529{
530 int ret;
531 OpusMSEncoder *st;
532 if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
533 (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0))
534 {
535 if (error)
536 *error = OPUS_BAD_ARG;
537 return NULL;
538 }
539 st = (OpusMSEncoder *)opus_alloc(opus_multistream_encoder_get_size(streams, coupled_streams));
540 if (st==NULL)
541 {
542 if (error)
543 *error = OPUS_ALLOC_FAIL;
544 return NULL;
545 }
546 ret = opus_multistream_encoder_init(st, Fs, channels, streams, coupled_streams, mapping, application);
547 if (ret != OPUS_OK)
548 {
549 opus_free(st);
550 st = NULL;
551 }
552 if (error)
553 *error = ret;
554 return st;
555}
556
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400557OpusMSEncoder *opus_multistream_surround_encoder_create(
558 opus_int32 Fs,
559 int channels,
560 int mapping_family,
561 int *streams,
562 int *coupled_streams,
563 unsigned char *mapping,
564 int application,
565 int *error
566)
567{
568 int ret;
569 OpusMSEncoder *st;
570 if ((channels>255) || (channels<1))
571 {
572 if (error)
573 *error = OPUS_BAD_ARG;
574 return NULL;
575 }
576 st = (OpusMSEncoder *)opus_alloc(opus_multistream_surround_encoder_get_size(channels, mapping_family));
577 if (st==NULL)
578 {
579 if (error)
580 *error = OPUS_ALLOC_FAIL;
581 return NULL;
582 }
583 ret = opus_multistream_surround_encoder_init(st, Fs, channels, mapping_family, streams, coupled_streams, mapping, application);
584 if (ret != OPUS_OK)
585 {
586 opus_free(st);
587 st = NULL;
588 }
589 if (error)
590 *error = ret;
591 return st;
592}
593
Jean-Marc Valin8dc91de2014-06-21 01:16:46 -0400594static opus_int32 surround_rate_allocation(
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400595 OpusMSEncoder *st,
596 opus_int32 *rate,
597 int frame_size
598 )
599{
600 int i;
601 opus_int32 channel_rate;
602 opus_int32 Fs;
603 char *ptr;
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400604 int stream_offset;
605 int lfe_offset;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400606 int coupled_ratio; /* Q8 */
607 int lfe_ratio; /* Q8 */
Jean-Marc Valin8dc91de2014-06-21 01:16:46 -0400608 opus_int32 rate_sum=0;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400609
610 ptr = (char*)st + align(sizeof(OpusMSEncoder));
611 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
612
Jean-Marc Valin49587512013-07-07 02:50:18 -0400613 if (st->bitrate_bps > st->layout.nb_channels*40000)
614 stream_offset = 20000;
615 else
616 stream_offset = st->bitrate_bps/st->layout.nb_channels/2;
Jean-Marc Valin87ca6c02013-11-13 22:58:10 -0500617 stream_offset += 60*(Fs/frame_size-50);
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400618 /* We start by giving each stream (coupled or uncoupled) the same bitrate.
619 This models the main saving of coupled channels over uncoupled. */
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400620 /* The LFE stream is an exception to the above and gets fewer bits. */
Jean-Marc Valin87ca6c02013-11-13 22:58:10 -0500621 lfe_offset = 3500 + 60*(Fs/frame_size-50);
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400622 /* Coupled streams get twice the mono rate after the first 20 kb/s. */
623 coupled_ratio = 512;
624 /* 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 -0400625 lfe_ratio = 32;
626
627 /* Compute bitrate allocation between streams */
628 if (st->bitrate_bps==OPUS_AUTO)
629 {
630 channel_rate = Fs+60*Fs/frame_size;
631 } else if (st->bitrate_bps==OPUS_BITRATE_MAX)
632 {
633 channel_rate = 300000;
634 } else {
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400635 int nb_lfe;
636 int nb_uncoupled;
637 int nb_coupled;
638 int total;
639 nb_lfe = (st->lfe_stream!=-1);
640 nb_coupled = st->layout.nb_coupled_streams;
641 nb_uncoupled = st->layout.nb_streams-nb_coupled-nb_lfe;
642 total = (nb_uncoupled<<8) /* mono */
643 + coupled_ratio*nb_coupled /* stereo */
644 + nb_lfe*lfe_ratio;
645 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 -0400646 }
647#ifndef FIXED_POINT
648 if (st->variable_duration==OPUS_FRAMESIZE_VARIABLE && frame_size != Fs/50)
649 {
650 opus_int32 bonus;
651 bonus = 60*(Fs/frame_size-50);
652 channel_rate += bonus;
653 }
654#endif
655
656 for (i=0;i<st->layout.nb_streams;i++)
657 {
658 if (i<st->layout.nb_coupled_streams)
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400659 rate[i] = stream_offset+(channel_rate*coupled_ratio>>8);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400660 else if (i!=st->lfe_stream)
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400661 rate[i] = stream_offset+channel_rate;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400662 else
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400663 rate[i] = lfe_offset+(channel_rate*lfe_ratio>>8);
Jean-Marc Valin8dc91de2014-06-21 01:16:46 -0400664 rate[i] = IMAX(rate[i], 500);
665 rate_sum += rate[i];
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400666 }
Jean-Marc Valin8dc91de2014-06-21 01:16:46 -0400667 return rate_sum;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400668}
669
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500670/* Max size in case the encoder decides to return three frames */
671#define MS_FRAME_TMP (3*1275+7)
672static int opus_multistream_encode_native
673(
674 OpusMSEncoder *st,
675 opus_copy_channel_in_func copy_channel_in,
676 const void *pcm,
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -0400677 int analysis_frame_size,
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500678 unsigned char *data,
Jean-Marc Valinb3eba242012-12-20 23:11:53 -0500679 opus_int32 max_data_bytes,
Jean-Marc Valin91904a42013-09-05 21:34:43 -0400680 int lsb_depth,
Jean-Marc Valinc94e4bb2013-12-08 03:31:50 -0500681 downmix_func downmix,
682 int float_api
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500683)
684{
685 opus_int32 Fs;
686 int coupled_size;
687 int mono_size;
688 int s;
689 char *ptr;
690 int tot_size;
691 VARDECL(opus_val16, buf);
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400692 VARDECL(opus_val16, bandSMR);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500693 unsigned char tmp_data[MS_FRAME_TMP];
694 OpusRepacketizer rp;
Jean-Marc Valineab134c2013-10-14 15:01:36 -0400695 opus_int32 vbr;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500696 const CELTMode *celt_mode;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400697 opus_int32 bitrates[256];
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400698 opus_val16 bandLogE[42];
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400699 opus_val32 *mem = NULL;
700 opus_val32 *preemph_mem=NULL;
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -0400701 int frame_size;
Jean-Marc Valin8dc91de2014-06-21 01:16:46 -0400702 opus_int32 rate_sum;
703 opus_int32 smallest_packet;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500704 ALLOC_STACK;
705
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400706 if (st->surround)
707 {
708 preemph_mem = ms_get_preemph_mem(st);
709 mem = ms_get_window_mem(st);
710 }
711
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500712 ptr = (char*)st + align(sizeof(OpusMSEncoder));
713 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
Jean-Marc Valineab134c2013-10-14 15:01:36 -0400714 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_VBR(&vbr));
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500715 opus_encoder_ctl((OpusEncoder*)ptr, CELT_GET_MODE(&celt_mode));
Jean-Marc Valin74483662012-12-17 16:23:42 -0500716
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -0400717 {
718 opus_int32 delay_compensation;
719 int channels;
720
721 channels = st->layout.nb_streams + st->layout.nb_coupled_streams;
722 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_LOOKAHEAD(&delay_compensation));
723 delay_compensation -= Fs/400;
724 frame_size = compute_frame_size(pcm, analysis_frame_size,
725 st->variable_duration, channels, Fs, st->bitrate_bps,
Jean-Marc Valinc2b34412013-10-28 21:48:50 -0400726 delay_compensation, downmix
727#ifndef DISABLE_FLOAT_API
728 , st->subframe_mem
729#endif
730 );
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -0400731 }
732
Jean-Marc Valin74483662012-12-17 16:23:42 -0500733 if (400*frame_size < Fs)
734 {
735 RESTORE_STACK;
736 return OPUS_BAD_ARG;
737 }
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500738 /* Validate frame_size before using it to allocate stack space.
739 This mirrors the checks in opus_encode[_float](). */
740 if (400*frame_size != Fs && 200*frame_size != Fs &&
741 100*frame_size != Fs && 50*frame_size != Fs &&
742 25*frame_size != Fs && 50*frame_size != 3*Fs)
743 {
744 RESTORE_STACK;
745 return OPUS_BAD_ARG;
746 }
Jean-Marc Valin8dc91de2014-06-21 01:16:46 -0400747 /* Estimate (slightly overestimating) of the smallest packet the encoder can produce. */
748 if (50*frame_size <= Fs)
749 {
750 smallest_packet = st->layout.nb_streams*4;
751 } else {
752 smallest_packet = st->layout.nb_streams*4*50*frame_size/Fs;
753 }
754 if (max_data_bytes < smallest_packet)
755 {
756 RESTORE_STACK;
757 return OPUS_BAD_ARG;
758 }
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500759 ALLOC(buf, 2*frame_size, opus_val16);
760 coupled_size = opus_encoder_get_size(2);
761 mono_size = opus_encoder_get_size(1);
762
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400763 ALLOC(bandSMR, 21*st->layout.nb_channels, opus_val16);
Jean-Marc Valin58d80ab2013-05-27 20:47:47 -0400764 if (st->surround)
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400765 {
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400766 surround_analysis(celt_mode, pcm, bandSMR, mem, preemph_mem, frame_size, 120, st->layout.nb_channels, Fs, copy_channel_in);
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400767 }
768
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500769 if (max_data_bytes < 4*st->layout.nb_streams-1)
770 {
771 RESTORE_STACK;
772 return OPUS_BUFFER_TOO_SMALL;
773 }
Jean-Marc Valin74483662012-12-17 16:23:42 -0500774
775 /* Compute bitrate allocation between streams (this could be a lot better) */
Jean-Marc Valin8dc91de2014-06-21 01:16:46 -0400776 rate_sum = surround_rate_allocation(st, bitrates, frame_size);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400777
Jean-Marc Valineab134c2013-10-14 15:01:36 -0400778 if (!vbr)
Jean-Marc Valin8dc91de2014-06-21 01:16:46 -0400779 {
780 if (st->bitrate_bps == OPUS_AUTO)
781 {
782 max_data_bytes = IMIN(max_data_bytes, 3*rate_sum/(3*8*Fs/frame_size));
783 } else if (st->bitrate_bps != OPUS_BITRATE_MAX)
784 {
785 max_data_bytes = IMIN(max_data_bytes, IMAX(smallest_packet,
786 3*st->bitrate_bps/(3*8*Fs/frame_size)));
787 }
788 }
Jean-Marc Valin74483662012-12-17 16:23:42 -0500789 ptr = (char*)st + align(sizeof(OpusMSEncoder));
790 for (s=0;s<st->layout.nb_streams;s++)
791 {
792 OpusEncoder *enc;
793 enc = (OpusEncoder*)ptr;
794 if (s < st->layout.nb_coupled_streams)
795 ptr += align(coupled_size);
796 else
797 ptr += align(mono_size);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400798 opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrates[s]));
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400799 if (st->surround)
800 {
Jean-Marc Valin6fbfed62013-09-13 17:16:38 -0400801 opus_int32 equiv_rate;
802 equiv_rate = st->bitrate_bps;
803 if (frame_size*50 < Fs)
804 equiv_rate -= 60*(Fs/frame_size - 50)*st->layout.nb_channels;
Jean-Marc Valinccf7d9b2013-11-24 01:57:52 -0500805 if (equiv_rate > 10000*st->layout.nb_channels)
Jean-Marc Valin6fbfed62013-09-13 17:16:38 -0400806 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
Jean-Marc Valinccf7d9b2013-11-24 01:57:52 -0500807 else if (equiv_rate > 7000*st->layout.nb_channels)
Jean-Marc Valin6fbfed62013-09-13 17:16:38 -0400808 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_SUPERWIDEBAND));
Jean-Marc Valinccf7d9b2013-11-24 01:57:52 -0500809 else if (equiv_rate > 5000*st->layout.nb_channels)
Jean-Marc Valin6fbfed62013-09-13 17:16:38 -0400810 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_WIDEBAND));
811 else
812 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND));
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400813 if (s < st->layout.nb_coupled_streams)
Jean-Marc Valin8824fdb2013-09-10 01:15:19 -0400814 {
815 /* To preserve the spatial image, force stereo CELT on coupled streams */
816 opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY));
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400817 opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(2));
Jean-Marc Valin8824fdb2013-09-10 01:15:19 -0400818 }
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400819 }
Jean-Marc Valin74483662012-12-17 16:23:42 -0500820 }
821
822 ptr = (char*)st + align(sizeof(OpusMSEncoder));
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500823 /* Counting ToC */
824 tot_size = 0;
825 for (s=0;s<st->layout.nb_streams;s++)
826 {
827 OpusEncoder *enc;
828 int len;
829 int curr_max;
Jean-Marc Valin91904a42013-09-05 21:34:43 -0400830 int c1, c2;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500831
832 opus_repacketizer_init(&rp);
833 enc = (OpusEncoder*)ptr;
834 if (s < st->layout.nb_coupled_streams)
835 {
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400836 int i;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500837 int left, right;
838 left = get_left_channel(&st->layout, s, -1);
839 right = get_right_channel(&st->layout, s, -1);
840 (*copy_channel_in)(buf, 2,
841 pcm, st->layout.nb_channels, left, frame_size);
842 (*copy_channel_in)(buf+1, 2,
843 pcm, st->layout.nb_channels, right, frame_size);
844 ptr += align(coupled_size);
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400845 if (st->surround)
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400846 {
847 for (i=0;i<21;i++)
848 {
849 bandLogE[i] = bandSMR[21*left+i];
850 bandLogE[21+i] = bandSMR[21*right+i];
851 }
852 }
Jean-Marc Valin91904a42013-09-05 21:34:43 -0400853 c1 = left;
854 c2 = right;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500855 } else {
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400856 int i;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500857 int chan = get_mono_channel(&st->layout, s, -1);
858 (*copy_channel_in)(buf, 1,
859 pcm, st->layout.nb_channels, chan, frame_size);
860 ptr += align(mono_size);
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400861 if (st->surround)
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400862 {
863 for (i=0;i<21;i++)
864 bandLogE[i] = bandSMR[21*chan+i];
865 }
Jean-Marc Valin91904a42013-09-05 21:34:43 -0400866 c1 = chan;
867 c2 = -1;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500868 }
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400869 if (st->surround)
870 opus_encoder_ctl(enc, OPUS_SET_ENERGY_MASK(bandLogE));
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500871 /* number of bytes left (+Toc) */
872 curr_max = max_data_bytes - tot_size;
873 /* Reserve three bytes for the last stream and four for the others */
874 curr_max -= IMAX(0,4*(st->layout.nb_streams-s-1)-1);
875 curr_max = IMIN(curr_max,MS_FRAME_TMP);
Jean-Marc Valin2e653a72013-10-14 17:47:18 -0400876 if (!vbr && s == st->layout.nb_streams-1)
877 opus_encoder_ctl(enc, OPUS_SET_BITRATE(curr_max*(8*Fs/frame_size)));
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -0400878 len = opus_encode_native(enc, buf, frame_size, tmp_data, curr_max, lsb_depth,
Jean-Marc Valinc94e4bb2013-12-08 03:31:50 -0500879 pcm, analysis_frame_size, c1, c2, st->layout.nb_channels, downmix, float_api);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500880 if (len<0)
881 {
882 RESTORE_STACK;
883 return len;
884 }
885 /* We need to use the repacketizer to add the self-delimiting lengths
886 while taking into account the fact that the encoder can now return
887 more than one frame at a time (e.g. 60 ms CELT-only) */
888 opus_repacketizer_cat(&rp, tmp_data, len);
Jean-Marc Valinc5635d22013-11-13 14:08:22 -0500889 len = opus_repacketizer_out_range_impl(&rp, 0, opus_repacketizer_get_nb_frames(&rp),
890 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 -0500891 data += len;
892 tot_size += len;
893 }
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400894 /*printf("\n");*/
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500895 RESTORE_STACK;
896 return tot_size;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500897}
898
Pedro Becerra1af7f952013-07-11 00:00:47 -0400899#if !defined(DISABLE_FLOAT_API)
900static void opus_copy_channel_in_float(
901 opus_val16 *dst,
902 int dst_stride,
903 const void *src,
904 int src_stride,
905 int src_channel,
906 int frame_size
907)
908{
909 const float *float_src;
910 opus_int32 i;
911 float_src = (const float *)src;
912 for (i=0;i<frame_size;i++)
913#if defined(FIXED_POINT)
914 dst[i*dst_stride] = FLOAT2INT16(float_src[i*src_stride+src_channel]);
915#else
916 dst[i*dst_stride] = float_src[i*src_stride+src_channel];
917#endif
918}
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500919#endif
920
921static void opus_copy_channel_in_short(
922 opus_val16 *dst,
923 int dst_stride,
924 const void *src,
925 int src_stride,
926 int src_channel,
927 int frame_size
928)
929{
930 const opus_int16 *short_src;
Timothy B. Terriberrya8f04b22013-03-18 14:42:44 -0700931 opus_int32 i;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500932 short_src = (const opus_int16 *)src;
933 for (i=0;i<frame_size;i++)
934#if defined(FIXED_POINT)
935 dst[i*dst_stride] = short_src[i*src_stride+src_channel];
936#else
937 dst[i*dst_stride] = (1/32768.f)*short_src[i*src_stride+src_channel];
938#endif
939}
940
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400941
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500942#ifdef FIXED_POINT
943int opus_multistream_encode(
944 OpusMSEncoder *st,
945 const opus_val16 *pcm,
946 int frame_size,
947 unsigned char *data,
948 opus_int32 max_data_bytes
949)
950{
951 return opus_multistream_encode_native(st, opus_copy_channel_in_short,
Jean-Marc Valinc94e4bb2013-12-08 03:31:50 -0500952 pcm, frame_size, data, max_data_bytes, 16, downmix_int, 0);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500953}
954
955#ifndef DISABLE_FLOAT_API
956int opus_multistream_encode_float(
957 OpusMSEncoder *st,
958 const float *pcm,
959 int frame_size,
960 unsigned char *data,
961 opus_int32 max_data_bytes
962)
963{
964 return opus_multistream_encode_native(st, opus_copy_channel_in_float,
Jean-Marc Valinc94e4bb2013-12-08 03:31:50 -0500965 pcm, frame_size, data, max_data_bytes, 16, downmix_float, 1);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500966}
967#endif
968
969#else
970
971int opus_multistream_encode_float
972(
973 OpusMSEncoder *st,
974 const opus_val16 *pcm,
975 int frame_size,
976 unsigned char *data,
977 opus_int32 max_data_bytes
978)
979{
980 return opus_multistream_encode_native(st, opus_copy_channel_in_float,
Jean-Marc Valinc94e4bb2013-12-08 03:31:50 -0500981 pcm, frame_size, data, max_data_bytes, 24, downmix_float, 1);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500982}
983
984int opus_multistream_encode(
985 OpusMSEncoder *st,
986 const opus_int16 *pcm,
987 int frame_size,
988 unsigned char *data,
989 opus_int32 max_data_bytes
990)
991{
992 return opus_multistream_encode_native(st, opus_copy_channel_in_short,
Jean-Marc Valinc94e4bb2013-12-08 03:31:50 -0500993 pcm, frame_size, data, max_data_bytes, 16, downmix_int, 0);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500994}
995#endif
996
997int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
998{
999 va_list ap;
1000 int coupled_size, mono_size;
1001 char *ptr;
1002 int ret = OPUS_OK;
1003
1004 va_start(ap, request);
1005
1006 coupled_size = opus_encoder_get_size(2);
1007 mono_size = opus_encoder_get_size(1);
1008 ptr = (char*)st + align(sizeof(OpusMSEncoder));
1009 switch (request)
1010 {
1011 case OPUS_SET_BITRATE_REQUEST:
1012 {
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001013 opus_int32 value = va_arg(ap, opus_int32);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07001014 if (value<0 && value!=OPUS_AUTO && value!=OPUS_BITRATE_MAX)
1015 {
Jean-Marc Valin95561be2012-12-17 17:54:01 -05001016 goto bad_arg;
Gregory Maxwellb271dae2013-06-29 20:25:55 -07001017 }
Jean-Marc Valin74483662012-12-17 16:23:42 -05001018 st->bitrate_bps = value;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001019 }
1020 break;
1021 case OPUS_GET_BITRATE_REQUEST:
1022 {
1023 int s;
1024 opus_int32 *value = va_arg(ap, opus_int32*);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07001025 if (!value)
1026 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07001027 goto bad_arg;
1028 }
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001029 *value = 0;
1030 for (s=0;s<st->layout.nb_streams;s++)
1031 {
1032 opus_int32 rate;
1033 OpusEncoder *enc;
1034 enc = (OpusEncoder*)ptr;
1035 if (s < st->layout.nb_coupled_streams)
1036 ptr += align(coupled_size);
1037 else
1038 ptr += align(mono_size);
1039 opus_encoder_ctl(enc, request, &rate);
1040 *value += rate;
1041 }
1042 }
1043 break;
1044 case OPUS_GET_LSB_DEPTH_REQUEST:
1045 case OPUS_GET_VBR_REQUEST:
1046 case OPUS_GET_APPLICATION_REQUEST:
1047 case OPUS_GET_BANDWIDTH_REQUEST:
1048 case OPUS_GET_COMPLEXITY_REQUEST:
1049 case OPUS_GET_PACKET_LOSS_PERC_REQUEST:
1050 case OPUS_GET_DTX_REQUEST:
1051 case OPUS_GET_VOICE_RATIO_REQUEST:
1052 case OPUS_GET_VBR_CONSTRAINT_REQUEST:
1053 case OPUS_GET_SIGNAL_REQUEST:
1054 case OPUS_GET_LOOKAHEAD_REQUEST:
1055 case OPUS_GET_SAMPLE_RATE_REQUEST:
1056 case OPUS_GET_INBAND_FEC_REQUEST:
1057 case OPUS_GET_FORCE_CHANNELS_REQUEST:
Jean-Marc Valincbe93e22013-11-15 13:50:38 -05001058 case OPUS_GET_PREDICTION_DISABLED_REQUEST:
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001059 {
1060 OpusEncoder *enc;
1061 /* For int32* GET params, just query the first stream */
1062 opus_int32 *value = va_arg(ap, opus_int32*);
1063 enc = (OpusEncoder*)ptr;
1064 ret = opus_encoder_ctl(enc, request, value);
1065 }
1066 break;
1067 case OPUS_GET_FINAL_RANGE_REQUEST:
1068 {
1069 int s;
1070 opus_uint32 *value = va_arg(ap, opus_uint32*);
1071 opus_uint32 tmp;
Gregory Maxwella0d096f2013-06-29 20:33:32 -07001072 if (!value)
1073 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07001074 goto bad_arg;
1075 }
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001076 *value=0;
1077 for (s=0;s<st->layout.nb_streams;s++)
1078 {
1079 OpusEncoder *enc;
1080 enc = (OpusEncoder*)ptr;
1081 if (s < st->layout.nb_coupled_streams)
1082 ptr += align(coupled_size);
1083 else
1084 ptr += align(mono_size);
1085 ret = opus_encoder_ctl(enc, request, &tmp);
1086 if (ret != OPUS_OK) break;
1087 *value ^= tmp;
1088 }
1089 }
1090 break;
1091 case OPUS_SET_LSB_DEPTH_REQUEST:
1092 case OPUS_SET_COMPLEXITY_REQUEST:
1093 case OPUS_SET_VBR_REQUEST:
1094 case OPUS_SET_VBR_CONSTRAINT_REQUEST:
Daniel Jensenc0c0ef62013-07-22 16:31:31 -06001095 case OPUS_SET_MAX_BANDWIDTH_REQUEST:
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001096 case OPUS_SET_BANDWIDTH_REQUEST:
1097 case OPUS_SET_SIGNAL_REQUEST:
1098 case OPUS_SET_APPLICATION_REQUEST:
1099 case OPUS_SET_INBAND_FEC_REQUEST:
1100 case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
1101 case OPUS_SET_DTX_REQUEST:
1102 case OPUS_SET_FORCE_MODE_REQUEST:
1103 case OPUS_SET_FORCE_CHANNELS_REQUEST:
Jean-Marc Valincbe93e22013-11-15 13:50:38 -05001104 case OPUS_SET_PREDICTION_DISABLED_REQUEST:
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001105 {
1106 int s;
1107 /* This works for int32 params */
1108 opus_int32 value = va_arg(ap, opus_int32);
1109 for (s=0;s<st->layout.nb_streams;s++)
1110 {
1111 OpusEncoder *enc;
1112
1113 enc = (OpusEncoder*)ptr;
1114 if (s < st->layout.nb_coupled_streams)
1115 ptr += align(coupled_size);
1116 else
1117 ptr += align(mono_size);
1118 ret = opus_encoder_ctl(enc, request, value);
1119 if (ret != OPUS_OK)
1120 break;
1121 }
1122 }
1123 break;
1124 case OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST:
1125 {
1126 int s;
1127 opus_int32 stream_id;
1128 OpusEncoder **value;
1129 stream_id = va_arg(ap, opus_int32);
1130 if (stream_id<0 || stream_id >= st->layout.nb_streams)
1131 ret = OPUS_BAD_ARG;
1132 value = va_arg(ap, OpusEncoder**);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07001133 if (!value)
1134 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07001135 goto bad_arg;
1136 }
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001137 for (s=0;s<stream_id;s++)
1138 {
1139 if (s < st->layout.nb_coupled_streams)
1140 ptr += align(coupled_size);
1141 else
1142 ptr += align(mono_size);
1143 }
1144 *value = (OpusEncoder*)ptr;
1145 }
Jean-Marc Valin74483662012-12-17 16:23:42 -05001146 break;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -05001147 case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST:
Jean-Marc Valin74483662012-12-17 16:23:42 -05001148 {
1149 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin74483662012-12-17 16:23:42 -05001150 st->variable_duration = value;
1151 }
1152 break;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -05001153 case OPUS_GET_EXPERT_FRAME_DURATION_REQUEST:
Jean-Marc Valin74483662012-12-17 16:23:42 -05001154 {
1155 opus_int32 *value = va_arg(ap, opus_int32*);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07001156 if (!value)
1157 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07001158 goto bad_arg;
1159 }
Jean-Marc Valin74483662012-12-17 16:23:42 -05001160 *value = st->variable_duration;
1161 }
1162 break;
Jean-Marc Valin811db622013-10-28 16:11:53 -04001163 case OPUS_RESET_STATE:
1164 {
1165 int s;
1166 st->subframe_mem[0] = st->subframe_mem[1] = st->subframe_mem[2] = 0;
1167 if (st->surround)
1168 {
1169 OPUS_CLEAR(ms_get_preemph_mem(st), st->layout.nb_channels);
1170 OPUS_CLEAR(ms_get_window_mem(st), st->layout.nb_channels*120);
1171 }
1172 for (s=0;s<st->layout.nb_streams;s++)
1173 {
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 ret = opus_encoder_ctl(enc, OPUS_RESET_STATE);
1181 if (ret != OPUS_OK)
1182 break;
1183 }
1184 }
1185 break;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001186 default:
1187 ret = OPUS_UNIMPLEMENTED;
1188 break;
1189 }
1190
1191 va_end(ap);
1192 return ret;
Jean-Marc Valin74483662012-12-17 16:23:42 -05001193bad_arg:
1194 va_end(ap);
1195 return OPUS_BAD_ARG;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001196}
1197
1198void opus_multistream_encoder_destroy(OpusMSEncoder *st)
1199{
1200 opus_free(st);
1201}