blob: 4430e6947837d6b48117f40e25b406c231dbc47b [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
270 compute_band_energies(celt_mode, freq, bandE, 21, 1, 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 Valin1b723862013-04-25 21:34:04 -0400594static void surround_rate_allocation(
595 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 */
608
609 ptr = (char*)st + align(sizeof(OpusMSEncoder));
610 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
611
Jean-Marc Valin49587512013-07-07 02:50:18 -0400612 if (st->bitrate_bps > st->layout.nb_channels*40000)
613 stream_offset = 20000;
614 else
615 stream_offset = st->bitrate_bps/st->layout.nb_channels/2;
Jean-Marc Valin87ca6c02013-11-13 22:58:10 -0500616 stream_offset += 60*(Fs/frame_size-50);
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400617 /* We start by giving each stream (coupled or uncoupled) the same bitrate.
618 This models the main saving of coupled channels over uncoupled. */
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400619 /* The LFE stream is an exception to the above and gets fewer bits. */
Jean-Marc Valin87ca6c02013-11-13 22:58:10 -0500620 lfe_offset = 3500 + 60*(Fs/frame_size-50);
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400621 /* Coupled streams get twice the mono rate after the first 20 kb/s. */
622 coupled_ratio = 512;
623 /* 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 -0400624 lfe_ratio = 32;
625
626 /* Compute bitrate allocation between streams */
627 if (st->bitrate_bps==OPUS_AUTO)
628 {
629 channel_rate = Fs+60*Fs/frame_size;
630 } else if (st->bitrate_bps==OPUS_BITRATE_MAX)
631 {
632 channel_rate = 300000;
633 } else {
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400634 int nb_lfe;
635 int nb_uncoupled;
636 int nb_coupled;
637 int total;
638 nb_lfe = (st->lfe_stream!=-1);
639 nb_coupled = st->layout.nb_coupled_streams;
640 nb_uncoupled = st->layout.nb_streams-nb_coupled-nb_lfe;
641 total = (nb_uncoupled<<8) /* mono */
642 + coupled_ratio*nb_coupled /* stereo */
643 + nb_lfe*lfe_ratio;
644 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 -0400645 }
646#ifndef FIXED_POINT
647 if (st->variable_duration==OPUS_FRAMESIZE_VARIABLE && frame_size != Fs/50)
648 {
649 opus_int32 bonus;
650 bonus = 60*(Fs/frame_size-50);
651 channel_rate += bonus;
652 }
653#endif
654
655 for (i=0;i<st->layout.nb_streams;i++)
656 {
657 if (i<st->layout.nb_coupled_streams)
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400658 rate[i] = stream_offset+(channel_rate*coupled_ratio>>8);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400659 else if (i!=st->lfe_stream)
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400660 rate[i] = stream_offset+channel_rate;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400661 else
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400662 rate[i] = lfe_offset+(channel_rate*lfe_ratio>>8);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400663 }
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400664}
665
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500666/* Max size in case the encoder decides to return three frames */
667#define MS_FRAME_TMP (3*1275+7)
668static int opus_multistream_encode_native
669(
670 OpusMSEncoder *st,
671 opus_copy_channel_in_func copy_channel_in,
672 const void *pcm,
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -0400673 int analysis_frame_size,
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500674 unsigned char *data,
Jean-Marc Valinb3eba242012-12-20 23:11:53 -0500675 opus_int32 max_data_bytes,
Jean-Marc Valin91904a42013-09-05 21:34:43 -0400676 int lsb_depth,
677 downmix_func downmix
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500678)
679{
680 opus_int32 Fs;
681 int coupled_size;
682 int mono_size;
683 int s;
684 char *ptr;
685 int tot_size;
686 VARDECL(opus_val16, buf);
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400687 VARDECL(opus_val16, bandSMR);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500688 unsigned char tmp_data[MS_FRAME_TMP];
689 OpusRepacketizer rp;
Jean-Marc Valineab134c2013-10-14 15:01:36 -0400690 opus_int32 vbr;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500691 const CELTMode *celt_mode;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400692 opus_int32 bitrates[256];
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400693 opus_val16 bandLogE[42];
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400694 opus_val32 *mem = NULL;
695 opus_val32 *preemph_mem=NULL;
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -0400696 int frame_size;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500697 ALLOC_STACK;
698
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400699 if (st->surround)
700 {
701 preemph_mem = ms_get_preemph_mem(st);
702 mem = ms_get_window_mem(st);
703 }
704
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500705 ptr = (char*)st + align(sizeof(OpusMSEncoder));
706 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
Jean-Marc Valineab134c2013-10-14 15:01:36 -0400707 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_VBR(&vbr));
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500708 opus_encoder_ctl((OpusEncoder*)ptr, CELT_GET_MODE(&celt_mode));
Jean-Marc Valin74483662012-12-17 16:23:42 -0500709
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -0400710 {
711 opus_int32 delay_compensation;
712 int channels;
713
714 channels = st->layout.nb_streams + st->layout.nb_coupled_streams;
715 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_LOOKAHEAD(&delay_compensation));
716 delay_compensation -= Fs/400;
717 frame_size = compute_frame_size(pcm, analysis_frame_size,
718 st->variable_duration, channels, Fs, st->bitrate_bps,
Jean-Marc Valinc2b34412013-10-28 21:48:50 -0400719 delay_compensation, downmix
720#ifndef DISABLE_FLOAT_API
721 , st->subframe_mem
722#endif
723 );
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -0400724 }
725
Jean-Marc Valin74483662012-12-17 16:23:42 -0500726 if (400*frame_size < Fs)
727 {
728 RESTORE_STACK;
729 return OPUS_BAD_ARG;
730 }
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500731 /* Validate frame_size before using it to allocate stack space.
732 This mirrors the checks in opus_encode[_float](). */
733 if (400*frame_size != Fs && 200*frame_size != Fs &&
734 100*frame_size != Fs && 50*frame_size != Fs &&
735 25*frame_size != Fs && 50*frame_size != 3*Fs)
736 {
737 RESTORE_STACK;
738 return OPUS_BAD_ARG;
739 }
740 ALLOC(buf, 2*frame_size, opus_val16);
741 coupled_size = opus_encoder_get_size(2);
742 mono_size = opus_encoder_get_size(1);
743
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400744 ALLOC(bandSMR, 21*st->layout.nb_channels, opus_val16);
Jean-Marc Valin58d80ab2013-05-27 20:47:47 -0400745 if (st->surround)
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400746 {
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400747 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 -0400748 }
749
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500750 if (max_data_bytes < 4*st->layout.nb_streams-1)
751 {
752 RESTORE_STACK;
753 return OPUS_BUFFER_TOO_SMALL;
754 }
Jean-Marc Valin74483662012-12-17 16:23:42 -0500755
756 /* Compute bitrate allocation between streams (this could be a lot better) */
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400757 surround_rate_allocation(st, bitrates, frame_size);
758
Jean-Marc Valineab134c2013-10-14 15:01:36 -0400759 if (!vbr)
760 max_data_bytes = IMIN(max_data_bytes, st->bitrate_bps/(8*Fs/frame_size));
761
Jean-Marc Valin74483662012-12-17 16:23:42 -0500762 ptr = (char*)st + align(sizeof(OpusMSEncoder));
763 for (s=0;s<st->layout.nb_streams;s++)
764 {
765 OpusEncoder *enc;
766 enc = (OpusEncoder*)ptr;
767 if (s < st->layout.nb_coupled_streams)
768 ptr += align(coupled_size);
769 else
770 ptr += align(mono_size);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400771 opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrates[s]));
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400772 if (st->surround)
773 {
Jean-Marc Valin6fbfed62013-09-13 17:16:38 -0400774 opus_int32 equiv_rate;
775 equiv_rate = st->bitrate_bps;
776 if (frame_size*50 < Fs)
777 equiv_rate -= 60*(Fs/frame_size - 50)*st->layout.nb_channels;
Jean-Marc Valin420231a2013-11-08 19:53:27 -0500778 if (equiv_rate > 16000*st->layout.nb_channels)
Jean-Marc Valin6fbfed62013-09-13 17:16:38 -0400779 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
Jean-Marc Valin420231a2013-11-08 19:53:27 -0500780 else if (equiv_rate > 12000*st->layout.nb_channels)
Jean-Marc Valin6fbfed62013-09-13 17:16:38 -0400781 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_SUPERWIDEBAND));
Jean-Marc Valin420231a2013-11-08 19:53:27 -0500782 else if (equiv_rate > 8000*st->layout.nb_channels)
Jean-Marc Valin6fbfed62013-09-13 17:16:38 -0400783 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_WIDEBAND));
784 else
785 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND));
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400786 if (s < st->layout.nb_coupled_streams)
Jean-Marc Valin8824fdb2013-09-10 01:15:19 -0400787 {
788 /* To preserve the spatial image, force stereo CELT on coupled streams */
789 opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY));
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400790 opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(2));
Jean-Marc Valin8824fdb2013-09-10 01:15:19 -0400791 }
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400792 }
Jean-Marc Valin74483662012-12-17 16:23:42 -0500793 }
794
795 ptr = (char*)st + align(sizeof(OpusMSEncoder));
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500796 /* Counting ToC */
797 tot_size = 0;
798 for (s=0;s<st->layout.nb_streams;s++)
799 {
800 OpusEncoder *enc;
801 int len;
802 int curr_max;
Jean-Marc Valin91904a42013-09-05 21:34:43 -0400803 int c1, c2;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500804
805 opus_repacketizer_init(&rp);
806 enc = (OpusEncoder*)ptr;
807 if (s < st->layout.nb_coupled_streams)
808 {
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400809 int i;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500810 int left, right;
811 left = get_left_channel(&st->layout, s, -1);
812 right = get_right_channel(&st->layout, s, -1);
813 (*copy_channel_in)(buf, 2,
814 pcm, st->layout.nb_channels, left, frame_size);
815 (*copy_channel_in)(buf+1, 2,
816 pcm, st->layout.nb_channels, right, frame_size);
817 ptr += align(coupled_size);
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400818 if (st->surround)
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400819 {
820 for (i=0;i<21;i++)
821 {
822 bandLogE[i] = bandSMR[21*left+i];
823 bandLogE[21+i] = bandSMR[21*right+i];
824 }
825 }
Jean-Marc Valin91904a42013-09-05 21:34:43 -0400826 c1 = left;
827 c2 = right;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500828 } else {
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400829 int i;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500830 int chan = get_mono_channel(&st->layout, s, -1);
831 (*copy_channel_in)(buf, 1,
832 pcm, st->layout.nb_channels, chan, frame_size);
833 ptr += align(mono_size);
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400834 if (st->surround)
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400835 {
836 for (i=0;i<21;i++)
837 bandLogE[i] = bandSMR[21*chan+i];
838 }
Jean-Marc Valin91904a42013-09-05 21:34:43 -0400839 c1 = chan;
840 c2 = -1;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500841 }
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400842 if (st->surround)
843 opus_encoder_ctl(enc, OPUS_SET_ENERGY_MASK(bandLogE));
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500844 /* number of bytes left (+Toc) */
845 curr_max = max_data_bytes - tot_size;
846 /* Reserve three bytes for the last stream and four for the others */
847 curr_max -= IMAX(0,4*(st->layout.nb_streams-s-1)-1);
848 curr_max = IMIN(curr_max,MS_FRAME_TMP);
Jean-Marc Valin2e653a72013-10-14 17:47:18 -0400849 if (!vbr && s == st->layout.nb_streams-1)
850 opus_encoder_ctl(enc, OPUS_SET_BITRATE(curr_max*(8*Fs/frame_size)));
Jean-Marc Valinb90e63b2013-09-16 13:08:52 -0400851 len = opus_encode_native(enc, buf, frame_size, tmp_data, curr_max, lsb_depth,
852 pcm, analysis_frame_size, c1, c2, st->layout.nb_channels, downmix);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500853 if (len<0)
854 {
855 RESTORE_STACK;
856 return len;
857 }
858 /* We need to use the repacketizer to add the self-delimiting lengths
859 while taking into account the fact that the encoder can now return
860 more than one frame at a time (e.g. 60 ms CELT-only) */
861 opus_repacketizer_cat(&rp, tmp_data, len);
862 len = opus_repacketizer_out_range_impl(&rp, 0, opus_repacketizer_get_nb_frames(&rp), data, max_data_bytes-tot_size, s != st->layout.nb_streams-1);
Jean-Marc Valineab134c2013-10-14 15:01:36 -0400863 if (!vbr && s == st->layout.nb_streams-1 && curr_max > len)
864 {
Jean-Marc Valin2e653a72013-10-14 17:47:18 -0400865 /* Can pad_frame() still fail here? */
866 if (!pad_frame(data, len, curr_max))
867 len = curr_max;
Jean-Marc Valineab134c2013-10-14 15:01:36 -0400868 }
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500869 data += len;
870 tot_size += len;
871 }
Jean-Marc Valinfdceae82013-08-30 21:58:02 -0400872 /*printf("\n");*/
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500873 RESTORE_STACK;
874 return tot_size;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500875}
876
Pedro Becerra1af7f952013-07-11 00:00:47 -0400877#if !defined(DISABLE_FLOAT_API)
878static void opus_copy_channel_in_float(
879 opus_val16 *dst,
880 int dst_stride,
881 const void *src,
882 int src_stride,
883 int src_channel,
884 int frame_size
885)
886{
887 const float *float_src;
888 opus_int32 i;
889 float_src = (const float *)src;
890 for (i=0;i<frame_size;i++)
891#if defined(FIXED_POINT)
892 dst[i*dst_stride] = FLOAT2INT16(float_src[i*src_stride+src_channel]);
893#else
894 dst[i*dst_stride] = float_src[i*src_stride+src_channel];
895#endif
896}
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500897#endif
898
899static void opus_copy_channel_in_short(
900 opus_val16 *dst,
901 int dst_stride,
902 const void *src,
903 int src_stride,
904 int src_channel,
905 int frame_size
906)
907{
908 const opus_int16 *short_src;
Timothy B. Terriberrya8f04b22013-03-18 14:42:44 -0700909 opus_int32 i;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500910 short_src = (const opus_int16 *)src;
911 for (i=0;i<frame_size;i++)
912#if defined(FIXED_POINT)
913 dst[i*dst_stride] = short_src[i*src_stride+src_channel];
914#else
915 dst[i*dst_stride] = (1/32768.f)*short_src[i*src_stride+src_channel];
916#endif
917}
918
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400919
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500920#ifdef FIXED_POINT
921int opus_multistream_encode(
922 OpusMSEncoder *st,
923 const opus_val16 *pcm,
924 int frame_size,
925 unsigned char *data,
926 opus_int32 max_data_bytes
927)
928{
929 return opus_multistream_encode_native(st, opus_copy_channel_in_short,
Jean-Marc Valin91904a42013-09-05 21:34:43 -0400930 pcm, frame_size, data, max_data_bytes, 16, downmix_int);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500931}
932
933#ifndef DISABLE_FLOAT_API
934int opus_multistream_encode_float(
935 OpusMSEncoder *st,
936 const float *pcm,
937 int frame_size,
938 unsigned char *data,
939 opus_int32 max_data_bytes
940)
941{
942 return opus_multistream_encode_native(st, opus_copy_channel_in_float,
Jean-Marc Valin91904a42013-09-05 21:34:43 -0400943 pcm, frame_size, data, max_data_bytes, 16, downmix_float);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500944}
945#endif
946
947#else
948
949int opus_multistream_encode_float
950(
951 OpusMSEncoder *st,
952 const opus_val16 *pcm,
953 int frame_size,
954 unsigned char *data,
955 opus_int32 max_data_bytes
956)
957{
958 return opus_multistream_encode_native(st, opus_copy_channel_in_float,
Jean-Marc Valin91904a42013-09-05 21:34:43 -0400959 pcm, frame_size, data, max_data_bytes, 24, downmix_float);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500960}
961
962int opus_multistream_encode(
963 OpusMSEncoder *st,
964 const opus_int16 *pcm,
965 int frame_size,
966 unsigned char *data,
967 opus_int32 max_data_bytes
968)
969{
970 return opus_multistream_encode_native(st, opus_copy_channel_in_short,
Jean-Marc Valin91904a42013-09-05 21:34:43 -0400971 pcm, frame_size, data, max_data_bytes, 16, downmix_int);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500972}
973#endif
974
975int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
976{
977 va_list ap;
978 int coupled_size, mono_size;
979 char *ptr;
980 int ret = OPUS_OK;
981
982 va_start(ap, request);
983
984 coupled_size = opus_encoder_get_size(2);
985 mono_size = opus_encoder_get_size(1);
986 ptr = (char*)st + align(sizeof(OpusMSEncoder));
987 switch (request)
988 {
989 case OPUS_SET_BITRATE_REQUEST:
990 {
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500991 opus_int32 value = va_arg(ap, opus_int32);
Gregory Maxwella0d096f2013-06-29 20:33:32 -0700992 if (value<0 && value!=OPUS_AUTO && value!=OPUS_BITRATE_MAX)
993 {
Jean-Marc Valin95561be2012-12-17 17:54:01 -0500994 goto bad_arg;
Gregory Maxwellb271dae2013-06-29 20:25:55 -0700995 }
Jean-Marc Valin74483662012-12-17 16:23:42 -0500996 st->bitrate_bps = value;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500997 }
998 break;
999 case OPUS_GET_BITRATE_REQUEST:
1000 {
1001 int s;
1002 opus_int32 *value = va_arg(ap, opus_int32*);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07001003 if (!value)
1004 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07001005 goto bad_arg;
1006 }
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001007 *value = 0;
1008 for (s=0;s<st->layout.nb_streams;s++)
1009 {
1010 opus_int32 rate;
1011 OpusEncoder *enc;
1012 enc = (OpusEncoder*)ptr;
1013 if (s < st->layout.nb_coupled_streams)
1014 ptr += align(coupled_size);
1015 else
1016 ptr += align(mono_size);
1017 opus_encoder_ctl(enc, request, &rate);
1018 *value += rate;
1019 }
1020 }
1021 break;
1022 case OPUS_GET_LSB_DEPTH_REQUEST:
1023 case OPUS_GET_VBR_REQUEST:
1024 case OPUS_GET_APPLICATION_REQUEST:
1025 case OPUS_GET_BANDWIDTH_REQUEST:
1026 case OPUS_GET_COMPLEXITY_REQUEST:
1027 case OPUS_GET_PACKET_LOSS_PERC_REQUEST:
1028 case OPUS_GET_DTX_REQUEST:
1029 case OPUS_GET_VOICE_RATIO_REQUEST:
1030 case OPUS_GET_VBR_CONSTRAINT_REQUEST:
1031 case OPUS_GET_SIGNAL_REQUEST:
1032 case OPUS_GET_LOOKAHEAD_REQUEST:
1033 case OPUS_GET_SAMPLE_RATE_REQUEST:
1034 case OPUS_GET_INBAND_FEC_REQUEST:
1035 case OPUS_GET_FORCE_CHANNELS_REQUEST:
1036 {
1037 OpusEncoder *enc;
1038 /* For int32* GET params, just query the first stream */
1039 opus_int32 *value = va_arg(ap, opus_int32*);
1040 enc = (OpusEncoder*)ptr;
1041 ret = opus_encoder_ctl(enc, request, value);
1042 }
1043 break;
1044 case OPUS_GET_FINAL_RANGE_REQUEST:
1045 {
1046 int s;
1047 opus_uint32 *value = va_arg(ap, opus_uint32*);
1048 opus_uint32 tmp;
Gregory Maxwella0d096f2013-06-29 20:33:32 -07001049 if (!value)
1050 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07001051 goto bad_arg;
1052 }
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001053 *value=0;
1054 for (s=0;s<st->layout.nb_streams;s++)
1055 {
1056 OpusEncoder *enc;
1057 enc = (OpusEncoder*)ptr;
1058 if (s < st->layout.nb_coupled_streams)
1059 ptr += align(coupled_size);
1060 else
1061 ptr += align(mono_size);
1062 ret = opus_encoder_ctl(enc, request, &tmp);
1063 if (ret != OPUS_OK) break;
1064 *value ^= tmp;
1065 }
1066 }
1067 break;
1068 case OPUS_SET_LSB_DEPTH_REQUEST:
1069 case OPUS_SET_COMPLEXITY_REQUEST:
1070 case OPUS_SET_VBR_REQUEST:
1071 case OPUS_SET_VBR_CONSTRAINT_REQUEST:
Daniel Jensenc0c0ef62013-07-22 16:31:31 -06001072 case OPUS_SET_MAX_BANDWIDTH_REQUEST:
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001073 case OPUS_SET_BANDWIDTH_REQUEST:
1074 case OPUS_SET_SIGNAL_REQUEST:
1075 case OPUS_SET_APPLICATION_REQUEST:
1076 case OPUS_SET_INBAND_FEC_REQUEST:
1077 case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
1078 case OPUS_SET_DTX_REQUEST:
1079 case OPUS_SET_FORCE_MODE_REQUEST:
1080 case OPUS_SET_FORCE_CHANNELS_REQUEST:
1081 {
1082 int s;
1083 /* This works for int32 params */
1084 opus_int32 value = va_arg(ap, opus_int32);
1085 for (s=0;s<st->layout.nb_streams;s++)
1086 {
1087 OpusEncoder *enc;
1088
1089 enc = (OpusEncoder*)ptr;
1090 if (s < st->layout.nb_coupled_streams)
1091 ptr += align(coupled_size);
1092 else
1093 ptr += align(mono_size);
1094 ret = opus_encoder_ctl(enc, request, value);
1095 if (ret != OPUS_OK)
1096 break;
1097 }
1098 }
1099 break;
1100 case OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST:
1101 {
1102 int s;
1103 opus_int32 stream_id;
1104 OpusEncoder **value;
1105 stream_id = va_arg(ap, opus_int32);
1106 if (stream_id<0 || stream_id >= st->layout.nb_streams)
1107 ret = OPUS_BAD_ARG;
1108 value = va_arg(ap, OpusEncoder**);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07001109 if (!value)
1110 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07001111 goto bad_arg;
1112 }
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001113 for (s=0;s<stream_id;s++)
1114 {
1115 if (s < st->layout.nb_coupled_streams)
1116 ptr += align(coupled_size);
1117 else
1118 ptr += align(mono_size);
1119 }
1120 *value = (OpusEncoder*)ptr;
1121 }
Jean-Marc Valin74483662012-12-17 16:23:42 -05001122 break;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -05001123 case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST:
Jean-Marc Valin74483662012-12-17 16:23:42 -05001124 {
1125 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin74483662012-12-17 16:23:42 -05001126 st->variable_duration = value;
1127 }
1128 break;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -05001129 case OPUS_GET_EXPERT_FRAME_DURATION_REQUEST:
Jean-Marc Valin74483662012-12-17 16:23:42 -05001130 {
1131 opus_int32 *value = va_arg(ap, opus_int32*);
Gregory Maxwella0d096f2013-06-29 20:33:32 -07001132 if (!value)
1133 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -07001134 goto bad_arg;
1135 }
Jean-Marc Valin74483662012-12-17 16:23:42 -05001136 *value = st->variable_duration;
1137 }
1138 break;
Jean-Marc Valin811db622013-10-28 16:11:53 -04001139 case OPUS_RESET_STATE:
1140 {
1141 int s;
1142 st->subframe_mem[0] = st->subframe_mem[1] = st->subframe_mem[2] = 0;
1143 if (st->surround)
1144 {
1145 OPUS_CLEAR(ms_get_preemph_mem(st), st->layout.nb_channels);
1146 OPUS_CLEAR(ms_get_window_mem(st), st->layout.nb_channels*120);
1147 }
1148 for (s=0;s<st->layout.nb_streams;s++)
1149 {
1150 OpusEncoder *enc;
1151 enc = (OpusEncoder*)ptr;
1152 if (s < st->layout.nb_coupled_streams)
1153 ptr += align(coupled_size);
1154 else
1155 ptr += align(mono_size);
1156 ret = opus_encoder_ctl(enc, OPUS_RESET_STATE);
1157 if (ret != OPUS_OK)
1158 break;
1159 }
1160 }
1161 break;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001162 default:
1163 ret = OPUS_UNIMPLEMENTED;
1164 break;
1165 }
1166
1167 va_end(ap);
1168 return ret;
Jean-Marc Valin74483662012-12-17 16:23:42 -05001169bad_arg:
1170 va_end(ap);
1171 return OPUS_BAD_ARG;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001172}
1173
1174void opus_multistream_encoder_destroy(OpusMSEncoder *st)
1175{
1176 opus_free(st);
1177}