blob: 89844cbc614ee918c5ec1815183f5cf4b8f87056 [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;
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400365 int stream_offset;
366 int lfe_offset;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400367 int coupled_ratio; /* Q8 */
368 int lfe_ratio; /* Q8 */
369
370 ptr = (char*)st + align(sizeof(OpusMSEncoder));
371 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
372
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400373 /* We start by giving each stream (coupled or uncoupled) the same bitrate.
374 This models the main saving of coupled channels over uncoupled. */
375 stream_offset = 20000;
376 /* The LFE stream is an exception to the above and gets fewer bits. */
377 lfe_offset = 3500;
378 /* Coupled streams get twice the mono rate after the first 20 kb/s. */
379 coupled_ratio = 512;
380 /* 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 -0400381 lfe_ratio = 32;
382
383 /* Compute bitrate allocation between streams */
384 if (st->bitrate_bps==OPUS_AUTO)
385 {
386 channel_rate = Fs+60*Fs/frame_size;
387 } else if (st->bitrate_bps==OPUS_BITRATE_MAX)
388 {
389 channel_rate = 300000;
390 } else {
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400391 int nb_lfe;
392 int nb_uncoupled;
393 int nb_coupled;
394 int total;
395 nb_lfe = (st->lfe_stream!=-1);
396 nb_coupled = st->layout.nb_coupled_streams;
397 nb_uncoupled = st->layout.nb_streams-nb_coupled-nb_lfe;
398 total = (nb_uncoupled<<8) /* mono */
399 + coupled_ratio*nb_coupled /* stereo */
400 + nb_lfe*lfe_ratio;
401 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 -0400402 }
403#ifndef FIXED_POINT
404 if (st->variable_duration==OPUS_FRAMESIZE_VARIABLE && frame_size != Fs/50)
405 {
406 opus_int32 bonus;
407 bonus = 60*(Fs/frame_size-50);
408 channel_rate += bonus;
409 }
410#endif
411
412 for (i=0;i<st->layout.nb_streams;i++)
413 {
414 if (i<st->layout.nb_coupled_streams)
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400415 rate[i] = stream_offset+(channel_rate*coupled_ratio>>8);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400416 else if (i!=st->lfe_stream)
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400417 rate[i] = stream_offset+channel_rate;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400418 else
Jean-Marc Valind66bdc72013-05-06 16:03:39 -0400419 rate[i] = lfe_offset+(channel_rate*lfe_ratio>>8);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400420 }
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400421}
422
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500423/* Max size in case the encoder decides to return three frames */
424#define MS_FRAME_TMP (3*1275+7)
425static int opus_multistream_encode_native
426(
427 OpusMSEncoder *st,
428 opus_copy_channel_in_func copy_channel_in,
429 const void *pcm,
430 int frame_size,
431 unsigned char *data,
Jean-Marc Valinb3eba242012-12-20 23:11:53 -0500432 opus_int32 max_data_bytes,
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400433 int lsb_depth,
434 opus_surround_downmix_funct surround_downmix
Jean-Marc Valin10a34a52012-12-20 00:23:01 -0500435#ifndef FIXED_POINT
436 , downmix_func downmix
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500437 , const void *pcm_analysis
Jean-Marc Valin10a34a52012-12-20 00:23:01 -0500438#endif
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500439)
440{
441 opus_int32 Fs;
442 int coupled_size;
443 int mono_size;
444 int s;
445 char *ptr;
446 int tot_size;
447 VARDECL(opus_val16, buf);
448 unsigned char tmp_data[MS_FRAME_TMP];
449 OpusRepacketizer rp;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500450 opus_int32 complexity;
451 AnalysisInfo analysis_info;
452 const CELTMode *celt_mode;
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400453 opus_int32 bitrates[256];
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400454 opus_val16 bandLogE[42];
455 opus_val16 bandLogE_mono[21];
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500456 ALLOC_STACK;
457
458 ptr = (char*)st + align(sizeof(OpusMSEncoder));
459 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs));
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500460 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_COMPLEXITY(&complexity));
461 opus_encoder_ctl((OpusEncoder*)ptr, CELT_GET_MODE(&celt_mode));
Jean-Marc Valin74483662012-12-17 16:23:42 -0500462
463 if (400*frame_size < Fs)
464 {
465 RESTORE_STACK;
466 return OPUS_BAD_ARG;
467 }
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500468#ifndef FIXED_POINT
469 analysis_info.valid = 0;
470 if (complexity >= 7 && Fs==48000)
Jean-Marc Valin74483662012-12-17 16:23:42 -0500471 {
Jean-Marc Valin74483662012-12-17 16:23:42 -0500472 opus_int32 delay_compensation;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500473 int channels;
Jean-Marc Valin74483662012-12-17 16:23:42 -0500474
475 channels = st->layout.nb_streams + st->layout.nb_coupled_streams;
476 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_LOOKAHEAD(&delay_compensation));
477 delay_compensation -= Fs/400;
Jean-Marc Valin74483662012-12-17 16:23:42 -0500478
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500479 frame_size = run_analysis(&st->analysis, celt_mode, pcm, pcm_analysis,
480 frame_size, st->variable_duration, channels, Fs, st->bitrate_bps, delay_compensation, lsb_depth, downmix, &analysis_info);
481 } else
482#endif
483 {
484 frame_size = frame_size_select(frame_size, st->variable_duration, Fs);
485 }
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500486 /* Validate frame_size before using it to allocate stack space.
487 This mirrors the checks in opus_encode[_float](). */
488 if (400*frame_size != Fs && 200*frame_size != Fs &&
489 100*frame_size != Fs && 50*frame_size != Fs &&
490 25*frame_size != Fs && 50*frame_size != 3*Fs)
491 {
492 RESTORE_STACK;
493 return OPUS_BAD_ARG;
494 }
495 ALLOC(buf, 2*frame_size, opus_val16);
496 coupled_size = opus_encoder_get_size(2);
497 mono_size = opus_encoder_get_size(1);
498
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400499 if (st->surround && st->layout.nb_channels>2)
500 {
501 int i;
502 unsigned char dummy[512];
503 /* Temporary kludge -- remove */
504 OpusEncoder *downmix_enc;
505
506 ptr = (char*)st + align(sizeof(OpusMSEncoder));
507 for (s=0;s<st->layout.nb_streams;s++)
508 {
509 if (s < st->layout.nb_coupled_streams)
510 ptr += align(coupled_size);
511 else
512 ptr += align(mono_size);
513 }
514 downmix_enc = (OpusEncoder*)ptr;
515 surround_downmix(buf, pcm, st->layout.nb_channels, frame_size);
516 opus_encoder_ctl(downmix_enc, OPUS_SET_ENERGY_SAVE(bandLogE));
517 opus_encoder_ctl(downmix_enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
518 opus_encoder_ctl(downmix_enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY));
519 opus_encoder_ctl(downmix_enc, OPUS_SET_FORCE_CHANNELS(2));
520 opus_encode_native(downmix_enc, buf, frame_size, dummy, 512, lsb_depth
521#ifndef FIXED_POINT
522 , &analysis_info
523#endif
524 );
525 for(i=0;i<21;i++)
526 bandLogE_mono[i] = MAX16(bandLogE[i], bandLogE[21+i]);
527 }
528
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500529 if (max_data_bytes < 4*st->layout.nb_streams-1)
530 {
531 RESTORE_STACK;
532 return OPUS_BUFFER_TOO_SMALL;
533 }
Jean-Marc Valin74483662012-12-17 16:23:42 -0500534
535 /* Compute bitrate allocation between streams (this could be a lot better) */
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400536 surround_rate_allocation(st, bitrates, frame_size);
537
Jean-Marc Valin74483662012-12-17 16:23:42 -0500538 ptr = (char*)st + align(sizeof(OpusMSEncoder));
539 for (s=0;s<st->layout.nb_streams;s++)
540 {
541 OpusEncoder *enc;
542 enc = (OpusEncoder*)ptr;
543 if (s < st->layout.nb_coupled_streams)
544 ptr += align(coupled_size);
545 else
546 ptr += align(mono_size);
Jean-Marc Valin1b723862013-04-25 21:34:04 -0400547 opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrates[s]));
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400548 if (st->surround)
549 {
550 opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY));
551 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND));
552 if (s < st->layout.nb_coupled_streams)
553 opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(2));
554 }
Jean-Marc Valin74483662012-12-17 16:23:42 -0500555 }
556
557 ptr = (char*)st + align(sizeof(OpusMSEncoder));
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500558 /* Counting ToC */
559 tot_size = 0;
560 for (s=0;s<st->layout.nb_streams;s++)
561 {
562 OpusEncoder *enc;
563 int len;
564 int curr_max;
565
566 opus_repacketizer_init(&rp);
567 enc = (OpusEncoder*)ptr;
568 if (s < st->layout.nb_coupled_streams)
569 {
570 int left, right;
571 left = get_left_channel(&st->layout, s, -1);
572 right = get_right_channel(&st->layout, s, -1);
573 (*copy_channel_in)(buf, 2,
574 pcm, st->layout.nb_channels, left, frame_size);
575 (*copy_channel_in)(buf+1, 2,
576 pcm, st->layout.nb_channels, right, frame_size);
577 ptr += align(coupled_size);
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400578 /* FIXME: This isn't correct for the coupled center channels in
579 6.1 surround configuration */
580 if (st->surround)
581 opus_encoder_ctl(enc, OPUS_SET_ENERGY_MASK(bandLogE));
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500582 } else {
583 int chan = get_mono_channel(&st->layout, s, -1);
584 (*copy_channel_in)(buf, 1,
585 pcm, st->layout.nb_channels, chan, frame_size);
586 ptr += align(mono_size);
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400587 if (st->surround)
588 opus_encoder_ctl(enc, OPUS_SET_ENERGY_MASK(bandLogE_mono));
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500589 }
590 /* number of bytes left (+Toc) */
591 curr_max = max_data_bytes - tot_size;
592 /* Reserve three bytes for the last stream and four for the others */
593 curr_max -= IMAX(0,4*(st->layout.nb_streams-s-1)-1);
594 curr_max = IMIN(curr_max,MS_FRAME_TMP);
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500595 len = opus_encode_native(enc, buf, frame_size, tmp_data, curr_max, lsb_depth
596#ifndef FIXED_POINT
597 , &analysis_info
598#endif
599 );
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500600 if (len<0)
601 {
602 RESTORE_STACK;
603 return len;
604 }
605 /* We need to use the repacketizer to add the self-delimiting lengths
606 while taking into account the fact that the encoder can now return
607 more than one frame at a time (e.g. 60 ms CELT-only) */
608 opus_repacketizer_cat(&rp, tmp_data, len);
609 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);
610 data += len;
611 tot_size += len;
612 }
613 RESTORE_STACK;
614 return tot_size;
615
616}
617
618#if !defined(DISABLE_FLOAT_API)
619static void opus_copy_channel_in_float(
620 opus_val16 *dst,
621 int dst_stride,
622 const void *src,
623 int src_stride,
624 int src_channel,
625 int frame_size
626)
627{
628 const float *float_src;
Timothy B. Terriberrya8f04b22013-03-18 14:42:44 -0700629 opus_int32 i;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500630 float_src = (const float *)src;
631 for (i=0;i<frame_size;i++)
632#if defined(FIXED_POINT)
633 dst[i*dst_stride] = FLOAT2INT16(float_src[i*src_stride+src_channel]);
634#else
635 dst[i*dst_stride] = float_src[i*src_stride+src_channel];
636#endif
637}
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400638
639static void channel_pos(int channels, int pos[8])
640{
641 /* Position in the mix: 0 don't mix, 1: left, 2: center, 3:right */
642 if (channels==4)
643 {
644 pos[0]=1;
645 pos[1]=3;
646 pos[2]=1;
647 pos[3]=3;
648 } else if (channels==3||channels==5||channels==6)
649 {
650 pos[0]=1;
651 pos[1]=2;
652 pos[2]=3;
653 pos[3]=1;
654 pos[4]=3;
655 pos[5]=0;
656 } else if (channels==7)
657 {
658 pos[0]=1;
659 pos[1]=2;
660 pos[2]=3;
661 pos[3]=1;
662 pos[4]=3;
663 pos[5]=2;
664 pos[6]=0;
665 } else if (channels==8)
666 {
667 pos[0]=1;
668 pos[1]=2;
669 pos[2]=3;
670 pos[3]=1;
671 pos[4]=3;
672 pos[5]=1;
673 pos[6]=3;
674 pos[7]=0;
675 }
676}
677
678static void opus_surround_downmix_float(
679 opus_val16 *dst,
680 const void *src,
681 int channels,
682 int frame_size
683)
684{
685 const float *float_src;
686 opus_int32 i;
687 int pos[8] = {0};
688 int c;
689 float_src = (const float *)src;
690
691 channel_pos(channels, pos);
692 for (i=0;i<2*frame_size;i++)
693 dst[i]=0;
694
695 for (c=0;c<channels;c++)
696 {
697 if (pos[c]==1||pos[c]==2)
698 {
699 for (i=0;i<frame_size;i++)
700#if defined(FIXED_POINT)
701 dst[2*i] += SHR16(FLOAT2INT16(float_src[i*channels+c]),3);
702#else
703 dst[2*i] += float_src[i*channels+c];
704#endif
705 }
706 if (pos[c]==2||pos[c]==3)
707 {
708 for (i=0;i<frame_size;i++)
709#if defined(FIXED_POINT)
710 dst[2*i+1] += SHR16(FLOAT2INT16(float_src[i*channels+c]),3);
711#else
712 dst[2*i+1] += float_src[i*channels+c];
713#endif
714 }
715 }
716}
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500717#endif
718
719static void opus_copy_channel_in_short(
720 opus_val16 *dst,
721 int dst_stride,
722 const void *src,
723 int src_stride,
724 int src_channel,
725 int frame_size
726)
727{
728 const opus_int16 *short_src;
Timothy B. Terriberrya8f04b22013-03-18 14:42:44 -0700729 opus_int32 i;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500730 short_src = (const opus_int16 *)src;
731 for (i=0;i<frame_size;i++)
732#if defined(FIXED_POINT)
733 dst[i*dst_stride] = short_src[i*src_stride+src_channel];
734#else
735 dst[i*dst_stride] = (1/32768.f)*short_src[i*src_stride+src_channel];
736#endif
737}
738
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400739static void opus_surround_downmix_short(
740 opus_val16 *dst,
741 const void *src,
742 int channels,
743 int frame_size
744)
745{
746 const opus_int16 *short_src;
747 opus_int32 i;
748 int pos[8] = {0};
749 int c;
750 short_src = (const opus_int16 *)src;
751
752 channel_pos(channels, pos);
753 for (i=0;i<2*frame_size;i++)
754 dst[i]=0;
755
756 for (c=0;c<channels;c++)
757 {
758 if (pos[c]==1||pos[c]==2)
759 {
760 for (i=0;i<frame_size;i++)
761#if defined(FIXED_POINT)
762 dst[2*i] += SHR16(short_src[i*channels+c],3);
763#else
764 dst[2*i] += (1/32768.f)*short_src[i*channels+c];
765#endif
766 }
767 if (pos[c]==2||pos[c]==3)
768 {
769 for (i=0;i<frame_size;i++)
770#if defined(FIXED_POINT)
771 dst[2*i+1] += SHR16(short_src[i*channels+c],3);
772#else
773 dst[2*i+1] += (1/32768.f)*short_src[i*channels+c];
774#endif
775 }
776 }
777}
778
779
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500780#ifdef FIXED_POINT
781int opus_multistream_encode(
782 OpusMSEncoder *st,
783 const opus_val16 *pcm,
784 int frame_size,
785 unsigned char *data,
786 opus_int32 max_data_bytes
787)
788{
789 return opus_multistream_encode_native(st, opus_copy_channel_in_short,
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400790 pcm, frame_size, data, max_data_bytes, 16, opus_surround_downmix_float);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500791}
792
793#ifndef DISABLE_FLOAT_API
794int opus_multistream_encode_float(
795 OpusMSEncoder *st,
796 const float *pcm,
797 int frame_size,
798 unsigned char *data,
799 opus_int32 max_data_bytes
800)
801{
802 return opus_multistream_encode_native(st, opus_copy_channel_in_float,
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400803 pcm, frame_size, data, max_data_bytes, 16, opus_surround_downmix_short);
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500804}
805#endif
806
807#else
808
809int opus_multistream_encode_float
810(
811 OpusMSEncoder *st,
812 const opus_val16 *pcm,
813 int frame_size,
814 unsigned char *data,
815 opus_int32 max_data_bytes
816)
817{
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500818 int channels = st->layout.nb_streams + st->layout.nb_coupled_streams;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500819 return opus_multistream_encode_native(st, opus_copy_channel_in_float,
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400820 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 -0500821}
822
823int opus_multistream_encode(
824 OpusMSEncoder *st,
825 const opus_int16 *pcm,
826 int frame_size,
827 unsigned char *data,
828 opus_int32 max_data_bytes
829)
830{
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500831 int channels = st->layout.nb_streams + st->layout.nb_coupled_streams;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500832 return opus_multistream_encode_native(st, opus_copy_channel_in_short,
Jean-Marc Valina4dccd32013-05-04 23:54:20 -0400833 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 -0500834}
835#endif
836
837int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...)
838{
839 va_list ap;
840 int coupled_size, mono_size;
841 char *ptr;
842 int ret = OPUS_OK;
843
844 va_start(ap, request);
845
846 coupled_size = opus_encoder_get_size(2);
847 mono_size = opus_encoder_get_size(1);
848 ptr = (char*)st + align(sizeof(OpusMSEncoder));
849 switch (request)
850 {
851 case OPUS_SET_BITRATE_REQUEST:
852 {
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500853 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin95561be2012-12-17 17:54:01 -0500854 if (value<0 && value!=OPUS_AUTO && value!=OPUS_BITRATE_MAX)
855 goto bad_arg;
Jean-Marc Valin74483662012-12-17 16:23:42 -0500856 st->bitrate_bps = value;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500857 }
858 break;
859 case OPUS_GET_BITRATE_REQUEST:
860 {
861 int s;
862 opus_int32 *value = va_arg(ap, opus_int32*);
863 *value = 0;
864 for (s=0;s<st->layout.nb_streams;s++)
865 {
866 opus_int32 rate;
867 OpusEncoder *enc;
868 enc = (OpusEncoder*)ptr;
869 if (s < st->layout.nb_coupled_streams)
870 ptr += align(coupled_size);
871 else
872 ptr += align(mono_size);
873 opus_encoder_ctl(enc, request, &rate);
874 *value += rate;
875 }
876 }
877 break;
878 case OPUS_GET_LSB_DEPTH_REQUEST:
879 case OPUS_GET_VBR_REQUEST:
880 case OPUS_GET_APPLICATION_REQUEST:
881 case OPUS_GET_BANDWIDTH_REQUEST:
882 case OPUS_GET_COMPLEXITY_REQUEST:
883 case OPUS_GET_PACKET_LOSS_PERC_REQUEST:
884 case OPUS_GET_DTX_REQUEST:
885 case OPUS_GET_VOICE_RATIO_REQUEST:
886 case OPUS_GET_VBR_CONSTRAINT_REQUEST:
887 case OPUS_GET_SIGNAL_REQUEST:
888 case OPUS_GET_LOOKAHEAD_REQUEST:
889 case OPUS_GET_SAMPLE_RATE_REQUEST:
890 case OPUS_GET_INBAND_FEC_REQUEST:
891 case OPUS_GET_FORCE_CHANNELS_REQUEST:
892 {
893 OpusEncoder *enc;
894 /* For int32* GET params, just query the first stream */
895 opus_int32 *value = va_arg(ap, opus_int32*);
896 enc = (OpusEncoder*)ptr;
897 ret = opus_encoder_ctl(enc, request, value);
898 }
899 break;
900 case OPUS_GET_FINAL_RANGE_REQUEST:
901 {
902 int s;
903 opus_uint32 *value = va_arg(ap, opus_uint32*);
904 opus_uint32 tmp;
905 *value=0;
906 for (s=0;s<st->layout.nb_streams;s++)
907 {
908 OpusEncoder *enc;
909 enc = (OpusEncoder*)ptr;
910 if (s < st->layout.nb_coupled_streams)
911 ptr += align(coupled_size);
912 else
913 ptr += align(mono_size);
914 ret = opus_encoder_ctl(enc, request, &tmp);
915 if (ret != OPUS_OK) break;
916 *value ^= tmp;
917 }
918 }
919 break;
920 case OPUS_SET_LSB_DEPTH_REQUEST:
921 case OPUS_SET_COMPLEXITY_REQUEST:
922 case OPUS_SET_VBR_REQUEST:
923 case OPUS_SET_VBR_CONSTRAINT_REQUEST:
924 case OPUS_SET_BANDWIDTH_REQUEST:
925 case OPUS_SET_SIGNAL_REQUEST:
926 case OPUS_SET_APPLICATION_REQUEST:
927 case OPUS_SET_INBAND_FEC_REQUEST:
928 case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
929 case OPUS_SET_DTX_REQUEST:
930 case OPUS_SET_FORCE_MODE_REQUEST:
931 case OPUS_SET_FORCE_CHANNELS_REQUEST:
932 {
933 int s;
934 /* This works for int32 params */
935 opus_int32 value = va_arg(ap, opus_int32);
936 for (s=0;s<st->layout.nb_streams;s++)
937 {
938 OpusEncoder *enc;
939
940 enc = (OpusEncoder*)ptr;
941 if (s < st->layout.nb_coupled_streams)
942 ptr += align(coupled_size);
943 else
944 ptr += align(mono_size);
945 ret = opus_encoder_ctl(enc, request, value);
946 if (ret != OPUS_OK)
947 break;
948 }
949 }
950 break;
951 case OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST:
952 {
953 int s;
954 opus_int32 stream_id;
955 OpusEncoder **value;
956 stream_id = va_arg(ap, opus_int32);
957 if (stream_id<0 || stream_id >= st->layout.nb_streams)
958 ret = OPUS_BAD_ARG;
959 value = va_arg(ap, OpusEncoder**);
960 for (s=0;s<stream_id;s++)
961 {
962 if (s < st->layout.nb_coupled_streams)
963 ptr += align(coupled_size);
964 else
965 ptr += align(mono_size);
966 }
967 *value = (OpusEncoder*)ptr;
968 }
Jean-Marc Valin74483662012-12-17 16:23:42 -0500969 break;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500970 case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST:
Jean-Marc Valin74483662012-12-17 16:23:42 -0500971 {
972 opus_int32 value = va_arg(ap, opus_int32);
Jean-Marc Valin74483662012-12-17 16:23:42 -0500973 st->variable_duration = value;
974 }
975 break;
Jean-Marc Valin51f4a322013-02-20 04:08:04 -0500976 case OPUS_GET_EXPERT_FRAME_DURATION_REQUEST:
Jean-Marc Valin74483662012-12-17 16:23:42 -0500977 {
978 opus_int32 *value = va_arg(ap, opus_int32*);
979 *value = st->variable_duration;
980 }
981 break;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500982 default:
983 ret = OPUS_UNIMPLEMENTED;
984 break;
985 }
986
987 va_end(ap);
988 return ret;
Jean-Marc Valin74483662012-12-17 16:23:42 -0500989bad_arg:
990 va_end(ap);
991 return OPUS_BAD_ARG;
Jean-Marc Valinae0e2ca2012-11-07 19:57:33 -0500992}
993
994void opus_multistream_encoder_destroy(OpusMSEncoder *st)
995{
996 opus_free(st);
997}
998
999