blob: 81ea48496a7ebe7c77aeaeed5bcc11783ae50269 [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{
227 st->lfe_stream = -1;
Jean-Marc Valin7a8b1392013-04-29 18:32:27 -0400228 if (mapping_family==0)
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400229 {
Jean-Marc Valin7a8b1392013-04-29 18:32:27 -0400230 if (channels==1)
231 {
232 *streams=1;
233 *coupled_streams=0;
234 mapping[0]=0;
235 } else if (channels==2)
236 {
237 *streams=1;
238 *coupled_streams=1;
239 mapping[0]=0;
240 mapping[1]=1;
241 } else
242 return OPUS_UNIMPLEMENTED;
243 } else if (mapping_family==1 && channels<=8 && channels>=1)
244 {
245 int i;
246 *streams=vorbis_mappings[channels-1].nb_streams;
247 *coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams;
248 for (i=0;i<channels;i++)
249 mapping[i] = vorbis_mappings[channels-1].mapping[i];
250 if (channels>=6)
251 st->lfe_stream = *streams-1;
252 } else if (mapping_family==255)
253 {
254 int i;
255 *streams=channels;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400256 *coupled_streams=0;
Jean-Marc Valin7a8b1392013-04-29 18:32:27 -0400257 for(i=0;i<channels;i++)
258 mapping[i] = i;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400259 } else
Jean-Marc Valin7a8b1392013-04-29 18:32:27 -0400260 return OPUS_UNIMPLEMENTED;
Jean-Marc Valin58d80ab2013-05-27 20:47:47 -0400261 opus_multistream_encoder_init_impl(st, Fs, channels, *streams, *coupled_streams,
262 mapping, application, channels>2&&mapping_family==1);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400263 return OPUS_OK;
264}
265
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500266OpusMSEncoder *opus_multistream_encoder_create(
267 opus_int32 Fs,
268 int channels,
269 int streams,
270 int coupled_streams,
271 const unsigned char *mapping,
272 int application,
273 int *error
274)
275{
276 int ret;
277 OpusMSEncoder *st;
278 if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
279 (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0))
280 {
281 if (error)
282 *error = OPUS_BAD_ARG;
283 return NULL;
284 }
285 st = (OpusMSEncoder *)opus_alloc(opus_multistream_encoder_get_size(streams, coupled_streams));
286 if (st==NULL)
287 {
288 if (error)
289 *error = OPUS_ALLOC_FAIL;
290 return NULL;
291 }
292 ret = opus_multistream_encoder_init(st, Fs, channels, streams, coupled_streams, mapping, application);
293 if (ret != OPUS_OK)
294 {
295 opus_free(st);
296 st = NULL;
297 }
298 if (error)
299 *error = ret;
300 return st;
301}
302
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400303OpusMSEncoder *opus_multistream_surround_encoder_create(
304 opus_int32 Fs,
305 int channels,
306 int mapping_family,
307 int *streams,
308 int *coupled_streams,
309 unsigned char *mapping,
310 int application,
311 int *error
312)
313{
314 int ret;
315 OpusMSEncoder *st;
316 if ((channels>255) || (channels<1))
317 {
318 if (error)
319 *error = OPUS_BAD_ARG;
320 return NULL;
321 }
322 st = (OpusMSEncoder *)opus_alloc(opus_multistream_surround_encoder_get_size(channels, mapping_family));
323 if (st==NULL)
324 {
325 if (error)
326 *error = OPUS_ALLOC_FAIL;
327 return NULL;
328 }
329 ret = opus_multistream_surround_encoder_init(st, Fs, channels, mapping_family, streams, coupled_streams, mapping, application);
330 if (ret != OPUS_OK)
331 {
332 opus_free(st);
333 st = NULL;
334 }
335 if (error)
336 *error = ret;
337 return st;
338}
339
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500340typedef void (*opus_copy_channel_in_func)(
341 opus_val16 *dst,
342 int dst_stride,
343 const void *src,
344 int src_stride,
345 int src_channel,
346 int frame_size
347);
348
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400349typedef void (*opus_surround_downmix_funct)(
350 opus_val16 *dst,
351 const void *src,
352 int channels,
353 int frame_size
354);
355
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400356static void surround_rate_allocation(
357 OpusMSEncoder *st,
358 opus_int32 *rate,
359 int frame_size
360 )
361{
362 int i;
363 opus_int32 channel_rate;
364 opus_int32 Fs;
365 char *ptr;
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400366 int stream_offset;
367 int lfe_offset;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400368 int coupled_ratio; /* Q8 */
369 int lfe_ratio; /* Q8 */
370
371 ptr = (char*)st + align(sizeof(OpusMSEncoder));
372 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
373
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400374 /* We start by giving each stream (coupled or uncoupled) the same bitrate.
375 This models the main saving of coupled channels over uncoupled. */
376 stream_offset = 20000;
377 /* The LFE stream is an exception to the above and gets fewer bits. */
378 lfe_offset = 3500;
379 /* Coupled streams get twice the mono rate after the first 20 kb/s. */
380 coupled_ratio = 512;
381 /* 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 -0400382 lfe_ratio = 32;
383
384 /* Compute bitrate allocation between streams */
385 if (st->bitrate_bps==OPUS_AUTO)
386 {
387 channel_rate = Fs+60*Fs/frame_size;
388 } else if (st->bitrate_bps==OPUS_BITRATE_MAX)
389 {
390 channel_rate = 300000;
391 } else {
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400392 int nb_lfe;
393 int nb_uncoupled;
394 int nb_coupled;
395 int total;
396 nb_lfe = (st->lfe_stream!=-1);
397 nb_coupled = st->layout.nb_coupled_streams;
398 nb_uncoupled = st->layout.nb_streams-nb_coupled-nb_lfe;
399 total = (nb_uncoupled<<8) /* mono */
400 + coupled_ratio*nb_coupled /* stereo */
401 + nb_lfe*lfe_ratio;
402 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 -0400403 }
404#ifndef FIXED_POINT
405 if (st->variable_duration==OPUS_FRAMESIZE_VARIABLE && frame_size != Fs/50)
406 {
407 opus_int32 bonus;
408 bonus = 60*(Fs/frame_size-50);
409 channel_rate += bonus;
410 }
411#endif
412
413 for (i=0;i<st->layout.nb_streams;i++)
414 {
415 if (i<st->layout.nb_coupled_streams)
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400416 rate[i] = stream_offset+(channel_rate*coupled_ratio>>8);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400417 else if (i!=st->lfe_stream)
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400418 rate[i] = stream_offset+channel_rate;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400419 else
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400420 rate[i] = lfe_offset+(channel_rate*lfe_ratio>>8);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400421 }
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400422}
423
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500424/* Max size in case the encoder decides to return three frames */
425#define MS_FRAME_TMP (3*1275+7)
426static int opus_multistream_encode_native
427(
428 OpusMSEncoder *st,
429 opus_copy_channel_in_func copy_channel_in,
430 const void *pcm,
431 int frame_size,
432 unsigned char *data,
Jean-Marc Valinb3eba242012-12-20 23:11:53 -0500433 opus_int32 max_data_bytes,
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400434 int lsb_depth,
435 opus_surround_downmix_funct surround_downmix
Jean-Marc Valin10a34a52012-12-20 00:23:01 -0500436#ifndef FIXED_POINT
437 , downmix_func downmix
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500438 , const void *pcm_analysis
Jean-Marc Valin10a34a52012-12-20 00:23:01 -0500439#endif
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500440)
441{
442 opus_int32 Fs;
443 int coupled_size;
444 int mono_size;
445 int s;
446 char *ptr;
447 int tot_size;
448 VARDECL(opus_val16, buf);
449 unsigned char tmp_data[MS_FRAME_TMP];
450 OpusRepacketizer rp;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500451 opus_int32 complexity;
452 AnalysisInfo analysis_info;
453 const CELTMode *celt_mode;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400454 opus_int32 bitrates[256];
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400455 opus_val16 bandLogE[42];
456 opus_val16 bandLogE_mono[21];
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500457 ALLOC_STACK;
458
459 ptr = (char*)st + align(sizeof(OpusMSEncoder));
460 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500461 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_COMPLEXITY(&complexity));
462 opus_encoder_ctl((OpusEncoder*)ptr, CELT_GET_MODE(&celt_mode));
Jean-Marc Valin74483662012-12-17 16:23:42 -0500463
464 if (400*frame_size < Fs)
465 {
466 RESTORE_STACK;
467 return OPUS_BAD_ARG;
468 }
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500469#ifndef FIXED_POINT
470 analysis_info.valid = 0;
471 if (complexity >= 7 && Fs==48000)
Jean-Marc Valin74483662012-12-17 16:23:42 -0500472 {
Jean-Marc Valin74483662012-12-17 16:23:42 -0500473 opus_int32 delay_compensation;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500474 int channels;
Jean-Marc Valin74483662012-12-17 16:23:42 -0500475
476 channels = st->layout.nb_streams + st->layout.nb_coupled_streams;
477 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_LOOKAHEAD(&delay_compensation));
478 delay_compensation -= Fs/400;
Jean-Marc Valin74483662012-12-17 16:23:42 -0500479
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500480 frame_size = run_analysis(&st->analysis, celt_mode, pcm, pcm_analysis,
481 frame_size, st->variable_duration, channels, Fs, st->bitrate_bps, delay_compensation, lsb_depth, downmix, &analysis_info);
482 } else
483#endif
484 {
485 frame_size = frame_size_select(frame_size, st->variable_duration, Fs);
486 }
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500487 /* Validate frame_size before using it to allocate stack space.
488 This mirrors the checks in opus_encode[_float](). */
489 if (400*frame_size != Fs && 200*frame_size != Fs &&
490 100*frame_size != Fs && 50*frame_size != Fs &&
491 25*frame_size != Fs && 50*frame_size != 3*Fs)
492 {
493 RESTORE_STACK;
494 return OPUS_BAD_ARG;
495 }
496 ALLOC(buf, 2*frame_size, opus_val16);
497 coupled_size = opus_encoder_get_size(2);
498 mono_size = opus_encoder_get_size(1);
499
Jean-Marc Valin58d80ab2013-05-27 20:47:47 -0400500 if (st->surround)
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400501 {
502 int i;
503 unsigned char dummy[512];
504 /* Temporary kludge -- remove */
505 OpusEncoder *downmix_enc;
506
507 ptr = (char*)st + align(sizeof(OpusMSEncoder));
508 for (s=0;s<st->layout.nb_streams;s++)
509 {
510 if (s < st->layout.nb_coupled_streams)
511 ptr += align(coupled_size);
512 else
513 ptr += align(mono_size);
514 }
515 downmix_enc = (OpusEncoder*)ptr;
516 surround_downmix(buf, pcm, st->layout.nb_channels, frame_size);
517 opus_encoder_ctl(downmix_enc, OPUS_SET_ENERGY_SAVE(bandLogE));
518 opus_encoder_ctl(downmix_enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
519 opus_encoder_ctl(downmix_enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY));
520 opus_encoder_ctl(downmix_enc, OPUS_SET_FORCE_CHANNELS(2));
521 opus_encode_native(downmix_enc, buf, frame_size, dummy, 512, lsb_depth
522#ifndef FIXED_POINT
523 , &analysis_info
524#endif
525 );
526 for(i=0;i<21;i++)
527 bandLogE_mono[i] = MAX16(bandLogE[i], bandLogE[21+i]);
528 }
529
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500530 if (max_data_bytes < 4*st->layout.nb_streams-1)
531 {
532 RESTORE_STACK;
533 return OPUS_BUFFER_TOO_SMALL;
534 }
Jean-Marc Valin74483662012-12-17 16:23:42 -0500535
536 /* Compute bitrate allocation between streams (this could be a lot better) */
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400537 surround_rate_allocation(st, bitrates, frame_size);
538
Jean-Marc Valin74483662012-12-17 16:23:42 -0500539 ptr = (char*)st + align(sizeof(OpusMSEncoder));
540 for (s=0;s<st->layout.nb_streams;s++)
541 {
542 OpusEncoder *enc;
543 enc = (OpusEncoder*)ptr;
544 if (s < st->layout.nb_coupled_streams)
545 ptr += align(coupled_size);
546 else
547 ptr += align(mono_size);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400548 opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrates[s]));
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400549 if (st->surround)
550 {
551 opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY));
552 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
553 if (s < st->layout.nb_coupled_streams)
554 opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(2));
555 }
Jean-Marc Valin74483662012-12-17 16:23:42 -0500556 }
557
558 ptr = (char*)st + align(sizeof(OpusMSEncoder));
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500559 /* Counting ToC */
560 tot_size = 0;
561 for (s=0;s<st->layout.nb_streams;s++)
562 {
563 OpusEncoder *enc;
564 int len;
565 int curr_max;
566
567 opus_repacketizer_init(&rp);
568 enc = (OpusEncoder*)ptr;
569 if (s < st->layout.nb_coupled_streams)
570 {
571 int left, right;
572 left = get_left_channel(&st->layout, s, -1);
573 right = get_right_channel(&st->layout, s, -1);
574 (*copy_channel_in)(buf, 2,
575 pcm, st->layout.nb_channels, left, frame_size);
576 (*copy_channel_in)(buf+1, 2,
577 pcm, st->layout.nb_channels, right, frame_size);
578 ptr += align(coupled_size);
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400579 /* FIXME: This isn't correct for the coupled center channels in
580 6.1 surround configuration */
581 if (st->surround)
582 opus_encoder_ctl(enc, OPUS_SET_ENERGY_MASK(bandLogE));
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500583 } else {
584 int chan = get_mono_channel(&st->layout, s, -1);
585 (*copy_channel_in)(buf, 1,
586 pcm, st->layout.nb_channels, chan, frame_size);
587 ptr += align(mono_size);
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400588 if (st->surround)
589 opus_encoder_ctl(enc, OPUS_SET_ENERGY_MASK(bandLogE_mono));
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500590 }
591 /* number of bytes left (+Toc) */
592 curr_max = max_data_bytes - tot_size;
593 /* Reserve three bytes for the last stream and four for the others */
594 curr_max -= IMAX(0,4*(st->layout.nb_streams-s-1)-1);
595 curr_max = IMIN(curr_max,MS_FRAME_TMP);
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500596 len = opus_encode_native(enc, buf, frame_size, tmp_data, curr_max, lsb_depth
597#ifndef FIXED_POINT
598 , &analysis_info
599#endif
600 );
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500601 if (len<0)
602 {
603 RESTORE_STACK;
604 return len;
605 }
606 /* We need to use the repacketizer to add the self-delimiting lengths
607 while taking into account the fact that the encoder can now return
608 more than one frame at a time (e.g. 60 ms CELT-only) */
609 opus_repacketizer_cat(&rp, tmp_data, len);
610 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);
611 data += len;
612 tot_size += len;
613 }
614 RESTORE_STACK;
615 return tot_size;
616
617}
618
619#if !defined(DISABLE_FLOAT_API)
620static void opus_copy_channel_in_float(
621 opus_val16 *dst,
622 int dst_stride,
623 const void *src,
624 int src_stride,
625 int src_channel,
626 int frame_size
627)
628{
629 const float *float_src;
Timothy B. Terriberrya8f04b22013-03-18 14:42:44 -0700630 opus_int32 i;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500631 float_src = (const float *)src;
632 for (i=0;i<frame_size;i++)
633#if defined(FIXED_POINT)
634 dst[i*dst_stride] = FLOAT2INT16(float_src[i*src_stride+src_channel]);
635#else
636 dst[i*dst_stride] = float_src[i*src_stride+src_channel];
637#endif
638}
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400639
640static void channel_pos(int channels, int pos[8])
641{
642 /* Position in the mix: 0 don't mix, 1: left, 2: center, 3:right */
643 if (channels==4)
644 {
645 pos[0]=1;
646 pos[1]=3;
647 pos[2]=1;
648 pos[3]=3;
649 } else if (channels==3||channels==5||channels==6)
650 {
651 pos[0]=1;
652 pos[1]=2;
653 pos[2]=3;
654 pos[3]=1;
655 pos[4]=3;
656 pos[5]=0;
657 } else if (channels==7)
658 {
659 pos[0]=1;
660 pos[1]=2;
661 pos[2]=3;
662 pos[3]=1;
663 pos[4]=3;
664 pos[5]=2;
665 pos[6]=0;
666 } else if (channels==8)
667 {
668 pos[0]=1;
669 pos[1]=2;
670 pos[2]=3;
671 pos[3]=1;
672 pos[4]=3;
673 pos[5]=1;
674 pos[6]=3;
675 pos[7]=0;
676 }
677}
678
679static void opus_surround_downmix_float(
680 opus_val16 *dst,
681 const void *src,
682 int channels,
683 int frame_size
684)
685{
686 const float *float_src;
687 opus_int32 i;
688 int pos[8] = {0};
689 int c;
690 float_src = (const float *)src;
691
692 channel_pos(channels, pos);
693 for (i=0;i<2*frame_size;i++)
694 dst[i]=0;
695
696 for (c=0;c<channels;c++)
697 {
698 if (pos[c]==1||pos[c]==2)
699 {
700 for (i=0;i<frame_size;i++)
701#if defined(FIXED_POINT)
702 dst[2*i] += SHR16(FLOAT2INT16(float_src[i*channels+c]),3);
703#else
704 dst[2*i] += float_src[i*channels+c];
705#endif
706 }
707 if (pos[c]==2||pos[c]==3)
708 {
709 for (i=0;i<frame_size;i++)
710#if defined(FIXED_POINT)
711 dst[2*i+1] += SHR16(FLOAT2INT16(float_src[i*channels+c]),3);
712#else
713 dst[2*i+1] += float_src[i*channels+c];
714#endif
715 }
716 }
717}
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500718#endif
719
720static void opus_copy_channel_in_short(
721 opus_val16 *dst,
722 int dst_stride,
723 const void *src,
724 int src_stride,
725 int src_channel,
726 int frame_size
727)
728{
729 const opus_int16 *short_src;
Timothy B. Terriberrya8f04b22013-03-18 14:42:44 -0700730 opus_int32 i;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500731 short_src = (const opus_int16 *)src;
732 for (i=0;i<frame_size;i++)
733#if defined(FIXED_POINT)
734 dst[i*dst_stride] = short_src[i*src_stride+src_channel];
735#else
736 dst[i*dst_stride] = (1/32768.f)*short_src[i*src_stride+src_channel];
737#endif
738}
739
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400740static void opus_surround_downmix_short(
741 opus_val16 *dst,
742 const void *src,
743 int channels,
744 int frame_size
745)
746{
747 const opus_int16 *short_src;
748 opus_int32 i;
749 int pos[8] = {0};
750 int c;
751 short_src = (const opus_int16 *)src;
752
753 channel_pos(channels, pos);
754 for (i=0;i<2*frame_size;i++)
755 dst[i]=0;
756
757 for (c=0;c<channels;c++)
758 {
759 if (pos[c]==1||pos[c]==2)
760 {
761 for (i=0;i<frame_size;i++)
762#if defined(FIXED_POINT)
763 dst[2*i] += SHR16(short_src[i*channels+c],3);
764#else
765 dst[2*i] += (1/32768.f)*short_src[i*channels+c];
766#endif
767 }
768 if (pos[c]==2||pos[c]==3)
769 {
770 for (i=0;i<frame_size;i++)
771#if defined(FIXED_POINT)
772 dst[2*i+1] += SHR16(short_src[i*channels+c],3);
773#else
774 dst[2*i+1] += (1/32768.f)*short_src[i*channels+c];
775#endif
776 }
777 }
778}
779
780
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500781#ifdef FIXED_POINT
782int opus_multistream_encode(
783 OpusMSEncoder *st,
784 const opus_val16 *pcm,
785 int frame_size,
786 unsigned char *data,
787 opus_int32 max_data_bytes
788)
789{
790 return opus_multistream_encode_native(st, opus_copy_channel_in_short,
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400791 pcm, frame_size, data, max_data_bytes, 16, opus_surround_downmix_float);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500792}
793
794#ifndef DISABLE_FLOAT_API
795int opus_multistream_encode_float(
796 OpusMSEncoder *st,
797 const float *pcm,
798 int frame_size,
799 unsigned char *data,
800 opus_int32 max_data_bytes
801)
802{
803 return opus_multistream_encode_native(st, opus_copy_channel_in_float,
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400804 pcm, frame_size, data, max_data_bytes, 16, opus_surround_downmix_short);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500805}
806#endif
807
808#else
809
810int opus_multistream_encode_float
811(
812 OpusMSEncoder *st,
813 const opus_val16 *pcm,
814 int frame_size,
815 unsigned char *data,
816 opus_int32 max_data_bytes
817)
818{
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500819 int channels = st->layout.nb_streams + st->layout.nb_coupled_streams;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500820 return opus_multistream_encode_native(st, opus_copy_channel_in_float,
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400821 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 -0500822}
823
824int opus_multistream_encode(
825 OpusMSEncoder *st,
826 const opus_int16 *pcm,
827 int frame_size,
828 unsigned char *data,
829 opus_int32 max_data_bytes
830)
831{
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500832 int channels = st->layout.nb_streams + st->layout.nb_coupled_streams;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500833 return opus_multistream_encode_native(st, opus_copy_channel_in_short,
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400834 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 -0500835}
836#endif
837
838int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
839{
840 va_list ap;
841 int coupled_size, mono_size;
842 char *ptr;
843 int ret = OPUS_OK;
844
845 va_start(ap, request);
846
847 coupled_size = opus_encoder_get_size(2);
848 mono_size = opus_encoder_get_size(1);
849 ptr = (char*)st + align(sizeof(OpusMSEncoder));
850 switch (request)
851 {
852 case OPUS_SET_BITRATE_REQUEST:
853 {
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500854 opus_int32 value = va_arg(ap, opus_int32);
Gregory Maxwellb271dae2013-06-29 20:25:55 -0700855 if (value<0 && value!=OPUS_AUTO && value!=OPUS_BITRATE_MAX) {
Jean-Marc Valin95561be2012-12-17 17:54:01 -0500856 goto bad_arg;
Gregory Maxwellb271dae2013-06-29 20:25:55 -0700857 }
Jean-Marc Valin74483662012-12-17 16:23:42 -0500858 st->bitrate_bps = value;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500859 }
860 break;
861 case OPUS_GET_BITRATE_REQUEST:
862 {
863 int s;
864 opus_int32 *value = va_arg(ap, opus_int32*);
Gregory Maxwellb271dae2013-06-29 20:25:55 -0700865 if (!value) {
866 goto bad_arg;
867 }
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500868 *value = 0;
869 for (s=0;s<st->layout.nb_streams;s++)
870 {
871 opus_int32 rate;
872 OpusEncoder *enc;
873 enc = (OpusEncoder*)ptr;
874 if (s < st->layout.nb_coupled_streams)
875 ptr += align(coupled_size);
876 else
877 ptr += align(mono_size);
878 opus_encoder_ctl(enc, request, &rate);
879 *value += rate;
880 }
881 }
882 break;
883 case OPUS_GET_LSB_DEPTH_REQUEST:
884 case OPUS_GET_VBR_REQUEST:
885 case OPUS_GET_APPLICATION_REQUEST:
886 case OPUS_GET_BANDWIDTH_REQUEST:
887 case OPUS_GET_COMPLEXITY_REQUEST:
888 case OPUS_GET_PACKET_LOSS_PERC_REQUEST:
889 case OPUS_GET_DTX_REQUEST:
890 case OPUS_GET_VOICE_RATIO_REQUEST:
891 case OPUS_GET_VBR_CONSTRAINT_REQUEST:
892 case OPUS_GET_SIGNAL_REQUEST:
893 case OPUS_GET_LOOKAHEAD_REQUEST:
894 case OPUS_GET_SAMPLE_RATE_REQUEST:
895 case OPUS_GET_INBAND_FEC_REQUEST:
896 case OPUS_GET_FORCE_CHANNELS_REQUEST:
897 {
898 OpusEncoder *enc;
899 /* For int32* GET params, just query the first stream */
900 opus_int32 *value = va_arg(ap, opus_int32*);
901 enc = (OpusEncoder*)ptr;
902 ret = opus_encoder_ctl(enc, request, value);
903 }
904 break;
905 case OPUS_GET_FINAL_RANGE_REQUEST:
906 {
907 int s;
908 opus_uint32 *value = va_arg(ap, opus_uint32*);
909 opus_uint32 tmp;
Gregory Maxwellb271dae2013-06-29 20:25:55 -0700910 if (!value) {
911 goto bad_arg;
912 }
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500913 *value=0;
914 for (s=0;s<st->layout.nb_streams;s++)
915 {
916 OpusEncoder *enc;
917 enc = (OpusEncoder*)ptr;
918 if (s < st->layout.nb_coupled_streams)
919 ptr += align(coupled_size);
920 else
921 ptr += align(mono_size);
922 ret = opus_encoder_ctl(enc, request, &tmp);
923 if (ret != OPUS_OK) break;
924 *value ^= tmp;
925 }
926 }
927 break;
928 case OPUS_SET_LSB_DEPTH_REQUEST:
929 case OPUS_SET_COMPLEXITY_REQUEST:
930 case OPUS_SET_VBR_REQUEST:
931 case OPUS_SET_VBR_CONSTRAINT_REQUEST:
932 case OPUS_SET_BANDWIDTH_REQUEST:
933 case OPUS_SET_SIGNAL_REQUEST:
934 case OPUS_SET_APPLICATION_REQUEST:
935 case OPUS_SET_INBAND_FEC_REQUEST:
936 case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
937 case OPUS_SET_DTX_REQUEST:
938 case OPUS_SET_FORCE_MODE_REQUEST:
939 case OPUS_SET_FORCE_CHANNELS_REQUEST:
940 {
941 int s;
942 /* This works for int32 params */
943 opus_int32 value = va_arg(ap, opus_int32);
944 for (s=0;s<st->layout.nb_streams;s++)
945 {
946 OpusEncoder *enc;
947
948 enc = (OpusEncoder*)ptr;
949 if (s < st->layout.nb_coupled_streams)
950 ptr += align(coupled_size);
951 else
952 ptr += align(mono_size);
953 ret = opus_encoder_ctl(enc, request, value);
954 if (ret != OPUS_OK)
955 break;
956 }
957 }
958 break;
959 case OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST:
960 {
961 int s;
962 opus_int32 stream_id;
963 OpusEncoder **value;
964 stream_id = va_arg(ap, opus_int32);
965 if (stream_id<0 || stream_id >= st->layout.nb_streams)
966 ret = OPUS_BAD_ARG;
967 value = va_arg(ap, OpusEncoder**);
Gregory Maxwellb271dae2013-06-29 20:25:55 -0700968 if (!value) {
969 goto bad_arg;
970 }
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500971 for (s=0;s<stream_id;s++)
972 {
973 if (s < st->layout.nb_coupled_streams)
974 ptr += align(coupled_size);
975 else
976 ptr += align(mono_size);
977 }
978 *value = (OpusEncoder*)ptr;
979 }
Jean-Marc Valin74483662012-12-17 16:23:42 -0500980 break;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500981 case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST:
Jean-Marc Valin74483662012-12-17 16:23:42 -0500982 {
983 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin74483662012-12-17 16:23:42 -0500984 st->variable_duration = value;
985 }
986 break;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500987 case OPUS_GET_EXPERT_FRAME_DURATION_REQUEST:
Jean-Marc Valin74483662012-12-17 16:23:42 -0500988 {
989 opus_int32 *value = va_arg(ap, opus_int32*);
Gregory Maxwellb271dae2013-06-29 20:25:55 -0700990 if (!value) {
991 goto bad_arg;
992 }
Jean-Marc Valin74483662012-12-17 16:23:42 -0500993 *value = st->variable_duration;
994 }
995 break;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500996 default:
997 ret = OPUS_UNIMPLEMENTED;
998 break;
999 }
1000
1001 va_end(ap);
1002 return ret;
Jean-Marc Valin74483662012-12-17 16:23:42 -05001003bad_arg:
1004 va_end(ap);
1005 return OPUS_BAD_ARG;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -05001006}
1007
1008void opus_multistream_encoder_destroy(OpusMSEncoder *st)
1009{
1010 opus_free(st);
1011}