blob: 163e73c218b05c51eaf11071612446dc2ddcd88b [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 Valina4dccd32013-05-04 23:54:20 -0400192 if (surround && st->layout.nb_channels>2)
193 {
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 Valin1b723862013-04-25 21:34:04 -0400261 opus_multistream_encoder_init_impl(st, Fs, channels, *streams, *coupled_streams, mapping, application, 1);
262 return OPUS_OK;
263}
264
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500265OpusMSEncoder *opus_multistream_encoder_create(
266 opus_int32 Fs,
267 int channels,
268 int streams,
269 int coupled_streams,
270 const unsigned char *mapping,
271 int application,
272 int *error
273)
274{
275 int ret;
276 OpusMSEncoder *st;
277 if ((channels>255) || (channels<1) || (coupled_streams>streams) ||
278 (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0))
279 {
280 if (error)
281 *error = OPUS_BAD_ARG;
282 return NULL;
283 }
284 st = (OpusMSEncoder *)opus_alloc(opus_multistream_encoder_get_size(streams, coupled_streams));
285 if (st==NULL)
286 {
287 if (error)
288 *error = OPUS_ALLOC_FAIL;
289 return NULL;
290 }
291 ret = opus_multistream_encoder_init(st, Fs, channels, streams, coupled_streams, mapping, application);
292 if (ret != OPUS_OK)
293 {
294 opus_free(st);
295 st = NULL;
296 }
297 if (error)
298 *error = ret;
299 return st;
300}
301
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400302OpusMSEncoder *opus_multistream_surround_encoder_create(
303 opus_int32 Fs,
304 int channels,
305 int mapping_family,
306 int *streams,
307 int *coupled_streams,
308 unsigned char *mapping,
309 int application,
310 int *error
311)
312{
313 int ret;
314 OpusMSEncoder *st;
315 if ((channels>255) || (channels<1))
316 {
317 if (error)
318 *error = OPUS_BAD_ARG;
319 return NULL;
320 }
321 st = (OpusMSEncoder *)opus_alloc(opus_multistream_surround_encoder_get_size(channels, mapping_family));
322 if (st==NULL)
323 {
324 if (error)
325 *error = OPUS_ALLOC_FAIL;
326 return NULL;
327 }
328 ret = opus_multistream_surround_encoder_init(st, Fs, channels, mapping_family, streams, coupled_streams, mapping, application);
329 if (ret != OPUS_OK)
330 {
331 opus_free(st);
332 st = NULL;
333 }
334 if (error)
335 *error = ret;
336 return st;
337}
338
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500339typedef void (*opus_copy_channel_in_func)(
340 opus_val16 *dst,
341 int dst_stride,
342 const void *src,
343 int src_stride,
344 int src_channel,
345 int frame_size
346);
347
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400348typedef void (*opus_surround_downmix_funct)(
349 opus_val16 *dst,
350 const void *src,
351 int channels,
352 int frame_size
353);
354
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400355static void surround_rate_allocation(
356 OpusMSEncoder *st,
357 opus_int32 *rate,
358 int frame_size
359 )
360{
361 int i;
362 opus_int32 channel_rate;
363 opus_int32 Fs;
364 char *ptr;
365 int coupled_ratio; /* Q8 */
366 int lfe_ratio; /* Q8 */
367
368 ptr = (char*)st + align(sizeof(OpusMSEncoder));
369 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
370
371 /* Should depend on the bitrate, for now we assume coupled streams get 60% more bits than mono */
372 coupled_ratio = 410;
373 /* Should depend on the bitrate, for now we assume LFE gets 1/12 the bits of mono */
374 lfe_ratio = 32;
375
376 /* Compute bitrate allocation between streams */
377 if (st->bitrate_bps==OPUS_AUTO)
378 {
379 channel_rate = Fs+60*Fs/frame_size;
380 } else if (st->bitrate_bps==OPUS_BITRATE_MAX)
381 {
382 channel_rate = 300000;
383 } else {
384 int total = ((st->layout.nb_streams-st->layout.nb_coupled_streams-(st->lfe_stream!=-1))<<8) /* mono */
385 + coupled_ratio*st->layout.nb_coupled_streams /* stereo */
386 + (st->lfe_stream!=-1)*lfe_ratio;
Jean-Marc Valinb08c4ca2013-04-26 16:32:10 -0400387 channel_rate = 256*(st->bitrate_bps-2000)/total;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400388 }
389#ifndef FIXED_POINT
390 if (st->variable_duration==OPUS_FRAMESIZE_VARIABLE && frame_size != Fs/50)
391 {
392 opus_int32 bonus;
393 bonus = 60*(Fs/frame_size-50);
394 channel_rate += bonus;
395 }
396#endif
397
398 for (i=0;i<st->layout.nb_streams;i++)
399 {
400 if (i<st->layout.nb_coupled_streams)
401 rate[i] = channel_rate*coupled_ratio>>8;
402 else if (i!=st->lfe_stream)
403 rate[i] = channel_rate;
404 else
Jean-Marc Valinb08c4ca2013-04-26 16:32:10 -0400405 rate[i] = 2000+(channel_rate*lfe_ratio>>8);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400406 }
407
408
409}
410
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500411/* Max size in case the encoder decides to return three frames */
412#define MS_FRAME_TMP (3*1275+7)
413static int opus_multistream_encode_native
414(
415 OpusMSEncoder *st,
416 opus_copy_channel_in_func copy_channel_in,
417 const void *pcm,
418 int frame_size,
419 unsigned char *data,
Jean-Marc Valinb3eba242012-12-20 23:11:53 -0500420 opus_int32 max_data_bytes,
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400421 int lsb_depth,
422 opus_surround_downmix_funct surround_downmix
Jean-Marc Valin10a34a52012-12-20 00:23:01 -0500423#ifndef FIXED_POINT
424 , downmix_func downmix
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500425 , const void *pcm_analysis
Jean-Marc Valin10a34a52012-12-20 00:23:01 -0500426#endif
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500427)
428{
429 opus_int32 Fs;
430 int coupled_size;
431 int mono_size;
432 int s;
433 char *ptr;
434 int tot_size;
435 VARDECL(opus_val16, buf);
436 unsigned char tmp_data[MS_FRAME_TMP];
437 OpusRepacketizer rp;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500438 opus_int32 complexity;
439 AnalysisInfo analysis_info;
440 const CELTMode *celt_mode;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400441 opus_int32 bitrates[256];
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400442 opus_val16 bandLogE[42];
443 opus_val16 bandLogE_mono[21];
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500444 ALLOC_STACK;
445
446 ptr = (char*)st + align(sizeof(OpusMSEncoder));
447 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500448 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_COMPLEXITY(&complexity));
449 opus_encoder_ctl((OpusEncoder*)ptr, CELT_GET_MODE(&celt_mode));
Jean-Marc Valin74483662012-12-17 16:23:42 -0500450
451 if (400*frame_size < Fs)
452 {
453 RESTORE_STACK;
454 return OPUS_BAD_ARG;
455 }
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500456#ifndef FIXED_POINT
457 analysis_info.valid = 0;
458 if (complexity >= 7 && Fs==48000)
Jean-Marc Valin74483662012-12-17 16:23:42 -0500459 {
Jean-Marc Valin74483662012-12-17 16:23:42 -0500460 opus_int32 delay_compensation;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500461 int channels;
Jean-Marc Valin74483662012-12-17 16:23:42 -0500462
463 channels = st->layout.nb_streams + st->layout.nb_coupled_streams;
464 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_LOOKAHEAD(&delay_compensation));
465 delay_compensation -= Fs/400;
Jean-Marc Valin74483662012-12-17 16:23:42 -0500466
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500467 frame_size = run_analysis(&st->analysis, celt_mode, pcm, pcm_analysis,
468 frame_size, st->variable_duration, channels, Fs, st->bitrate_bps, delay_compensation, lsb_depth, downmix, &analysis_info);
469 } else
470#endif
471 {
472 frame_size = frame_size_select(frame_size, st->variable_duration, Fs);
473 }
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500474 /* Validate frame_size before using it to allocate stack space.
475 This mirrors the checks in opus_encode[_float](). */
476 if (400*frame_size != Fs && 200*frame_size != Fs &&
477 100*frame_size != Fs && 50*frame_size != Fs &&
478 25*frame_size != Fs && 50*frame_size != 3*Fs)
479 {
480 RESTORE_STACK;
481 return OPUS_BAD_ARG;
482 }
483 ALLOC(buf, 2*frame_size, opus_val16);
484 coupled_size = opus_encoder_get_size(2);
485 mono_size = opus_encoder_get_size(1);
486
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400487 if (st->surround && st->layout.nb_channels>2)
488 {
489 int i;
490 unsigned char dummy[512];
491 /* Temporary kludge -- remove */
492 OpusEncoder *downmix_enc;
493
494 ptr = (char*)st + align(sizeof(OpusMSEncoder));
495 for (s=0;s<st->layout.nb_streams;s++)
496 {
497 if (s < st->layout.nb_coupled_streams)
498 ptr += align(coupled_size);
499 else
500 ptr += align(mono_size);
501 }
502 downmix_enc = (OpusEncoder*)ptr;
503 surround_downmix(buf, pcm, st->layout.nb_channels, frame_size);
504 opus_encoder_ctl(downmix_enc, OPUS_SET_ENERGY_SAVE(bandLogE));
505 opus_encoder_ctl(downmix_enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
506 opus_encoder_ctl(downmix_enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY));
507 opus_encoder_ctl(downmix_enc, OPUS_SET_FORCE_CHANNELS(2));
508 opus_encode_native(downmix_enc, buf, frame_size, dummy, 512, lsb_depth
509#ifndef FIXED_POINT
510 , &analysis_info
511#endif
512 );
513 for(i=0;i<21;i++)
514 bandLogE_mono[i] = MAX16(bandLogE[i], bandLogE[21+i]);
515 }
516
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500517 if (max_data_bytes < 4*st->layout.nb_streams-1)
518 {
519 RESTORE_STACK;
520 return OPUS_BUFFER_TOO_SMALL;
521 }
Jean-Marc Valin74483662012-12-17 16:23:42 -0500522
523 /* Compute bitrate allocation between streams (this could be a lot better) */
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400524 surround_rate_allocation(st, bitrates, frame_size);
525
Jean-Marc Valin74483662012-12-17 16:23:42 -0500526 ptr = (char*)st + align(sizeof(OpusMSEncoder));
527 for (s=0;s<st->layout.nb_streams;s++)
528 {
529 OpusEncoder *enc;
530 enc = (OpusEncoder*)ptr;
531 if (s < st->layout.nb_coupled_streams)
532 ptr += align(coupled_size);
533 else
534 ptr += align(mono_size);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400535 opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrates[s]));
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400536 if (st->surround)
537 {
538 opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY));
539 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
540 if (s < st->layout.nb_coupled_streams)
541 opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(2));
542 }
Jean-Marc Valin74483662012-12-17 16:23:42 -0500543 }
544
545 ptr = (char*)st + align(sizeof(OpusMSEncoder));
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500546 /* Counting ToC */
547 tot_size = 0;
548 for (s=0;s<st->layout.nb_streams;s++)
549 {
550 OpusEncoder *enc;
551 int len;
552 int curr_max;
553
554 opus_repacketizer_init(&rp);
555 enc = (OpusEncoder*)ptr;
556 if (s < st->layout.nb_coupled_streams)
557 {
558 int left, right;
559 left = get_left_channel(&st->layout, s, -1);
560 right = get_right_channel(&st->layout, s, -1);
561 (*copy_channel_in)(buf, 2,
562 pcm, st->layout.nb_channels, left, frame_size);
563 (*copy_channel_in)(buf+1, 2,
564 pcm, st->layout.nb_channels, right, frame_size);
565 ptr += align(coupled_size);
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400566 /* FIXME: This isn't correct for the coupled center channels in
567 6.1 surround configuration */
568 if (st->surround)
569 opus_encoder_ctl(enc, OPUS_SET_ENERGY_MASK(bandLogE));
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500570 } else {
571 int chan = get_mono_channel(&st->layout, s, -1);
572 (*copy_channel_in)(buf, 1,
573 pcm, st->layout.nb_channels, chan, frame_size);
574 ptr += align(mono_size);
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400575 if (st->surround)
576 opus_encoder_ctl(enc, OPUS_SET_ENERGY_MASK(bandLogE_mono));
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500577 }
578 /* number of bytes left (+Toc) */
579 curr_max = max_data_bytes - tot_size;
580 /* Reserve three bytes for the last stream and four for the others */
581 curr_max -= IMAX(0,4*(st->layout.nb_streams-s-1)-1);
582 curr_max = IMIN(curr_max,MS_FRAME_TMP);
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500583 len = opus_encode_native(enc, buf, frame_size, tmp_data, curr_max, lsb_depth
584#ifndef FIXED_POINT
585 , &analysis_info
586#endif
587 );
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500588 if (len<0)
589 {
590 RESTORE_STACK;
591 return len;
592 }
593 /* We need to use the repacketizer to add the self-delimiting lengths
594 while taking into account the fact that the encoder can now return
595 more than one frame at a time (e.g. 60 ms CELT-only) */
596 opus_repacketizer_cat(&rp, tmp_data, len);
597 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);
598 data += len;
599 tot_size += len;
600 }
601 RESTORE_STACK;
602 return tot_size;
603
604}
605
606#if !defined(DISABLE_FLOAT_API)
607static void opus_copy_channel_in_float(
608 opus_val16 *dst,
609 int dst_stride,
610 const void *src,
611 int src_stride,
612 int src_channel,
613 int frame_size
614)
615{
616 const float *float_src;
Timothy B. Terriberrya8f04b22013-03-18 14:42:44 -0700617 opus_int32 i;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500618 float_src = (const float *)src;
619 for (i=0;i<frame_size;i++)
620#if defined(FIXED_POINT)
621 dst[i*dst_stride] = FLOAT2INT16(float_src[i*src_stride+src_channel]);
622#else
623 dst[i*dst_stride] = float_src[i*src_stride+src_channel];
624#endif
625}
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400626
627static void channel_pos(int channels, int pos[8])
628{
629 /* Position in the mix: 0 don't mix, 1: left, 2: center, 3:right */
630 if (channels==4)
631 {
632 pos[0]=1;
633 pos[1]=3;
634 pos[2]=1;
635 pos[3]=3;
636 } else if (channels==3||channels==5||channels==6)
637 {
638 pos[0]=1;
639 pos[1]=2;
640 pos[2]=3;
641 pos[3]=1;
642 pos[4]=3;
643 pos[5]=0;
644 } else if (channels==7)
645 {
646 pos[0]=1;
647 pos[1]=2;
648 pos[2]=3;
649 pos[3]=1;
650 pos[4]=3;
651 pos[5]=2;
652 pos[6]=0;
653 } else if (channels==8)
654 {
655 pos[0]=1;
656 pos[1]=2;
657 pos[2]=3;
658 pos[3]=1;
659 pos[4]=3;
660 pos[5]=1;
661 pos[6]=3;
662 pos[7]=0;
663 }
664}
665
666static void opus_surround_downmix_float(
667 opus_val16 *dst,
668 const void *src,
669 int channels,
670 int frame_size
671)
672{
673 const float *float_src;
674 opus_int32 i;
675 int pos[8] = {0};
676 int c;
677 float_src = (const float *)src;
678
679 channel_pos(channels, pos);
680 for (i=0;i<2*frame_size;i++)
681 dst[i]=0;
682
683 for (c=0;c<channels;c++)
684 {
685 if (pos[c]==1||pos[c]==2)
686 {
687 for (i=0;i<frame_size;i++)
688#if defined(FIXED_POINT)
689 dst[2*i] += SHR16(FLOAT2INT16(float_src[i*channels+c]),3);
690#else
691 dst[2*i] += float_src[i*channels+c];
692#endif
693 }
694 if (pos[c]==2||pos[c]==3)
695 {
696 for (i=0;i<frame_size;i++)
697#if defined(FIXED_POINT)
698 dst[2*i+1] += SHR16(FLOAT2INT16(float_src[i*channels+c]),3);
699#else
700 dst[2*i+1] += float_src[i*channels+c];
701#endif
702 }
703 }
704}
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500705#endif
706
707static void opus_copy_channel_in_short(
708 opus_val16 *dst,
709 int dst_stride,
710 const void *src,
711 int src_stride,
712 int src_channel,
713 int frame_size
714)
715{
716 const opus_int16 *short_src;
Timothy B. Terriberrya8f04b22013-03-18 14:42:44 -0700717 opus_int32 i;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500718 short_src = (const opus_int16 *)src;
719 for (i=0;i<frame_size;i++)
720#if defined(FIXED_POINT)
721 dst[i*dst_stride] = short_src[i*src_stride+src_channel];
722#else
723 dst[i*dst_stride] = (1/32768.f)*short_src[i*src_stride+src_channel];
724#endif
725}
726
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400727static void opus_surround_downmix_short(
728 opus_val16 *dst,
729 const void *src,
730 int channels,
731 int frame_size
732)
733{
734 const opus_int16 *short_src;
735 opus_int32 i;
736 int pos[8] = {0};
737 int c;
738 short_src = (const opus_int16 *)src;
739
740 channel_pos(channels, pos);
741 for (i=0;i<2*frame_size;i++)
742 dst[i]=0;
743
744 for (c=0;c<channels;c++)
745 {
746 if (pos[c]==1||pos[c]==2)
747 {
748 for (i=0;i<frame_size;i++)
749#if defined(FIXED_POINT)
750 dst[2*i] += SHR16(short_src[i*channels+c],3);
751#else
752 dst[2*i] += (1/32768.f)*short_src[i*channels+c];
753#endif
754 }
755 if (pos[c]==2||pos[c]==3)
756 {
757 for (i=0;i<frame_size;i++)
758#if defined(FIXED_POINT)
759 dst[2*i+1] += SHR16(short_src[i*channels+c],3);
760#else
761 dst[2*i+1] += (1/32768.f)*short_src[i*channels+c];
762#endif
763 }
764 }
765}
766
767
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500768#ifdef FIXED_POINT
769int opus_multistream_encode(
770 OpusMSEncoder *st,
771 const opus_val16 *pcm,
772 int frame_size,
773 unsigned char *data,
774 opus_int32 max_data_bytes
775)
776{
777 return opus_multistream_encode_native(st, opus_copy_channel_in_short,
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400778 pcm, frame_size, data, max_data_bytes, 16, opus_surround_downmix_float);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500779}
780
781#ifndef DISABLE_FLOAT_API
782int opus_multistream_encode_float(
783 OpusMSEncoder *st,
784 const float *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_float,
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400791 pcm, frame_size, data, max_data_bytes, 16, opus_surround_downmix_short);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500792}
793#endif
794
795#else
796
797int opus_multistream_encode_float
798(
799 OpusMSEncoder *st,
800 const opus_val16 *pcm,
801 int frame_size,
802 unsigned char *data,
803 opus_int32 max_data_bytes
804)
805{
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500806 int channels = st->layout.nb_streams + st->layout.nb_coupled_streams;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500807 return opus_multistream_encode_native(st, opus_copy_channel_in_float,
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400808 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 -0500809}
810
811int opus_multistream_encode(
812 OpusMSEncoder *st,
813 const opus_int16 *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_short,
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400821 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 -0500822}
823#endif
824
825int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
826{
827 va_list ap;
828 int coupled_size, mono_size;
829 char *ptr;
830 int ret = OPUS_OK;
831
832 va_start(ap, request);
833
834 coupled_size = opus_encoder_get_size(2);
835 mono_size = opus_encoder_get_size(1);
836 ptr = (char*)st + align(sizeof(OpusMSEncoder));
837 switch (request)
838 {
839 case OPUS_SET_BITRATE_REQUEST:
840 {
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500841 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin95561be2012-12-17 17:54:01 -0500842 if (value<0 && value!=OPUS_AUTO && value!=OPUS_BITRATE_MAX)
843 goto bad_arg;
Jean-Marc Valin74483662012-12-17 16:23:42 -0500844 st->bitrate_bps = value;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500845 }
846 break;
847 case OPUS_GET_BITRATE_REQUEST:
848 {
849 int s;
850 opus_int32 *value = va_arg(ap, opus_int32*);
851 *value = 0;
852 for (s=0;s<st->layout.nb_streams;s++)
853 {
854 opus_int32 rate;
855 OpusEncoder *enc;
856 enc = (OpusEncoder*)ptr;
857 if (s < st->layout.nb_coupled_streams)
858 ptr += align(coupled_size);
859 else
860 ptr += align(mono_size);
861 opus_encoder_ctl(enc, request, &rate);
862 *value += rate;
863 }
864 }
865 break;
866 case OPUS_GET_LSB_DEPTH_REQUEST:
867 case OPUS_GET_VBR_REQUEST:
868 case OPUS_GET_APPLICATION_REQUEST:
869 case OPUS_GET_BANDWIDTH_REQUEST:
870 case OPUS_GET_COMPLEXITY_REQUEST:
871 case OPUS_GET_PACKET_LOSS_PERC_REQUEST:
872 case OPUS_GET_DTX_REQUEST:
873 case OPUS_GET_VOICE_RATIO_REQUEST:
874 case OPUS_GET_VBR_CONSTRAINT_REQUEST:
875 case OPUS_GET_SIGNAL_REQUEST:
876 case OPUS_GET_LOOKAHEAD_REQUEST:
877 case OPUS_GET_SAMPLE_RATE_REQUEST:
878 case OPUS_GET_INBAND_FEC_REQUEST:
879 case OPUS_GET_FORCE_CHANNELS_REQUEST:
880 {
881 OpusEncoder *enc;
882 /* For int32* GET params, just query the first stream */
883 opus_int32 *value = va_arg(ap, opus_int32*);
884 enc = (OpusEncoder*)ptr;
885 ret = opus_encoder_ctl(enc, request, value);
886 }
887 break;
888 case OPUS_GET_FINAL_RANGE_REQUEST:
889 {
890 int s;
891 opus_uint32 *value = va_arg(ap, opus_uint32*);
892 opus_uint32 tmp;
893 *value=0;
894 for (s=0;s<st->layout.nb_streams;s++)
895 {
896 OpusEncoder *enc;
897 enc = (OpusEncoder*)ptr;
898 if (s < st->layout.nb_coupled_streams)
899 ptr += align(coupled_size);
900 else
901 ptr += align(mono_size);
902 ret = opus_encoder_ctl(enc, request, &tmp);
903 if (ret != OPUS_OK) break;
904 *value ^= tmp;
905 }
906 }
907 break;
908 case OPUS_SET_LSB_DEPTH_REQUEST:
909 case OPUS_SET_COMPLEXITY_REQUEST:
910 case OPUS_SET_VBR_REQUEST:
911 case OPUS_SET_VBR_CONSTRAINT_REQUEST:
912 case OPUS_SET_BANDWIDTH_REQUEST:
913 case OPUS_SET_SIGNAL_REQUEST:
914 case OPUS_SET_APPLICATION_REQUEST:
915 case OPUS_SET_INBAND_FEC_REQUEST:
916 case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
917 case OPUS_SET_DTX_REQUEST:
918 case OPUS_SET_FORCE_MODE_REQUEST:
919 case OPUS_SET_FORCE_CHANNELS_REQUEST:
920 {
921 int s;
922 /* This works for int32 params */
923 opus_int32 value = va_arg(ap, opus_int32);
924 for (s=0;s<st->layout.nb_streams;s++)
925 {
926 OpusEncoder *enc;
927
928 enc = (OpusEncoder*)ptr;
929 if (s < st->layout.nb_coupled_streams)
930 ptr += align(coupled_size);
931 else
932 ptr += align(mono_size);
933 ret = opus_encoder_ctl(enc, request, value);
934 if (ret != OPUS_OK)
935 break;
936 }
937 }
938 break;
939 case OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST:
940 {
941 int s;
942 opus_int32 stream_id;
943 OpusEncoder **value;
944 stream_id = va_arg(ap, opus_int32);
945 if (stream_id<0 || stream_id >= st->layout.nb_streams)
946 ret = OPUS_BAD_ARG;
947 value = va_arg(ap, OpusEncoder**);
948 for (s=0;s<stream_id;s++)
949 {
950 if (s < st->layout.nb_coupled_streams)
951 ptr += align(coupled_size);
952 else
953 ptr += align(mono_size);
954 }
955 *value = (OpusEncoder*)ptr;
956 }
Jean-Marc Valin74483662012-12-17 16:23:42 -0500957 break;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500958 case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST:
Jean-Marc Valin74483662012-12-17 16:23:42 -0500959 {
960 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin74483662012-12-17 16:23:42 -0500961 st->variable_duration = value;
962 }
963 break;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500964 case OPUS_GET_EXPERT_FRAME_DURATION_REQUEST:
Jean-Marc Valin74483662012-12-17 16:23:42 -0500965 {
966 opus_int32 *value = va_arg(ap, opus_int32*);
967 *value = st->variable_duration;
968 }
969 break;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500970 default:
971 ret = OPUS_UNIMPLEMENTED;
972 break;
973 }
974
975 va_end(ap);
976 return ret;
Jean-Marc Valin74483662012-12-17 16:23:42 -0500977bad_arg:
978 va_end(ap);
979 return OPUS_BAD_ARG;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500980}
981
982void opus_multistream_encoder_destroy(OpusMSEncoder *st)
983{
984 opus_free(st);
985}
986
987