blob: 7163d1444e44e32f23a0c61d9ee1fed41e20309c [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 }
Mark Harris4feb0df2015-08-07 01:24:48 -0700101 /* void* cast avoids clang -Wcast-align warning */
102 return (opus_val32*)(void*)(ptr+st->layout.nb_channels*120*sizeof(opus_val32));
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400103}
104
105static opus_val32 *ms_get_window_mem(OpusMSEncoder *st)
106{
107 int s;
108 char *ptr;
109 int coupled_size, mono_size;
110
111 coupled_size = opus_encoder_get_size(2);
112 mono_size = opus_encoder_get_size(1);
113 ptr = (char*)st + align(sizeof(OpusMSEncoder));
114 for (s=0;s<st->layout.nb_streams;s++)
115 {
116 if (s < st->layout.nb_coupled_streams)
117 ptr += align(coupled_size);
118 else
119 ptr += align(mono_size);
120 }
Mark Harris4feb0df2015-08-07 01:24:48 -0700121 /* void* cast avoids clang -Wcast-align warning */
122 return (opus_val32*)(void*)ptr;
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400123}
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500124
125static int validate_encoder_layout(const ChannelLayout *layout)
126{
127 int s;
128 for (s=0;s<layout->nb_streams;s++)
129 {
130 if (s < layout->nb_coupled_streams)
131 {
132 if (get_left_channel(layout, s, -1)==-1)
133 return 0;
134 if (get_right_channel(layout, s, -1)==-1)
135 return 0;
136 } else {
137 if (get_mono_channel(layout, s, -1)==-1)
138 return 0;
139 }
140 }
141 return 1;
142}
143
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400144static void channel_pos(int channels, int pos[8])
145{
146 /* Position in the mix: 0 don't mix, 1: left, 2: center, 3:right */
147 if (channels==4)
148 {
149 pos[0]=1;
150 pos[1]=3;
151 pos[2]=1;
152 pos[3]=3;
153 } else if (channels==3||channels==5||channels==6)
154 {
155 pos[0]=1;
156 pos[1]=2;
157 pos[2]=3;
158 pos[3]=1;
159 pos[4]=3;
160 pos[5]=0;
161 } else if (channels==7)
162 {
163 pos[0]=1;
164 pos[1]=2;
165 pos[2]=3;
166 pos[3]=1;
167 pos[4]=3;
168 pos[5]=2;
169 pos[6]=0;
170 } else if (channels==8)
171 {
172 pos[0]=1;
173 pos[1]=2;
174 pos[2]=3;
175 pos[3]=1;
176 pos[4]=3;
177 pos[5]=1;
178 pos[6]=3;
179 pos[7]=0;
180 }
181}
182
Jean-Marc Valina714ae92013-08-31 02:05:32 -0400183#if 1
184/* Computes a rough approximation of log2(2^a + 2^b) */
185static opus_val16 logSum(opus_val16 a, opus_val16 b)
186{
187 opus_val16 max;
188 opus_val32 diff;
189 opus_val16 frac;
190 static const opus_val16 diff_table[17] = {
191 QCONST16(0.5000000f, DB_SHIFT), QCONST16(0.2924813f, DB_SHIFT), QCONST16(0.1609640f, DB_SHIFT), QCONST16(0.0849625f, DB_SHIFT),
192 QCONST16(0.0437314f, DB_SHIFT), QCONST16(0.0221971f, DB_SHIFT), QCONST16(0.0111839f, DB_SHIFT), QCONST16(0.0056136f, DB_SHIFT),
193 QCONST16(0.0028123f, DB_SHIFT)
194 };
195 int low;
196 if (a>b)
197 {
198 max = a;
199 diff = SUB32(EXTEND32(a),EXTEND32(b));
200 } else {
201 max = b;
202 diff = SUB32(EXTEND32(b),EXTEND32(a));
203 }
204 if (diff >= QCONST16(8.f, DB_SHIFT))
205 return max;
206#ifdef FIXED_POINT
207 low = SHR32(diff, DB_SHIFT-1);
208 frac = SHL16(diff - SHL16(low, DB_SHIFT-1), 16-DB_SHIFT);
209#else
Jean-Marc Valina71c9ad2013-11-13 12:07:01 -0500210 low = (int)floor(2*diff);
Jean-Marc Valina714ae92013-08-31 02:05:32 -0400211 frac = 2*diff - low;
212#endif
213 return max + diff_table[low] + MULT16_16_Q15(frac, SUB16(diff_table[low+1], diff_table[low]));
214}
215#else
216opus_val16 logSum(opus_val16 a, opus_val16 b)
217{
218 return log2(pow(4, a)+ pow(4, b))/2;
219}
220#endif
221
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400222void surround_analysis(const CELTMode *celt_mode, const void *pcm, opus_val16 *bandLogE, opus_val32 *mem, opus_val32 *preemph_mem,
223 int len, int overlap, int channels, int rate, opus_copy_channel_in_func copy_channel_in
224)
225{
226 int c;
227 int i;
Jean-Marc Valin54bddf02013-09-11 23:34:51 -0400228 int LM;
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400229 int pos[8] = {0};
230 int upsample;
Jean-Marc Valin978e4cb2013-09-11 00:51:22 -0400231 int frame_size;
Jean-Marc Valin942fc812013-10-01 19:27:30 -0400232 opus_val16 channel_offset;
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400233 opus_val32 bandE[21];
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400234 opus_val16 maskLogE[3][21];
235 VARDECL(opus_val32, in);
236 VARDECL(opus_val16, x);
Jean-Marc Valine8e5ecb2013-10-01 17:16:33 -0400237 VARDECL(opus_val32, freq);
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400238 SAVE_STACK;
Jean-Marc Valin978e4cb2013-09-11 00:51:22 -0400239
240 upsample = resampling_factor(rate);
241 frame_size = len*upsample;
242
Jean-Marc Valin2e653a72013-10-14 17:47:18 -0400243 for (LM=0;LM<celt_mode->maxLM;LM++)
Jean-Marc Valin54bddf02013-09-11 23:34:51 -0400244 if (celt_mode->shortMdctSize<<LM==frame_size)
245 break;
246
Jean-Marc Valin978e4cb2013-09-11 00:51:22 -0400247 ALLOC(in, frame_size+overlap, opus_val32);
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400248 ALLOC(x, len, opus_val16);
Jean-Marc Valin978e4cb2013-09-11 00:51:22 -0400249 ALLOC(freq, frame_size, opus_val32);
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400250
251 channel_pos(channels, pos);
252
Jean-Marc Valina714ae92013-08-31 02:05:32 -0400253 for (c=0;c<3;c++)
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400254 for (i=0;i<21;i++)
Jean-Marc Valina714ae92013-08-31 02:05:32 -0400255 maskLogE[c][i] = -QCONST16(28.f, DB_SHIFT);
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400256
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400257 for (c=0;c<channels;c++)
258 {
259 OPUS_COPY(in, mem+c*overlap, overlap);
260 (*copy_channel_in)(x, 1, pcm, channels, c, len);
Jean-Marc Valin2dc27df2013-11-13 19:35:43 -0500261 celt_preemphasis(x, in+overlap, frame_size, 1, upsample, celt_mode->preemph, preemph_mem+c, 0);
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400262 clt_mdct_forward(&celt_mode->mdct, in, freq, celt_mode->window, overlap, celt_mode->maxLM-LM, 1);
263 if (upsample != 1)
264 {
Jean-Marc Valin978e4cb2013-09-11 00:51:22 -0400265 int bound = len;
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400266 for (i=0;i<bound;i++)
267 freq[i] *= upsample;
Jean-Marc Valin978e4cb2013-09-11 00:51:22 -0400268 for (;i<frame_size;i++)
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400269 freq[i] = 0;
270 }
271
Mark Harris58107d82014-01-25 16:32:18 -0800272 compute_band_energies(celt_mode, freq, bandE, 21, 1, LM);
Jean-Marc Valina714ae92013-08-31 02:05:32 -0400273 amp2Log2(celt_mode, 21, 21, bandE, bandLogE+21*c, 1);
Jean-Marc Valin0f686962013-09-05 12:49:55 -0400274 /* Apply spreading function with -6 dB/band going up and -12 dB/band going down. */
275 for (i=1;i<21;i++)
276 bandLogE[21*c+i] = MAX16(bandLogE[21*c+i], bandLogE[21*c+i-1]-QCONST16(1.f, DB_SHIFT));
277 for (i=19;i>=0;i--)
278 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 -0400279 if (pos[c]==1)
280 {
281 for (i=0;i<21;i++)
Jean-Marc Valina714ae92013-08-31 02:05:32 -0400282 maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]);
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400283 } else if (pos[c]==3)
284 {
285 for (i=0;i<21;i++)
Jean-Marc Valina714ae92013-08-31 02:05:32 -0400286 maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]);
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400287 } else if (pos[c]==2)
288 {
289 for (i=0;i<21;i++)
290 {
Jean-Marc Valina714ae92013-08-31 02:05:32 -0400291 maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]-QCONST16(.5f, DB_SHIFT));
292 maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]-QCONST16(.5f, DB_SHIFT));
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400293 }
294 }
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400295#if 0
296 for (i=0;i<21;i++)
297 printf("%f ", bandLogE[21*c+i]);
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400298 float sum=0;
299 for (i=0;i<21;i++)
300 sum += bandLogE[21*c+i];
301 printf("%f ", sum/21);
302#endif
Jean-Marc Valin978e4cb2013-09-11 00:51:22 -0400303 OPUS_COPY(mem+c*overlap, in+frame_size, overlap);
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400304 }
305 for (i=0;i<21;i++)
Jean-Marc Valina714ae92013-08-31 02:05:32 -0400306 maskLogE[1][i] = MIN32(maskLogE[0][i],maskLogE[2][i]);
Jean-Marc Valin942fc812013-10-01 19:27:30 -0400307 channel_offset = HALF16(celt_log2(QCONST32(2.f,14)/(channels-1)));
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400308 for (c=0;c<3;c++)
309 for (i=0;i<21;i++)
Jean-Marc Valin942fc812013-10-01 19:27:30 -0400310 maskLogE[c][i] += channel_offset;
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400311#if 0
312 for (c=0;c<3;c++)
313 {
314 for (i=0;i<21;i++)
315 printf("%f ", maskLogE[c][i]);
316 }
317#endif
318 for (c=0;c<channels;c++)
319 {
320 opus_val16 *mask;
321 if (pos[c]!=0)
322 {
323 mask = &maskLogE[pos[c]-1][0];
324 for (i=0;i<21;i++)
325 bandLogE[21*c+i] = bandLogE[21*c+i] - mask[i];
326 } else {
327 for (i=0;i<21;i++)
328 bandLogE[21*c+i] = 0;
329 }
330#if 0
331 for (i=0;i<21;i++)
332 printf("%f ", bandLogE[21*c+i]);
333 printf("\n");
334#endif
335#if 0
336 float sum=0;
337 for (i=0;i<21;i++)
338 sum += bandLogE[21*c+i];
Jean-Marc Valin942fc812013-10-01 19:27:30 -0400339 printf("%f ", sum/(float)QCONST32(21.f, DB_SHIFT));
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400340 printf("\n");
341#endif
342 }
343 RESTORE_STACK;
344}
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500345
346opus_int32 opus_multistream_encoder_get_size(int nb_streams, int nb_coupled_streams)
347{
348 int coupled_size;
349 int mono_size;
350
351 if(nb_streams<1||nb_coupled_streams>nb_streams||nb_coupled_streams<0)return 0;
352 coupled_size = opus_encoder_get_size(2);
353 mono_size = opus_encoder_get_size(1);
354 return align(sizeof(OpusMSEncoder))
355 + nb_coupled_streams * align(coupled_size)
356 + (nb_streams-nb_coupled_streams) * align(mono_size);
357}
358
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400359opus_int32 opus_multistream_surround_encoder_get_size(int channels, int mapping_family)
360{
361 int nb_streams;
362 int nb_coupled_streams;
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400363 opus_int32 size;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400364
Jean-Marc Valin7a8b1392013-04-29 18:32:27 -0400365 if (mapping_family==0)
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400366 {
Jean-Marc Valin7a8b1392013-04-29 18:32:27 -0400367 if (channels==1)
368 {
369 nb_streams=1;
370 nb_coupled_streams=0;
371 } else if (channels==2)
372 {
373 nb_streams=1;
374 nb_coupled_streams=1;
375 } else
376 return 0;
377 } else if (mapping_family==1 && channels<=8 && channels>=1)
378 {
379 nb_streams=vorbis_mappings[channels-1].nb_streams;
380 nb_coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams;
381 } else if (mapping_family==255)
382 {
383 nb_streams=channels;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400384 nb_coupled_streams=0;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400385 } else
386 return 0;
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400387 size = opus_multistream_encoder_get_size(nb_streams, nb_coupled_streams);
388 if (channels>2)
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400389 {
390 size += channels*(120*sizeof(opus_val32) + sizeof(opus_val32));
391 }
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400392 return size;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400393}
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500394
395
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400396static int opus_multistream_encoder_init_impl(
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500397 OpusMSEncoder *st,
398 opus_int32 Fs,
399 int channels,
400 int streams,
401 int coupled_streams,
402 const unsigned char *mapping,
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400403 int application,
404 int surround
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500405)
406{
407 int coupled_size;
408 int mono_size;
409 int i, ret;
410 char *ptr;
411
412 if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
Mark Harris25b27a92014-11-27 08:48:09 -0800413 (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams))
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500414 return OPUS_BAD_ARG;
415
416 st->layout.nb_channels = channels;
417 st->layout.nb_streams = streams;
418 st->layout.nb_coupled_streams = coupled_streams;
Jean-Marc Valinb0429352013-05-05 02:22:06 -0400419 st->subframe_mem[0]=st->subframe_mem[1]=st->subframe_mem[2]=0;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400420 if (!surround)
421 st->lfe_stream = -1;
Jean-Marc Valin95561be2012-12-17 17:54:01 -0500422 st->bitrate_bps = OPUS_AUTO;
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -0400423 st->application = application;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500424 st->variable_duration = OPUS_FRAMESIZE_ARG;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500425 for (i=0;i<st->layout.nb_channels;i++)
426 st->layout.mapping[i] = mapping[i];
427 if (!validate_layout(&st->layout) || !validate_encoder_layout(&st->layout))
428 return OPUS_BAD_ARG;
429 ptr = (char*)st + align(sizeof(OpusMSEncoder));
430 coupled_size = opus_encoder_get_size(2);
431 mono_size = opus_encoder_get_size(1);
432
433 for (i=0;i<st->layout.nb_coupled_streams;i++)
434 {
435 ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 2, application);
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400436 if(ret!=OPUS_OK)return ret;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400437 if (i==st->lfe_stream)
438 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1));
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500439 ptr += align(coupled_size);
440 }
441 for (;i<st->layout.nb_streams;i++)
442 {
443 ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 1, application);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400444 if (i==st->lfe_stream)
445 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1));
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500446 if(ret!=OPUS_OK)return ret;
447 ptr += align(mono_size);
448 }
Jean-Marc Valin58d80ab2013-05-27 20:47:47 -0400449 if (surround)
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400450 {
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400451 OPUS_CLEAR(ms_get_preemph_mem(st), channels);
452 OPUS_CLEAR(ms_get_window_mem(st), channels*120);
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400453 }
454 st->surround = surround;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500455 return OPUS_OK;
456}
457
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400458int opus_multistream_encoder_init(
459 OpusMSEncoder *st,
460 opus_int32 Fs,
461 int channels,
462 int streams,
463 int coupled_streams,
464 const unsigned char *mapping,
465 int application
466)
467{
468 return opus_multistream_encoder_init_impl(st, Fs, channels, streams, coupled_streams, mapping, application, 0);
469}
470
471int opus_multistream_surround_encoder_init(
472 OpusMSEncoder *st,
473 opus_int32 Fs,
474 int channels,
475 int mapping_family,
476 int *streams,
477 int *coupled_streams,
478 unsigned char *mapping,
479 int application
480)
481{
Jean-Marc Valin337f34c2013-07-01 16:17:01 -0400482 if ((channels>255) || (channels<1))
483 return OPUS_BAD_ARG;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400484 st->lfe_stream = -1;
Jean-Marc Valin7a8b1392013-04-29 18:32:27 -0400485 if (mapping_family==0)
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400486 {
Jean-Marc Valin7a8b1392013-04-29 18:32:27 -0400487 if (channels==1)
488 {
489 *streams=1;
490 *coupled_streams=0;
491 mapping[0]=0;
492 } else if (channels==2)
493 {
494 *streams=1;
495 *coupled_streams=1;
496 mapping[0]=0;
497 mapping[1]=1;
498 } else
499 return OPUS_UNIMPLEMENTED;
500 } else if (mapping_family==1 && channels<=8 && channels>=1)
501 {
502 int i;
503 *streams=vorbis_mappings[channels-1].nb_streams;
504 *coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams;
505 for (i=0;i<channels;i++)
506 mapping[i] = vorbis_mappings[channels-1].mapping[i];
507 if (channels>=6)
508 st->lfe_stream = *streams-1;
509 } else if (mapping_family==255)
510 {
511 int i;
512 *streams=channels;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400513 *coupled_streams=0;
Jean-Marc Valin7a8b1392013-04-29 18:32:27 -0400514 for(i=0;i<channels;i++)
515 mapping[i] = i;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400516 } else
Jean-Marc Valin7a8b1392013-04-29 18:32:27 -0400517 return OPUS_UNIMPLEMENTED;
Jean-Marc Valin337f34c2013-07-01 16:17:01 -0400518 return opus_multistream_encoder_init_impl(st, Fs, channels, *streams, *coupled_streams,
Jean-Marc Valin58d80ab2013-05-27 20:47:47 -0400519 mapping, application, channels>2&&mapping_family==1);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400520}
521
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500522OpusMSEncoder *opus_multistream_encoder_create(
523 opus_int32 Fs,
524 int channels,
525 int streams,
526 int coupled_streams,
527 const unsigned char *mapping,
528 int application,
529 int *error
530)
531{
532 int ret;
533 OpusMSEncoder *st;
534 if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
Mark Harris25b27a92014-11-27 08:48:09 -0800535 (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams))
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500536 {
537 if (error)
538 *error = OPUS_BAD_ARG;
539 return NULL;
540 }
541 st = (OpusMSEncoder *)opus_alloc(opus_multistream_encoder_get_size(streams, coupled_streams));
542 if (st==NULL)
543 {
544 if (error)
545 *error = OPUS_ALLOC_FAIL;
546 return NULL;
547 }
548 ret = opus_multistream_encoder_init(st, Fs, channels, streams, coupled_streams, mapping, application);
549 if (ret != OPUS_OK)
550 {
551 opus_free(st);
552 st = NULL;
553 }
554 if (error)
555 *error = ret;
556 return st;
557}
558
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400559OpusMSEncoder *opus_multistream_surround_encoder_create(
560 opus_int32 Fs,
561 int channels,
562 int mapping_family,
563 int *streams,
564 int *coupled_streams,
565 unsigned char *mapping,
566 int application,
567 int *error
568)
569{
570 int ret;
Mark Harris25b27a92014-11-27 08:48:09 -0800571 opus_int32 size;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400572 OpusMSEncoder *st;
573 if ((channels>255) || (channels<1))
574 {
575 if (error)
576 *error = OPUS_BAD_ARG;
577 return NULL;
578 }
Mark Harris25b27a92014-11-27 08:48:09 -0800579 size = opus_multistream_surround_encoder_get_size(channels, mapping_family);
580 if (!size)
581 {
582 if (error)
583 *error = OPUS_UNIMPLEMENTED;
584 return NULL;
585 }
586 st = (OpusMSEncoder *)opus_alloc(size);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400587 if (st==NULL)
588 {
589 if (error)
590 *error = OPUS_ALLOC_FAIL;
591 return NULL;
592 }
593 ret = opus_multistream_surround_encoder_init(st, Fs, channels, mapping_family, streams, coupled_streams, mapping, application);
594 if (ret != OPUS_OK)
595 {
596 opus_free(st);
597 st = NULL;
598 }
599 if (error)
600 *error = ret;
601 return st;
602}
603
Jean-Marc Valin8dc91de2014-06-21 01:16:46 -0400604static opus_int32 surround_rate_allocation(
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400605 OpusMSEncoder *st,
606 opus_int32 *rate,
607 int frame_size
608 )
609{
610 int i;
611 opus_int32 channel_rate;
612 opus_int32 Fs;
613 char *ptr;
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400614 int stream_offset;
615 int lfe_offset;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400616 int coupled_ratio; /* Q8 */
617 int lfe_ratio; /* Q8 */
Jean-Marc Valin8dc91de2014-06-21 01:16:46 -0400618 opus_int32 rate_sum=0;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400619
620 ptr = (char*)st + align(sizeof(OpusMSEncoder));
621 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
622
Jean-Marc Valin49587512013-07-07 02:50:18 -0400623 if (st->bitrate_bps > st->layout.nb_channels*40000)
624 stream_offset = 20000;
625 else
626 stream_offset = st->bitrate_bps/st->layout.nb_channels/2;
Jean-Marc Valin87ca6c02013-11-13 22:58:10 -0500627 stream_offset += 60*(Fs/frame_size-50);
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400628 /* We start by giving each stream (coupled or uncoupled) the same bitrate.
629 This models the main saving of coupled channels over uncoupled. */
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400630 /* The LFE stream is an exception to the above and gets fewer bits. */
Jean-Marc Valin87ca6c02013-11-13 22:58:10 -0500631 lfe_offset = 3500 + 60*(Fs/frame_size-50);
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400632 /* Coupled streams get twice the mono rate after the first 20 kb/s. */
633 coupled_ratio = 512;
634 /* 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 -0400635 lfe_ratio = 32;
636
637 /* Compute bitrate allocation between streams */
638 if (st->bitrate_bps==OPUS_AUTO)
639 {
640 channel_rate = Fs+60*Fs/frame_size;
641 } else if (st->bitrate_bps==OPUS_BITRATE_MAX)
642 {
643 channel_rate = 300000;
644 } else {
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400645 int nb_lfe;
646 int nb_uncoupled;
647 int nb_coupled;
648 int total;
649 nb_lfe = (st->lfe_stream!=-1);
650 nb_coupled = st->layout.nb_coupled_streams;
651 nb_uncoupled = st->layout.nb_streams-nb_coupled-nb_lfe;
652 total = (nb_uncoupled<<8) /* mono */
653 + coupled_ratio*nb_coupled /* stereo */
654 + nb_lfe*lfe_ratio;
655 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 -0400656 }
657#ifndef FIXED_POINT
658 if (st->variable_duration==OPUS_FRAMESIZE_VARIABLE && frame_size != Fs/50)
659 {
660 opus_int32 bonus;
661 bonus = 60*(Fs/frame_size-50);
662 channel_rate += bonus;
663 }
664#endif
665
666 for (i=0;i<st->layout.nb_streams;i++)
667 {
668 if (i<st->layout.nb_coupled_streams)
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400669 rate[i] = stream_offset+(channel_rate*coupled_ratio>>8);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400670 else if (i!=st->lfe_stream)
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400671 rate[i] = stream_offset+channel_rate;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400672 else
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400673 rate[i] = lfe_offset+(channel_rate*lfe_ratio>>8);
Jean-Marc Valin8dc91de2014-06-21 01:16:46 -0400674 rate[i] = IMAX(rate[i], 500);
675 rate_sum += rate[i];
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400676 }
Jean-Marc Valin8dc91de2014-06-21 01:16:46 -0400677 return rate_sum;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400678}
679
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500680/* Max size in case the encoder decides to return three frames */
681#define MS_FRAME_TMP (3*1275+7)
682static int opus_multistream_encode_native
683(
684 OpusMSEncoder *st,
685 opus_copy_channel_in_func copy_channel_in,
686 const void *pcm,
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -0400687 int analysis_frame_size,
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500688 unsigned char *data,
Jean-Marc Valinb3eba242012-12-20 23:11:53 -0500689 opus_int32 max_data_bytes,
Jean-Marc Valin91904a42013-09-05 21:34:43 -0400690 int lsb_depth,
Jean-Marc Valinc94e4bb2013-12-08 03:31:50 -0500691 downmix_func downmix,
692 int float_api
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500693)
694{
695 opus_int32 Fs;
696 int coupled_size;
697 int mono_size;
698 int s;
699 char *ptr;
700 int tot_size;
701 VARDECL(opus_val16, buf);
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400702 VARDECL(opus_val16, bandSMR);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500703 unsigned char tmp_data[MS_FRAME_TMP];
704 OpusRepacketizer rp;
Jean-Marc Valineab134c2013-10-14 15:01:36 -0400705 opus_int32 vbr;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500706 const CELTMode *celt_mode;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400707 opus_int32 bitrates[256];
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400708 opus_val16 bandLogE[42];
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400709 opus_val32 *mem = NULL;
710 opus_val32 *preemph_mem=NULL;
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -0400711 int frame_size;
Jean-Marc Valin8dc91de2014-06-21 01:16:46 -0400712 opus_int32 rate_sum;
713 opus_int32 smallest_packet;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500714 ALLOC_STACK;
715
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400716 if (st->surround)
717 {
718 preemph_mem = ms_get_preemph_mem(st);
719 mem = ms_get_window_mem(st);
720 }
721
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500722 ptr = (char*)st + align(sizeof(OpusMSEncoder));
723 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
Jean-Marc Valineab134c2013-10-14 15:01:36 -0400724 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_VBR(&vbr));
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500725 opus_encoder_ctl((OpusEncoder*)ptr, CELT_GET_MODE(&celt_mode));
Jean-Marc Valin74483662012-12-17 16:23:42 -0500726
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -0400727 {
728 opus_int32 delay_compensation;
729 int channels;
730
731 channels = st->layout.nb_streams + st->layout.nb_coupled_streams;
732 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_LOOKAHEAD(&delay_compensation));
733 delay_compensation -= Fs/400;
734 frame_size = compute_frame_size(pcm, analysis_frame_size,
735 st->variable_duration, channels, Fs, st->bitrate_bps,
Jean-Marc Valinc2b34412013-10-28 21:48:50 -0400736 delay_compensation, downmix
737#ifndef DISABLE_FLOAT_API
738 , st->subframe_mem
739#endif
740 );
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -0400741 }
742
Jean-Marc Valin74483662012-12-17 16:23:42 -0500743 if (400*frame_size < Fs)
744 {
745 RESTORE_STACK;
746 return OPUS_BAD_ARG;
747 }
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500748 /* Validate frame_size before using it to allocate stack space.
749 This mirrors the checks in opus_encode[_float](). */
750 if (400*frame_size != Fs && 200*frame_size != Fs &&
751 100*frame_size != Fs && 50*frame_size != Fs &&
752 25*frame_size != Fs && 50*frame_size != 3*Fs)
753 {
754 RESTORE_STACK;
755 return OPUS_BAD_ARG;
756 }
Jean-Marc Valine1326fe2014-09-04 01:48:46 -0400757
758 /* Smallest packet the encoder can produce. */
759 smallest_packet = st->layout.nb_streams*2-1;
Jean-Marc Valin8dc91de2014-06-21 01:16:46 -0400760 if (max_data_bytes < smallest_packet)
761 {
762 RESTORE_STACK;
Jean-Marc Valine1326fe2014-09-04 01:48:46 -0400763 return OPUS_BUFFER_TOO_SMALL;
Jean-Marc Valin8dc91de2014-06-21 01:16:46 -0400764 }
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500765 ALLOC(buf, 2*frame_size, opus_val16);
766 coupled_size = opus_encoder_get_size(2);
767 mono_size = opus_encoder_get_size(1);
768
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400769 ALLOC(bandSMR, 21*st->layout.nb_channels, opus_val16);
Jean-Marc Valin58d80ab2013-05-27 20:47:47 -0400770 if (st->surround)
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400771 {
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400772 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 -0400773 }
774
Jean-Marc Valin74483662012-12-17 16:23:42 -0500775 /* 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;
Jean-Marc Valinda97db12014-09-04 02:48:21 -0400873 /* Reserve one byte for the last stream and two for the others */
Jean-Marc Valine1326fe2014-09-04 01:48:46 -0400874 curr_max -= IMAX(0,2*(st->layout.nb_streams-s-1)-1);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500875 curr_max = IMIN(curr_max,MS_FRAME_TMP);
Jean-Marc Valinda97db12014-09-04 02:48:21 -0400876 /* Repacketizer will add one or two bytes for self-delimited frames */
Jean-Marc Valin648eb9a2014-09-04 02:44:09 -0400877 if (s != st->layout.nb_streams-1) curr_max -= curr_max>253 ? 2 : 1;
Jean-Marc Valin2e653a72013-10-14 17:47:18 -0400878 if (!vbr && s == st->layout.nb_streams-1)
879 opus_encoder_ctl(enc, OPUS_SET_BITRATE(curr_max*(8*Fs/frame_size)));
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -0400880 len = opus_encode_native(enc, buf, frame_size, tmp_data, curr_max, lsb_depth,
Jean-Marc Valinc94e4bb2013-12-08 03:31:50 -0500881 pcm, analysis_frame_size, c1, c2, st->layout.nb_channels, downmix, float_api);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500882 if (len<0)
883 {
884 RESTORE_STACK;
885 return len;
886 }
887 /* We need to use the repacketizer to add the self-delimiting lengths
888 while taking into account the fact that the encoder can now return
889 more than one frame at a time (e.g. 60 ms CELT-only) */
890 opus_repacketizer_cat(&rp, tmp_data, len);
Jean-Marc Valinc5635d22013-11-13 14:08:22 -0500891 len = opus_repacketizer_out_range_impl(&rp, 0, opus_repacketizer_get_nb_frames(&rp),
892 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 -0500893 data += len;
894 tot_size += len;
895 }
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400896 /*printf("\n");*/
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500897 RESTORE_STACK;
898 return tot_size;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500899}
900
Pedro Becerra1af7f952013-07-11 00:00:47 -0400901#if !defined(DISABLE_FLOAT_API)
902static void opus_copy_channel_in_float(
903 opus_val16 *dst,
904 int dst_stride,
905 const void *src,
906 int src_stride,
907 int src_channel,
908 int frame_size
909)
910{
911 const float *float_src;
912 opus_int32 i;
913 float_src = (const float *)src;
914 for (i=0;i<frame_size;i++)
915#if defined(FIXED_POINT)
916 dst[i*dst_stride] = FLOAT2INT16(float_src[i*src_stride+src_channel]);
917#else
918 dst[i*dst_stride] = float_src[i*src_stride+src_channel];
919#endif
920}
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500921#endif
922
923static void opus_copy_channel_in_short(
924 opus_val16 *dst,
925 int dst_stride,
926 const void *src,
927 int src_stride,
928 int src_channel,
929 int frame_size
930)
931{
932 const opus_int16 *short_src;
Timothy B. Terriberrya8f04b22013-03-18 14:42:44 -0700933 opus_int32 i;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500934 short_src = (const opus_int16 *)src;
935 for (i=0;i<frame_size;i++)
936#if defined(FIXED_POINT)
937 dst[i*dst_stride] = short_src[i*src_stride+src_channel];
938#else
939 dst[i*dst_stride] = (1/32768.f)*short_src[i*src_stride+src_channel];
940#endif
941}
942
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400943
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500944#ifdef FIXED_POINT
945int opus_multistream_encode(
946 OpusMSEncoder *st,
947 const opus_val16 *pcm,
948 int frame_size,
949 unsigned char *data,
950 opus_int32 max_data_bytes
951)
952{
953 return opus_multistream_encode_native(st, opus_copy_channel_in_short,
Jean-Marc Valinc94e4bb2013-12-08 03:31:50 -0500954 pcm, frame_size, data, max_data_bytes, 16, downmix_int, 0);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500955}
956
957#ifndef DISABLE_FLOAT_API
958int opus_multistream_encode_float(
959 OpusMSEncoder *st,
960 const float *pcm,
961 int frame_size,
962 unsigned char *data,
963 opus_int32 max_data_bytes
964)
965{
966 return opus_multistream_encode_native(st, opus_copy_channel_in_float,
Jean-Marc Valinc94e4bb2013-12-08 03:31:50 -0500967 pcm, frame_size, data, max_data_bytes, 16, downmix_float, 1);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500968}
969#endif
970
971#else
972
973int opus_multistream_encode_float
974(
975 OpusMSEncoder *st,
976 const opus_val16 *pcm,
977 int frame_size,
978 unsigned char *data,
979 opus_int32 max_data_bytes
980)
981{
982 return opus_multistream_encode_native(st, opus_copy_channel_in_float,
Jean-Marc Valinc94e4bb2013-12-08 03:31:50 -0500983 pcm, frame_size, data, max_data_bytes, 24, downmix_float, 1);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500984}
985
986int opus_multistream_encode(
987 OpusMSEncoder *st,
988 const opus_int16 *pcm,
989 int frame_size,
990 unsigned char *data,
991 opus_int32 max_data_bytes
992)
993{
994 return opus_multistream_encode_native(st, opus_copy_channel_in_short,
Jean-Marc Valinc94e4bb2013-12-08 03:31:50 -0500995 pcm, frame_size, data, max_data_bytes, 16, downmix_int, 0);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500996}
997#endif
998
999int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
1000{
1001 va_list ap;
1002 int coupled_size, mono_size;
1003 char *ptr;
1004 int ret = OPUS_OK;
1005
1006 va_start(ap, request);
1007
1008 coupled_size = opus_encoder_get_size(2);
1009 mono_size = opus_encoder_get_size(1);
1010 ptr = (char*)st + align(sizeof(OpusMSEncoder));
1011 switch (request)
1012 {
1013 case OPUS_SET_BITRATE_REQUEST:
1014 {
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001015 opus_int32 value = va_arg(ap, opus_int32);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07001016 if (value<0 && value!=OPUS_AUTO && value!=OPUS_BITRATE_MAX)
1017 {
Jean-Marc Valin95561be2012-12-17 17:54:01 -05001018 goto bad_arg;
Gregory Maxwellb271dae2013-06-29 20:25:55 -07001019 }
Jean-Marc Valin74483662012-12-17 16:23:42 -05001020 st->bitrate_bps = value;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001021 }
1022 break;
1023 case OPUS_GET_BITRATE_REQUEST:
1024 {
1025 int s;
1026 opus_int32 *value = va_arg(ap, opus_int32*);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07001027 if (!value)
1028 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07001029 goto bad_arg;
1030 }
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001031 *value = 0;
1032 for (s=0;s<st->layout.nb_streams;s++)
1033 {
1034 opus_int32 rate;
1035 OpusEncoder *enc;
1036 enc = (OpusEncoder*)ptr;
1037 if (s < st->layout.nb_coupled_streams)
1038 ptr += align(coupled_size);
1039 else
1040 ptr += align(mono_size);
1041 opus_encoder_ctl(enc, request, &rate);
1042 *value += rate;
1043 }
1044 }
1045 break;
1046 case OPUS_GET_LSB_DEPTH_REQUEST:
1047 case OPUS_GET_VBR_REQUEST:
1048 case OPUS_GET_APPLICATION_REQUEST:
1049 case OPUS_GET_BANDWIDTH_REQUEST:
1050 case OPUS_GET_COMPLEXITY_REQUEST:
1051 case OPUS_GET_PACKET_LOSS_PERC_REQUEST:
1052 case OPUS_GET_DTX_REQUEST:
1053 case OPUS_GET_VOICE_RATIO_REQUEST:
1054 case OPUS_GET_VBR_CONSTRAINT_REQUEST:
1055 case OPUS_GET_SIGNAL_REQUEST:
1056 case OPUS_GET_LOOKAHEAD_REQUEST:
1057 case OPUS_GET_SAMPLE_RATE_REQUEST:
1058 case OPUS_GET_INBAND_FEC_REQUEST:
1059 case OPUS_GET_FORCE_CHANNELS_REQUEST:
Jean-Marc Valincbe93e22013-11-15 13:50:38 -05001060 case OPUS_GET_PREDICTION_DISABLED_REQUEST:
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001061 {
1062 OpusEncoder *enc;
1063 /* For int32* GET params, just query the first stream */
1064 opus_int32 *value = va_arg(ap, opus_int32*);
1065 enc = (OpusEncoder*)ptr;
1066 ret = opus_encoder_ctl(enc, request, value);
1067 }
1068 break;
1069 case OPUS_GET_FINAL_RANGE_REQUEST:
1070 {
1071 int s;
1072 opus_uint32 *value = va_arg(ap, opus_uint32*);
1073 opus_uint32 tmp;
Gregory Maxwella0d096f2013-06-29 20:33:32 -07001074 if (!value)
1075 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07001076 goto bad_arg;
1077 }
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001078 *value=0;
1079 for (s=0;s<st->layout.nb_streams;s++)
1080 {
1081 OpusEncoder *enc;
1082 enc = (OpusEncoder*)ptr;
1083 if (s < st->layout.nb_coupled_streams)
1084 ptr += align(coupled_size);
1085 else
1086 ptr += align(mono_size);
1087 ret = opus_encoder_ctl(enc, request, &tmp);
1088 if (ret != OPUS_OK) break;
1089 *value ^= tmp;
1090 }
1091 }
1092 break;
1093 case OPUS_SET_LSB_DEPTH_REQUEST:
1094 case OPUS_SET_COMPLEXITY_REQUEST:
1095 case OPUS_SET_VBR_REQUEST:
1096 case OPUS_SET_VBR_CONSTRAINT_REQUEST:
Daniel Jensenc0c0ef62013-07-22 16:31:31 -06001097 case OPUS_SET_MAX_BANDWIDTH_REQUEST:
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001098 case OPUS_SET_BANDWIDTH_REQUEST:
1099 case OPUS_SET_SIGNAL_REQUEST:
1100 case OPUS_SET_APPLICATION_REQUEST:
1101 case OPUS_SET_INBAND_FEC_REQUEST:
1102 case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
1103 case OPUS_SET_DTX_REQUEST:
1104 case OPUS_SET_FORCE_MODE_REQUEST:
1105 case OPUS_SET_FORCE_CHANNELS_REQUEST:
Jean-Marc Valincbe93e22013-11-15 13:50:38 -05001106 case OPUS_SET_PREDICTION_DISABLED_REQUEST:
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001107 {
1108 int s;
1109 /* This works for int32 params */
1110 opus_int32 value = va_arg(ap, opus_int32);
1111 for (s=0;s<st->layout.nb_streams;s++)
1112 {
1113 OpusEncoder *enc;
1114
1115 enc = (OpusEncoder*)ptr;
1116 if (s < st->layout.nb_coupled_streams)
1117 ptr += align(coupled_size);
1118 else
1119 ptr += align(mono_size);
1120 ret = opus_encoder_ctl(enc, request, value);
1121 if (ret != OPUS_OK)
1122 break;
1123 }
1124 }
1125 break;
1126 case OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST:
1127 {
1128 int s;
1129 opus_int32 stream_id;
1130 OpusEncoder **value;
1131 stream_id = va_arg(ap, opus_int32);
1132 if (stream_id<0 || stream_id >= st->layout.nb_streams)
1133 ret = OPUS_BAD_ARG;
1134 value = va_arg(ap, OpusEncoder**);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07001135 if (!value)
1136 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07001137 goto bad_arg;
1138 }
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001139 for (s=0;s<stream_id;s++)
1140 {
1141 if (s < st->layout.nb_coupled_streams)
1142 ptr += align(coupled_size);
1143 else
1144 ptr += align(mono_size);
1145 }
1146 *value = (OpusEncoder*)ptr;
1147 }
Jean-Marc Valin74483662012-12-17 16:23:42 -05001148 break;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -05001149 case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST:
Jean-Marc Valin74483662012-12-17 16:23:42 -05001150 {
1151 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin74483662012-12-17 16:23:42 -05001152 st->variable_duration = value;
1153 }
1154 break;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -05001155 case OPUS_GET_EXPERT_FRAME_DURATION_REQUEST:
Jean-Marc Valin74483662012-12-17 16:23:42 -05001156 {
1157 opus_int32 *value = va_arg(ap, opus_int32*);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07001158 if (!value)
1159 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07001160 goto bad_arg;
1161 }
Jean-Marc Valin74483662012-12-17 16:23:42 -05001162 *value = st->variable_duration;
1163 }
1164 break;
Jean-Marc Valin811db622013-10-28 16:11:53 -04001165 case OPUS_RESET_STATE:
1166 {
1167 int s;
1168 st->subframe_mem[0] = st->subframe_mem[1] = st->subframe_mem[2] = 0;
1169 if (st->surround)
1170 {
1171 OPUS_CLEAR(ms_get_preemph_mem(st), st->layout.nb_channels);
1172 OPUS_CLEAR(ms_get_window_mem(st), st->layout.nb_channels*120);
1173 }
1174 for (s=0;s<st->layout.nb_streams;s++)
1175 {
1176 OpusEncoder *enc;
1177 enc = (OpusEncoder*)ptr;
1178 if (s < st->layout.nb_coupled_streams)
1179 ptr += align(coupled_size);
1180 else
1181 ptr += align(mono_size);
1182 ret = opus_encoder_ctl(enc, OPUS_RESET_STATE);
1183 if (ret != OPUS_OK)
1184 break;
1185 }
1186 }
1187 break;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001188 default:
1189 ret = OPUS_UNIMPLEMENTED;
1190 break;
1191 }
1192
1193 va_end(ap);
1194 return ret;
Jean-Marc Valin74483662012-12-17 16:23:42 -05001195bad_arg:
1196 va_end(ap);
1197 return OPUS_BAD_ARG;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001198}
1199
1200void opus_multistream_encoder_destroy(OpusMSEncoder *st)
1201{
1202 opus_free(st);
1203}