blob: d3250a17aa1f04c68375b16a2d4c0f87a5a9e79d [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 Valin51f4a322013-02-20 04:08:04 -050039#include "analysis.h"
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -050040
Jean-Marc Valin7a8b1392013-04-29 18:32:27 -040041typedef struct {
42 int nb_streams;
43 int nb_coupled_streams;
44 unsigned char mapping[8];
45} VorbisLayout;
46
47/* Index is nb_channel-1*/
48static const VorbisLayout vorbis_mappings[8] = {
49 {1, 0, {0}}, /* 1: mono */
50 {1, 1, {0, 1}}, /* 2: stereo */
51 {2, 1, {0, 2, 1}}, /* 3: 1-d surround */
52 {2, 2, {0, 1, 2, 3}}, /* 4: quadraphonic surround */
53 {3, 2, {0, 4, 1, 2, 3}}, /* 5: 5-channel surround */
54 {4, 2, {0, 4, 1, 2, 3, 5}}, /* 6: 5.1 surround */
55 {4, 3, {0, 4, 1, 2, 3, 5, 6}}, /* 7: 6.1 surround */
56 {5, 3, {0, 6, 1, 2, 3, 4, 5, 7}}, /* 8: 7.1 surround */
57};
58
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -050059struct OpusMSEncoder {
Jean-Marc Valin51f4a322013-02-20 04:08:04 -050060 TonalityAnalysisState analysis;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -050061 ChannelLayout layout;
Jean-Marc Valin1b723862013-04-25 21:34:04 -040062 int lfe_stream;
Jean-Marc Valin74483662012-12-17 16:23:42 -050063 int variable_duration;
Jean-Marc Valina4dccd32013-05-04 23:54:20 -040064 int surround;
Jean-Marc Valin74483662012-12-17 16:23:42 -050065 opus_int32 bitrate_bps;
66 opus_val32 subframe_mem[3];
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -050067 /* Encoder states go here */
68};
69
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -050070
71static int validate_encoder_layout(const ChannelLayout *layout)
72{
73 int s;
74 for (s=0;s<layout->nb_streams;s++)
75 {
76 if (s < layout->nb_coupled_streams)
77 {
78 if (get_left_channel(layout, s, -1)==-1)
79 return 0;
80 if (get_right_channel(layout, s, -1)==-1)
81 return 0;
82 } else {
83 if (get_mono_channel(layout, s, -1)==-1)
84 return 0;
85 }
86 }
87 return 1;
88}
89
90
91opus_int32 opus_multistream_encoder_get_size(int nb_streams, int nb_coupled_streams)
92{
93 int coupled_size;
94 int mono_size;
95
96 if(nb_streams<1||nb_coupled_streams>nb_streams||nb_coupled_streams<0)return 0;
97 coupled_size = opus_encoder_get_size(2);
98 mono_size = opus_encoder_get_size(1);
99 return align(sizeof(OpusMSEncoder))
100 + nb_coupled_streams * align(coupled_size)
101 + (nb_streams-nb_coupled_streams) * align(mono_size);
102}
103
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400104opus_int32 opus_multistream_surround_encoder_get_size(int channels, int mapping_family)
105{
106 int nb_streams;
107 int nb_coupled_streams;
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400108 opus_int32 size;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400109
Jean-Marc Valin7a8b1392013-04-29 18:32:27 -0400110 if (mapping_family==0)
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400111 {
Jean-Marc Valin7a8b1392013-04-29 18:32:27 -0400112 if (channels==1)
113 {
114 nb_streams=1;
115 nb_coupled_streams=0;
116 } else if (channels==2)
117 {
118 nb_streams=1;
119 nb_coupled_streams=1;
120 } else
121 return 0;
122 } else if (mapping_family==1 && channels<=8 && channels>=1)
123 {
124 nb_streams=vorbis_mappings[channels-1].nb_streams;
125 nb_coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams;
126 } else if (mapping_family==255)
127 {
128 nb_streams=channels;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400129 nb_coupled_streams=0;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400130 } else
131 return 0;
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400132 size = opus_multistream_encoder_get_size(nb_streams, nb_coupled_streams);
133 if (channels>2)
134 size += align(opus_encoder_get_size(2));
135 return size;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400136}
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500137
138
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400139static int opus_multistream_encoder_init_impl(
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500140 OpusMSEncoder *st,
141 opus_int32 Fs,
142 int channels,
143 int streams,
144 int coupled_streams,
145 const unsigned char *mapping,
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400146 int application,
147 int surround
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500148)
149{
150 int coupled_size;
151 int mono_size;
152 int i, ret;
153 char *ptr;
154
155 if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
156 (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0))
157 return OPUS_BAD_ARG;
158
159 st->layout.nb_channels = channels;
160 st->layout.nb_streams = streams;
161 st->layout.nb_coupled_streams = coupled_streams;
Jean-Marc Valinb0429352013-05-05 02:22:06 -0400162 st->subframe_mem[0]=st->subframe_mem[1]=st->subframe_mem[2]=0;
163 OPUS_CLEAR(&st->analysis,1);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400164 if (!surround)
165 st->lfe_stream = -1;
Jean-Marc Valin95561be2012-12-17 17:54:01 -0500166 st->bitrate_bps = OPUS_AUTO;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500167 st->variable_duration = OPUS_FRAMESIZE_ARG;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500168 for (i=0;i<st->layout.nb_channels;i++)
169 st->layout.mapping[i] = mapping[i];
170 if (!validate_layout(&st->layout) || !validate_encoder_layout(&st->layout))
171 return OPUS_BAD_ARG;
172 ptr = (char*)st + align(sizeof(OpusMSEncoder));
173 coupled_size = opus_encoder_get_size(2);
174 mono_size = opus_encoder_get_size(1);
175
176 for (i=0;i<st->layout.nb_coupled_streams;i++)
177 {
178 ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 2, application);
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400179 if(ret!=OPUS_OK)return ret;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400180 if (i==st->lfe_stream)
181 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1));
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500182 ptr += align(coupled_size);
183 }
184 for (;i<st->layout.nb_streams;i++)
185 {
186 ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 1, application);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400187 if (i==st->lfe_stream)
188 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1));
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500189 if(ret!=OPUS_OK)return ret;
190 ptr += align(mono_size);
191 }
Jean-Marc Valin58d80ab2013-05-27 20:47:47 -0400192 if (surround)
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400193 {
194 OpusEncoder *downmix_enc;
195 downmix_enc = (OpusEncoder*)ptr;
196 ret = opus_encoder_init(downmix_enc, Fs, 2, OPUS_APPLICATION_AUDIO);
197 if(ret!=OPUS_OK)return ret;
198 }
199 st->surround = surround;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500200 return OPUS_OK;
201}
202
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400203int opus_multistream_encoder_init(
204 OpusMSEncoder *st,
205 opus_int32 Fs,
206 int channels,
207 int streams,
208 int coupled_streams,
209 const unsigned char *mapping,
210 int application
211)
212{
213 return opus_multistream_encoder_init_impl(st, Fs, channels, streams, coupled_streams, mapping, application, 0);
214}
215
216int opus_multistream_surround_encoder_init(
217 OpusMSEncoder *st,
218 opus_int32 Fs,
219 int channels,
220 int mapping_family,
221 int *streams,
222 int *coupled_streams,
223 unsigned char *mapping,
224 int application
225)
226{
Jean-Marc Valin337f34c2013-07-01 16:17:01 -0400227 if ((channels>255) || (channels<1))
228 return OPUS_BAD_ARG;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400229 st->lfe_stream = -1;
Jean-Marc Valin7a8b1392013-04-29 18:32:27 -0400230 if (mapping_family==0)
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400231 {
Jean-Marc Valin7a8b1392013-04-29 18:32:27 -0400232 if (channels==1)
233 {
234 *streams=1;
235 *coupled_streams=0;
236 mapping[0]=0;
237 } else if (channels==2)
238 {
239 *streams=1;
240 *coupled_streams=1;
241 mapping[0]=0;
242 mapping[1]=1;
243 } else
244 return OPUS_UNIMPLEMENTED;
245 } else if (mapping_family==1 && channels<=8 && channels>=1)
246 {
247 int i;
248 *streams=vorbis_mappings[channels-1].nb_streams;
249 *coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams;
250 for (i=0;i<channels;i++)
251 mapping[i] = vorbis_mappings[channels-1].mapping[i];
252 if (channels>=6)
253 st->lfe_stream = *streams-1;
254 } else if (mapping_family==255)
255 {
256 int i;
257 *streams=channels;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400258 *coupled_streams=0;
Jean-Marc Valin7a8b1392013-04-29 18:32:27 -0400259 for(i=0;i<channels;i++)
260 mapping[i] = i;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400261 } else
Jean-Marc Valin7a8b1392013-04-29 18:32:27 -0400262 return OPUS_UNIMPLEMENTED;
Jean-Marc Valin337f34c2013-07-01 16:17:01 -0400263 return opus_multistream_encoder_init_impl(st, Fs, channels, *streams, *coupled_streams,
Jean-Marc Valin58d80ab2013-05-27 20:47:47 -0400264 mapping, application, channels>2&&mapping_family==1);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400265}
266
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500267OpusMSEncoder *opus_multistream_encoder_create(
268 opus_int32 Fs,
269 int channels,
270 int streams,
271 int coupled_streams,
272 const unsigned char *mapping,
273 int application,
274 int *error
275)
276{
277 int ret;
278 OpusMSEncoder *st;
279 if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
280 (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0))
281 {
282 if (error)
283 *error = OPUS_BAD_ARG;
284 return NULL;
285 }
286 st = (OpusMSEncoder *)opus_alloc(opus_multistream_encoder_get_size(streams, coupled_streams));
287 if (st==NULL)
288 {
289 if (error)
290 *error = OPUS_ALLOC_FAIL;
291 return NULL;
292 }
293 ret = opus_multistream_encoder_init(st, Fs, channels, streams, coupled_streams, mapping, application);
294 if (ret != OPUS_OK)
295 {
296 opus_free(st);
297 st = NULL;
298 }
299 if (error)
300 *error = ret;
301 return st;
302}
303
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400304OpusMSEncoder *opus_multistream_surround_encoder_create(
305 opus_int32 Fs,
306 int channels,
307 int mapping_family,
308 int *streams,
309 int *coupled_streams,
310 unsigned char *mapping,
311 int application,
312 int *error
313)
314{
315 int ret;
316 OpusMSEncoder *st;
317 if ((channels>255) || (channels<1))
318 {
319 if (error)
320 *error = OPUS_BAD_ARG;
321 return NULL;
322 }
323 st = (OpusMSEncoder *)opus_alloc(opus_multistream_surround_encoder_get_size(channels, mapping_family));
324 if (st==NULL)
325 {
326 if (error)
327 *error = OPUS_ALLOC_FAIL;
328 return NULL;
329 }
330 ret = opus_multistream_surround_encoder_init(st, Fs, channels, mapping_family, streams, coupled_streams, mapping, application);
331 if (ret != OPUS_OK)
332 {
333 opus_free(st);
334 st = NULL;
335 }
336 if (error)
337 *error = ret;
338 return st;
339}
340
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500341typedef void (*opus_copy_channel_in_func)(
342 opus_val16 *dst,
343 int dst_stride,
344 const void *src,
345 int src_stride,
346 int src_channel,
347 int frame_size
348);
349
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400350typedef void (*opus_surround_downmix_funct)(
351 opus_val16 *dst,
352 const void *src,
353 int channels,
354 int frame_size
355);
356
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400357static void surround_rate_allocation(
358 OpusMSEncoder *st,
359 opus_int32 *rate,
360 int frame_size
361 )
362{
363 int i;
364 opus_int32 channel_rate;
365 opus_int32 Fs;
366 char *ptr;
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400367 int stream_offset;
368 int lfe_offset;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400369 int coupled_ratio; /* Q8 */
370 int lfe_ratio; /* Q8 */
371
372 ptr = (char*)st + align(sizeof(OpusMSEncoder));
373 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
374
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400375 /* We start by giving each stream (coupled or uncoupled) the same bitrate.
376 This models the main saving of coupled channels over uncoupled. */
377 stream_offset = 20000;
378 /* The LFE stream is an exception to the above and gets fewer bits. */
379 lfe_offset = 3500;
380 /* Coupled streams get twice the mono rate after the first 20 kb/s. */
381 coupled_ratio = 512;
382 /* 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 -0400383 lfe_ratio = 32;
384
385 /* Compute bitrate allocation between streams */
386 if (st->bitrate_bps==OPUS_AUTO)
387 {
388 channel_rate = Fs+60*Fs/frame_size;
389 } else if (st->bitrate_bps==OPUS_BITRATE_MAX)
390 {
391 channel_rate = 300000;
392 } else {
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400393 int nb_lfe;
394 int nb_uncoupled;
395 int nb_coupled;
396 int total;
397 nb_lfe = (st->lfe_stream!=-1);
398 nb_coupled = st->layout.nb_coupled_streams;
399 nb_uncoupled = st->layout.nb_streams-nb_coupled-nb_lfe;
400 total = (nb_uncoupled<<8) /* mono */
401 + coupled_ratio*nb_coupled /* stereo */
402 + nb_lfe*lfe_ratio;
403 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 -0400404 }
405#ifndef FIXED_POINT
406 if (st->variable_duration==OPUS_FRAMESIZE_VARIABLE && frame_size != Fs/50)
407 {
408 opus_int32 bonus;
409 bonus = 60*(Fs/frame_size-50);
410 channel_rate += bonus;
411 }
412#endif
413
414 for (i=0;i<st->layout.nb_streams;i++)
415 {
416 if (i<st->layout.nb_coupled_streams)
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400417 rate[i] = stream_offset+(channel_rate*coupled_ratio>>8);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400418 else if (i!=st->lfe_stream)
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400419 rate[i] = stream_offset+channel_rate;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400420 else
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400421 rate[i] = lfe_offset+(channel_rate*lfe_ratio>>8);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400422 }
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400423}
424
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500425/* Max size in case the encoder decides to return three frames */
426#define MS_FRAME_TMP (3*1275+7)
427static int opus_multistream_encode_native
428(
429 OpusMSEncoder *st,
430 opus_copy_channel_in_func copy_channel_in,
431 const void *pcm,
432 int frame_size,
433 unsigned char *data,
Jean-Marc Valinb3eba242012-12-20 23:11:53 -0500434 opus_int32 max_data_bytes,
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400435 int lsb_depth,
436 opus_surround_downmix_funct surround_downmix
Jean-Marc Valin10a34a52012-12-20 00:23:01 -0500437#ifndef FIXED_POINT
438 , downmix_func downmix
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500439 , const void *pcm_analysis
Jean-Marc Valin10a34a52012-12-20 00:23:01 -0500440#endif
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500441)
442{
443 opus_int32 Fs;
444 int coupled_size;
445 int mono_size;
446 int s;
447 char *ptr;
448 int tot_size;
449 VARDECL(opus_val16, buf);
450 unsigned char tmp_data[MS_FRAME_TMP];
451 OpusRepacketizer rp;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500452 opus_int32 complexity;
453 AnalysisInfo analysis_info;
454 const CELTMode *celt_mode;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400455 opus_int32 bitrates[256];
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400456 opus_val16 bandLogE[42];
457 opus_val16 bandLogE_mono[21];
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500458 ALLOC_STACK;
459
460 ptr = (char*)st + align(sizeof(OpusMSEncoder));
461 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500462 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_COMPLEXITY(&complexity));
463 opus_encoder_ctl((OpusEncoder*)ptr, CELT_GET_MODE(&celt_mode));
Jean-Marc Valin74483662012-12-17 16:23:42 -0500464
465 if (400*frame_size < Fs)
466 {
467 RESTORE_STACK;
468 return OPUS_BAD_ARG;
469 }
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500470#ifndef FIXED_POINT
471 analysis_info.valid = 0;
472 if (complexity >= 7 && Fs==48000)
Jean-Marc Valin74483662012-12-17 16:23:42 -0500473 {
Jean-Marc Valin74483662012-12-17 16:23:42 -0500474 opus_int32 delay_compensation;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500475 int channels;
Jean-Marc Valin74483662012-12-17 16:23:42 -0500476
477 channels = st->layout.nb_streams + st->layout.nb_coupled_streams;
478 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_LOOKAHEAD(&delay_compensation));
479 delay_compensation -= Fs/400;
Jean-Marc Valin74483662012-12-17 16:23:42 -0500480
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500481 frame_size = run_analysis(&st->analysis, celt_mode, pcm, pcm_analysis,
482 frame_size, st->variable_duration, channels, Fs, st->bitrate_bps, delay_compensation, lsb_depth, downmix, &analysis_info);
483 } else
484#endif
485 {
486 frame_size = frame_size_select(frame_size, st->variable_duration, Fs);
487 }
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500488 /* Validate frame_size before using it to allocate stack space.
489 This mirrors the checks in opus_encode[_float](). */
490 if (400*frame_size != Fs && 200*frame_size != Fs &&
491 100*frame_size != Fs && 50*frame_size != Fs &&
492 25*frame_size != Fs && 50*frame_size != 3*Fs)
493 {
494 RESTORE_STACK;
495 return OPUS_BAD_ARG;
496 }
497 ALLOC(buf, 2*frame_size, opus_val16);
498 coupled_size = opus_encoder_get_size(2);
499 mono_size = opus_encoder_get_size(1);
500
Jean-Marc Valin58d80ab2013-05-27 20:47:47 -0400501 if (st->surround)
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400502 {
503 int i;
504 unsigned char dummy[512];
505 /* Temporary kludge -- remove */
506 OpusEncoder *downmix_enc;
507
508 ptr = (char*)st + align(sizeof(OpusMSEncoder));
509 for (s=0;s<st->layout.nb_streams;s++)
510 {
511 if (s < st->layout.nb_coupled_streams)
512 ptr += align(coupled_size);
513 else
514 ptr += align(mono_size);
515 }
516 downmix_enc = (OpusEncoder*)ptr;
517 surround_downmix(buf, pcm, st->layout.nb_channels, frame_size);
518 opus_encoder_ctl(downmix_enc, OPUS_SET_ENERGY_SAVE(bandLogE));
519 opus_encoder_ctl(downmix_enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
520 opus_encoder_ctl(downmix_enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY));
521 opus_encoder_ctl(downmix_enc, OPUS_SET_FORCE_CHANNELS(2));
522 opus_encode_native(downmix_enc, buf, frame_size, dummy, 512, lsb_depth
523#ifndef FIXED_POINT
524 , &analysis_info
525#endif
526 );
527 for(i=0;i<21;i++)
528 bandLogE_mono[i] = MAX16(bandLogE[i], bandLogE[21+i]);
529 }
530
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500531 if (max_data_bytes < 4*st->layout.nb_streams-1)
532 {
533 RESTORE_STACK;
534 return OPUS_BUFFER_TOO_SMALL;
535 }
Jean-Marc Valin74483662012-12-17 16:23:42 -0500536
537 /* Compute bitrate allocation between streams (this could be a lot better) */
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400538 surround_rate_allocation(st, bitrates, frame_size);
539
Jean-Marc Valin74483662012-12-17 16:23:42 -0500540 ptr = (char*)st + align(sizeof(OpusMSEncoder));
541 for (s=0;s<st->layout.nb_streams;s++)
542 {
543 OpusEncoder *enc;
544 enc = (OpusEncoder*)ptr;
545 if (s < st->layout.nb_coupled_streams)
546 ptr += align(coupled_size);
547 else
548 ptr += align(mono_size);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400549 opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrates[s]));
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400550 if (st->surround)
551 {
552 opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY));
553 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
554 if (s < st->layout.nb_coupled_streams)
555 opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(2));
556 }
Jean-Marc Valin74483662012-12-17 16:23:42 -0500557 }
558
559 ptr = (char*)st + align(sizeof(OpusMSEncoder));
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500560 /* Counting ToC */
561 tot_size = 0;
562 for (s=0;s<st->layout.nb_streams;s++)
563 {
564 OpusEncoder *enc;
565 int len;
566 int curr_max;
567
568 opus_repacketizer_init(&rp);
569 enc = (OpusEncoder*)ptr;
570 if (s < st->layout.nb_coupled_streams)
571 {
572 int left, right;
573 left = get_left_channel(&st->layout, s, -1);
574 right = get_right_channel(&st->layout, s, -1);
575 (*copy_channel_in)(buf, 2,
576 pcm, st->layout.nb_channels, left, frame_size);
577 (*copy_channel_in)(buf+1, 2,
578 pcm, st->layout.nb_channels, right, frame_size);
579 ptr += align(coupled_size);
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400580 /* FIXME: This isn't correct for the coupled center channels in
581 6.1 surround configuration */
582 if (st->surround)
583 opus_encoder_ctl(enc, OPUS_SET_ENERGY_MASK(bandLogE));
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500584 } else {
585 int chan = get_mono_channel(&st->layout, s, -1);
586 (*copy_channel_in)(buf, 1,
587 pcm, st->layout.nb_channels, chan, frame_size);
588 ptr += align(mono_size);
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400589 if (st->surround)
590 opus_encoder_ctl(enc, OPUS_SET_ENERGY_MASK(bandLogE_mono));
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500591 }
592 /* number of bytes left (+Toc) */
593 curr_max = max_data_bytes - tot_size;
594 /* Reserve three bytes for the last stream and four for the others */
595 curr_max -= IMAX(0,4*(st->layout.nb_streams-s-1)-1);
596 curr_max = IMIN(curr_max,MS_FRAME_TMP);
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500597 len = opus_encode_native(enc, buf, frame_size, tmp_data, curr_max, lsb_depth
598#ifndef FIXED_POINT
599 , &analysis_info
600#endif
601 );
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500602 if (len<0)
603 {
604 RESTORE_STACK;
605 return len;
606 }
607 /* We need to use the repacketizer to add the self-delimiting lengths
608 while taking into account the fact that the encoder can now return
609 more than one frame at a time (e.g. 60 ms CELT-only) */
610 opus_repacketizer_cat(&rp, tmp_data, len);
611 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);
612 data += len;
613 tot_size += len;
614 }
615 RESTORE_STACK;
616 return tot_size;
617
618}
619
620#if !defined(DISABLE_FLOAT_API)
621static void opus_copy_channel_in_float(
622 opus_val16 *dst,
623 int dst_stride,
624 const void *src,
625 int src_stride,
626 int src_channel,
627 int frame_size
628)
629{
630 const float *float_src;
Timothy B. Terriberrya8f04b22013-03-18 14:42:44 -0700631 opus_int32 i;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500632 float_src = (const float *)src;
633 for (i=0;i<frame_size;i++)
634#if defined(FIXED_POINT)
635 dst[i*dst_stride] = FLOAT2INT16(float_src[i*src_stride+src_channel]);
636#else
637 dst[i*dst_stride] = float_src[i*src_stride+src_channel];
638#endif
639}
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400640
641static void channel_pos(int channels, int pos[8])
642{
643 /* Position in the mix: 0 don't mix, 1: left, 2: center, 3:right */
644 if (channels==4)
645 {
646 pos[0]=1;
647 pos[1]=3;
648 pos[2]=1;
649 pos[3]=3;
650 } else if (channels==3||channels==5||channels==6)
651 {
652 pos[0]=1;
653 pos[1]=2;
654 pos[2]=3;
655 pos[3]=1;
656 pos[4]=3;
657 pos[5]=0;
658 } else if (channels==7)
659 {
660 pos[0]=1;
661 pos[1]=2;
662 pos[2]=3;
663 pos[3]=1;
664 pos[4]=3;
665 pos[5]=2;
666 pos[6]=0;
667 } else if (channels==8)
668 {
669 pos[0]=1;
670 pos[1]=2;
671 pos[2]=3;
672 pos[3]=1;
673 pos[4]=3;
674 pos[5]=1;
675 pos[6]=3;
676 pos[7]=0;
677 }
678}
679
680static void opus_surround_downmix_float(
681 opus_val16 *dst,
682 const void *src,
683 int channels,
684 int frame_size
685)
686{
687 const float *float_src;
688 opus_int32 i;
689 int pos[8] = {0};
690 int c;
691 float_src = (const float *)src;
692
693 channel_pos(channels, pos);
694 for (i=0;i<2*frame_size;i++)
695 dst[i]=0;
696
697 for (c=0;c<channels;c++)
698 {
699 if (pos[c]==1||pos[c]==2)
700 {
701 for (i=0;i<frame_size;i++)
702#if defined(FIXED_POINT)
703 dst[2*i] += SHR16(FLOAT2INT16(float_src[i*channels+c]),3);
704#else
705 dst[2*i] += float_src[i*channels+c];
706#endif
707 }
708 if (pos[c]==2||pos[c]==3)
709 {
710 for (i=0;i<frame_size;i++)
711#if defined(FIXED_POINT)
712 dst[2*i+1] += SHR16(FLOAT2INT16(float_src[i*channels+c]),3);
713#else
714 dst[2*i+1] += float_src[i*channels+c];
715#endif
716 }
717 }
718}
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500719#endif
720
721static void opus_copy_channel_in_short(
722 opus_val16 *dst,
723 int dst_stride,
724 const void *src,
725 int src_stride,
726 int src_channel,
727 int frame_size
728)
729{
730 const opus_int16 *short_src;
Timothy B. Terriberrya8f04b22013-03-18 14:42:44 -0700731 opus_int32 i;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500732 short_src = (const opus_int16 *)src;
733 for (i=0;i<frame_size;i++)
734#if defined(FIXED_POINT)
735 dst[i*dst_stride] = short_src[i*src_stride+src_channel];
736#else
737 dst[i*dst_stride] = (1/32768.f)*short_src[i*src_stride+src_channel];
738#endif
739}
740
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400741static void opus_surround_downmix_short(
742 opus_val16 *dst,
743 const void *src,
744 int channels,
745 int frame_size
746)
747{
748 const opus_int16 *short_src;
749 opus_int32 i;
750 int pos[8] = {0};
751 int c;
752 short_src = (const opus_int16 *)src;
753
754 channel_pos(channels, pos);
755 for (i=0;i<2*frame_size;i++)
756 dst[i]=0;
757
758 for (c=0;c<channels;c++)
759 {
760 if (pos[c]==1||pos[c]==2)
761 {
762 for (i=0;i<frame_size;i++)
763#if defined(FIXED_POINT)
764 dst[2*i] += SHR16(short_src[i*channels+c],3);
765#else
766 dst[2*i] += (1/32768.f)*short_src[i*channels+c];
767#endif
768 }
769 if (pos[c]==2||pos[c]==3)
770 {
771 for (i=0;i<frame_size;i++)
772#if defined(FIXED_POINT)
773 dst[2*i+1] += SHR16(short_src[i*channels+c],3);
774#else
775 dst[2*i+1] += (1/32768.f)*short_src[i*channels+c];
776#endif
777 }
778 }
779}
780
781
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500782#ifdef FIXED_POINT
783int opus_multistream_encode(
784 OpusMSEncoder *st,
785 const opus_val16 *pcm,
786 int frame_size,
787 unsigned char *data,
788 opus_int32 max_data_bytes
789)
790{
791 return opus_multistream_encode_native(st, opus_copy_channel_in_short,
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400792 pcm, frame_size, data, max_data_bytes, 16, opus_surround_downmix_float);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500793}
794
795#ifndef DISABLE_FLOAT_API
796int opus_multistream_encode_float(
797 OpusMSEncoder *st,
798 const float *pcm,
799 int frame_size,
800 unsigned char *data,
801 opus_int32 max_data_bytes
802)
803{
804 return opus_multistream_encode_native(st, opus_copy_channel_in_float,
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400805 pcm, frame_size, data, max_data_bytes, 16, opus_surround_downmix_short);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500806}
807#endif
808
809#else
810
811int opus_multistream_encode_float
812(
813 OpusMSEncoder *st,
814 const opus_val16 *pcm,
815 int frame_size,
816 unsigned char *data,
817 opus_int32 max_data_bytes
818)
819{
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500820 int channels = st->layout.nb_streams + st->layout.nb_coupled_streams;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500821 return opus_multistream_encode_native(st, opus_copy_channel_in_float,
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400822 pcm, frame_size, data, max_data_bytes, 24, opus_surround_downmix_float, downmix_float, pcm+channels*st->analysis.analysis_offset);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500823}
824
825int opus_multistream_encode(
826 OpusMSEncoder *st,
827 const opus_int16 *pcm,
828 int frame_size,
829 unsigned char *data,
830 opus_int32 max_data_bytes
831)
832{
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500833 int channels = st->layout.nb_streams + st->layout.nb_coupled_streams;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500834 return opus_multistream_encode_native(st, opus_copy_channel_in_short,
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400835 pcm, frame_size, data, max_data_bytes, 16, opus_surround_downmix_short, downmix_int, pcm+channels*st->analysis.analysis_offset);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500836}
837#endif
838
839int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
840{
841 va_list ap;
842 int coupled_size, mono_size;
843 char *ptr;
844 int ret = OPUS_OK;
845
846 va_start(ap, request);
847
848 coupled_size = opus_encoder_get_size(2);
849 mono_size = opus_encoder_get_size(1);
850 ptr = (char*)st + align(sizeof(OpusMSEncoder));
851 switch (request)
852 {
853 case OPUS_SET_BITRATE_REQUEST:
854 {
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500855 opus_int32 value = va_arg(ap, opus_int32);
Gregory Maxwella0d096f2013-06-29 20:33:32 -0700856 if (value<0 && value!=OPUS_AUTO && value!=OPUS_BITRATE_MAX)
857 {
Jean-Marc Valin95561be2012-12-17 17:54:01 -0500858 goto bad_arg;
Gregory Maxwellb271dae2013-06-29 20:25:55 -0700859 }
Jean-Marc Valin74483662012-12-17 16:23:42 -0500860 st->bitrate_bps = value;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500861 }
862 break;
863 case OPUS_GET_BITRATE_REQUEST:
864 {
865 int s;
866 opus_int32 *value = va_arg(ap, opus_int32*);
Gregory Maxwella0d096f2013-06-29 20:33:32 -0700867 if (!value)
868 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -0700869 goto bad_arg;
870 }
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500871 *value = 0;
872 for (s=0;s<st->layout.nb_streams;s++)
873 {
874 opus_int32 rate;
875 OpusEncoder *enc;
876 enc = (OpusEncoder*)ptr;
877 if (s < st->layout.nb_coupled_streams)
878 ptr += align(coupled_size);
879 else
880 ptr += align(mono_size);
881 opus_encoder_ctl(enc, request, &rate);
882 *value += rate;
883 }
884 }
885 break;
886 case OPUS_GET_LSB_DEPTH_REQUEST:
887 case OPUS_GET_VBR_REQUEST:
888 case OPUS_GET_APPLICATION_REQUEST:
889 case OPUS_GET_BANDWIDTH_REQUEST:
890 case OPUS_GET_COMPLEXITY_REQUEST:
891 case OPUS_GET_PACKET_LOSS_PERC_REQUEST:
892 case OPUS_GET_DTX_REQUEST:
893 case OPUS_GET_VOICE_RATIO_REQUEST:
894 case OPUS_GET_VBR_CONSTRAINT_REQUEST:
895 case OPUS_GET_SIGNAL_REQUEST:
896 case OPUS_GET_LOOKAHEAD_REQUEST:
897 case OPUS_GET_SAMPLE_RATE_REQUEST:
898 case OPUS_GET_INBAND_FEC_REQUEST:
899 case OPUS_GET_FORCE_CHANNELS_REQUEST:
900 {
901 OpusEncoder *enc;
902 /* For int32* GET params, just query the first stream */
903 opus_int32 *value = va_arg(ap, opus_int32*);
904 enc = (OpusEncoder*)ptr;
905 ret = opus_encoder_ctl(enc, request, value);
906 }
907 break;
908 case OPUS_GET_FINAL_RANGE_REQUEST:
909 {
910 int s;
911 opus_uint32 *value = va_arg(ap, opus_uint32*);
912 opus_uint32 tmp;
Gregory Maxwella0d096f2013-06-29 20:33:32 -0700913 if (!value)
914 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -0700915 goto bad_arg;
916 }
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500917 *value=0;
918 for (s=0;s<st->layout.nb_streams;s++)
919 {
920 OpusEncoder *enc;
921 enc = (OpusEncoder*)ptr;
922 if (s < st->layout.nb_coupled_streams)
923 ptr += align(coupled_size);
924 else
925 ptr += align(mono_size);
926 ret = opus_encoder_ctl(enc, request, &tmp);
927 if (ret != OPUS_OK) break;
928 *value ^= tmp;
929 }
930 }
931 break;
932 case OPUS_SET_LSB_DEPTH_REQUEST:
933 case OPUS_SET_COMPLEXITY_REQUEST:
934 case OPUS_SET_VBR_REQUEST:
935 case OPUS_SET_VBR_CONSTRAINT_REQUEST:
936 case OPUS_SET_BANDWIDTH_REQUEST:
937 case OPUS_SET_SIGNAL_REQUEST:
938 case OPUS_SET_APPLICATION_REQUEST:
939 case OPUS_SET_INBAND_FEC_REQUEST:
940 case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
941 case OPUS_SET_DTX_REQUEST:
942 case OPUS_SET_FORCE_MODE_REQUEST:
943 case OPUS_SET_FORCE_CHANNELS_REQUEST:
944 {
945 int s;
946 /* This works for int32 params */
947 opus_int32 value = va_arg(ap, opus_int32);
948 for (s=0;s<st->layout.nb_streams;s++)
949 {
950 OpusEncoder *enc;
951
952 enc = (OpusEncoder*)ptr;
953 if (s < st->layout.nb_coupled_streams)
954 ptr += align(coupled_size);
955 else
956 ptr += align(mono_size);
957 ret = opus_encoder_ctl(enc, request, value);
958 if (ret != OPUS_OK)
959 break;
960 }
961 }
962 break;
963 case OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST:
964 {
965 int s;
966 opus_int32 stream_id;
967 OpusEncoder **value;
968 stream_id = va_arg(ap, opus_int32);
969 if (stream_id<0 || stream_id >= st->layout.nb_streams)
970 ret = OPUS_BAD_ARG;
971 value = va_arg(ap, OpusEncoder**);
Gregory Maxwella0d096f2013-06-29 20:33:32 -0700972 if (!value)
973 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -0700974 goto bad_arg;
975 }
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500976 for (s=0;s<stream_id;s++)
977 {
978 if (s < st->layout.nb_coupled_streams)
979 ptr += align(coupled_size);
980 else
981 ptr += align(mono_size);
982 }
983 *value = (OpusEncoder*)ptr;
984 }
Jean-Marc Valin74483662012-12-17 16:23:42 -0500985 break;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500986 case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST:
Jean-Marc Valin74483662012-12-17 16:23:42 -0500987 {
988 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin74483662012-12-17 16:23:42 -0500989 st->variable_duration = value;
990 }
991 break;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500992 case OPUS_GET_EXPERT_FRAME_DURATION_REQUEST:
Jean-Marc Valin74483662012-12-17 16:23:42 -0500993 {
994 opus_int32 *value = va_arg(ap, opus_int32*);
Gregory Maxwella0d096f2013-06-29 20:33:32 -0700995 if (!value)
996 {
Gregory Maxwellb271dae2013-06-29 20:25:55 -0700997 goto bad_arg;
998 }
Jean-Marc Valin74483662012-12-17 16:23:42 -0500999 *value = st->variable_duration;
1000 }
1001 break;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001002 default:
1003 ret = OPUS_UNIMPLEMENTED;
1004 break;
1005 }
1006
1007 va_end(ap);
1008 return ret;
Jean-Marc Valin74483662012-12-17 16:23:42 -05001009bad_arg:
1010 va_end(ap);
1011 return OPUS_BAD_ARG;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001012}
1013
1014void opus_multistream_encoder_destroy(OpusMSEncoder *st)
1015{
1016 opus_free(st);
1017}