opus_multistream_encoder.c (39853B)
1 /* 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" 39 #include "mathops.h" 40 #include "mdct.h" 41 #include "modes.h" 42 #include "bands.h" 43 #include "quant_bands.h" 44 #include "pitch.h" 45 46 typedef struct { 47 int nb_streams; 48 int nb_coupled_streams; 49 unsigned char mapping[8]; 50 } VorbisLayout; 51 52 /* Index is nb_channel-1*/ 53 static const VorbisLayout vorbis_mappings[8] = { 54 {1, 0, {0}}, /* 1: mono */ 55 {1, 1, {0, 1}}, /* 2: stereo */ 56 {2, 1, {0, 2, 1}}, /* 3: 1-d surround */ 57 {2, 2, {0, 1, 2, 3}}, /* 4: quadraphonic surround */ 58 {3, 2, {0, 4, 1, 2, 3}}, /* 5: 5-channel surround */ 59 {4, 2, {0, 4, 1, 2, 3, 5}}, /* 6: 5.1 surround */ 60 {4, 3, {0, 4, 1, 2, 3, 5, 6}}, /* 7: 6.1 surround */ 61 {5, 3, {0, 6, 1, 2, 3, 4, 5, 7}}, /* 8: 7.1 surround */ 62 }; 63 64 #ifdef ENABLE_QEXT 65 #define MAX_OVERLAP 240 66 #else 67 #define MAX_OVERLAP 120 68 #endif 69 70 static opus_val32 *ms_get_preemph_mem(OpusMSEncoder *st) 71 { 72 int s; 73 char *ptr; 74 int coupled_size, mono_size; 75 76 coupled_size = opus_encoder_init(NULL, st->Fs, 2, st->application); 77 mono_size = opus_encoder_init(NULL, st->Fs, 1, st->application); 78 ptr = (char*)st + align(sizeof(OpusMSEncoder)); 79 for (s=0;s<st->layout.nb_streams;s++) 80 { 81 if (s < st->layout.nb_coupled_streams) 82 ptr += align(coupled_size); 83 else 84 ptr += align(mono_size); 85 } 86 /* void* cast avoids clang -Wcast-align warning */ 87 return (opus_val32*)(void*)(ptr+st->layout.nb_channels*MAX_OVERLAP*sizeof(opus_val32)); 88 } 89 90 static opus_val32 *ms_get_window_mem(OpusMSEncoder *st) 91 { 92 int s; 93 char *ptr; 94 int coupled_size, mono_size; 95 96 coupled_size = opus_encoder_init(NULL, st->Fs, 2, st->application); 97 mono_size = opus_encoder_init(NULL, st->Fs, 1, st->application); 98 ptr = (char*)st + align(sizeof(OpusMSEncoder)); 99 for (s=0;s<st->layout.nb_streams;s++) 100 { 101 if (s < st->layout.nb_coupled_streams) 102 ptr += align(coupled_size); 103 else 104 ptr += align(mono_size); 105 } 106 /* void* cast avoids clang -Wcast-align warning */ 107 return (opus_val32*)(void*)ptr; 108 } 109 110 static int validate_ambisonics(int nb_channels, int *nb_streams, int *nb_coupled_streams) 111 { 112 int order_plus_one; 113 int acn_channels; 114 int nondiegetic_channels; 115 116 if (nb_channels < 1 || nb_channels > 227) 117 return 0; 118 119 order_plus_one = isqrt32(nb_channels); 120 acn_channels = order_plus_one * order_plus_one; 121 nondiegetic_channels = nb_channels - acn_channels; 122 123 if (nondiegetic_channels != 0 && nondiegetic_channels != 2) 124 return 0; 125 126 if (nb_streams) 127 *nb_streams = acn_channels + (nondiegetic_channels != 0); 128 if (nb_coupled_streams) 129 *nb_coupled_streams = nondiegetic_channels != 0; 130 return 1; 131 } 132 133 static int validate_encoder_layout(const ChannelLayout *layout) 134 { 135 int s; 136 for (s=0;s<layout->nb_streams;s++) 137 { 138 if (s < layout->nb_coupled_streams) 139 { 140 if (get_left_channel(layout, s, -1)==-1) 141 return 0; 142 if (get_right_channel(layout, s, -1)==-1) 143 return 0; 144 } else { 145 if (get_mono_channel(layout, s, -1)==-1) 146 return 0; 147 } 148 } 149 return 1; 150 } 151 152 static void channel_pos(int channels, int pos[8]) 153 { 154 /* Position in the mix: 0 don't mix, 1: left, 2: center, 3:right */ 155 if (channels==4) 156 { 157 pos[0]=1; 158 pos[1]=3; 159 pos[2]=1; 160 pos[3]=3; 161 } else if (channels==3||channels==5||channels==6) 162 { 163 pos[0]=1; 164 pos[1]=2; 165 pos[2]=3; 166 pos[3]=1; 167 pos[4]=3; 168 pos[5]=0; 169 } else if (channels==7) 170 { 171 pos[0]=1; 172 pos[1]=2; 173 pos[2]=3; 174 pos[3]=1; 175 pos[4]=3; 176 pos[5]=2; 177 pos[6]=0; 178 } else if (channels==8) 179 { 180 pos[0]=1; 181 pos[1]=2; 182 pos[2]=3; 183 pos[3]=1; 184 pos[4]=3; 185 pos[5]=1; 186 pos[6]=3; 187 pos[7]=0; 188 } 189 } 190 191 #if 1 192 /* Computes a rough approximation of log2(2^a + 2^b) */ 193 static opus_val16 logSum(celt_glog a, celt_glog b) 194 { 195 celt_glog max; 196 celt_glog diff; 197 celt_glog frac; 198 static const celt_glog diff_table[17] = { 199 GCONST(0.5000000f), GCONST(0.2924813f), GCONST(0.1609640f), GCONST(0.0849625f), 200 GCONST(0.0437314f), GCONST(0.0221971f), GCONST(0.0111839f), GCONST(0.0056136f), 201 GCONST(0.0028123f) 202 }; 203 int low; 204 if (a>b) 205 { 206 max = a; 207 diff = SUB32(a,b); 208 } else { 209 max = b; 210 diff = SUB32(b,a); 211 } 212 if (!(diff < GCONST(8.f))) /* inverted to catch NaNs */ 213 return max; 214 #ifdef FIXED_POINT 215 low = SHR32(diff, DB_SHIFT-1); 216 frac = VSHR32(diff - SHL32(low, DB_SHIFT-1), DB_SHIFT-16); 217 #else 218 low = (int)floor(2*diff); 219 frac = 2*diff - low; 220 #endif 221 return max + diff_table[low] + MULT16_32_Q15(frac, SUB32(diff_table[low+1], diff_table[low])); 222 } 223 #else 224 opus_val16 logSum(opus_val16 a, opus_val16 b) 225 { 226 return log2(pow(4, a)+ pow(4, b))/2; 227 } 228 #endif 229 230 void surround_analysis(const CELTMode *celt_mode, const void *pcm, celt_glog *bandLogE, opus_val32 *mem, opus_val32 *preemph_mem, 231 int len, int overlap, int channels, int rate, opus_copy_channel_in_func copy_channel_in, int arch 232 ) 233 { 234 int c; 235 int i; 236 int LM; 237 int pos[8] = {0}; 238 int upsample; 239 int frame_size; 240 int freq_size; 241 opus_val16 channel_offset; 242 opus_val32 bandE[21]; 243 celt_glog maskLogE[3][21]; 244 VARDECL(opus_val32, in); 245 VARDECL(opus_res, x); 246 VARDECL(opus_val32, freq); 247 SAVE_STACK; 248 249 upsample = resampling_factor(rate); 250 frame_size = len*upsample; 251 252 /* LM = log2(frame_size / 120) */ 253 for (LM=0;LM<celt_mode->maxLM;LM++) 254 if (celt_mode->shortMdctSize<<LM==frame_size) 255 break; 256 257 freq_size = celt_mode->shortMdctSize<<LM; 258 259 ALLOC(in, frame_size+overlap, opus_val32); 260 ALLOC(x, len, opus_res); 261 ALLOC(freq, freq_size, opus_val32); 262 263 channel_pos(channels, pos); 264 265 for (c=0;c<3;c++) 266 for (i=0;i<21;i++) 267 maskLogE[c][i] = -GCONST(28.f); 268 269 for (c=0;c<channels;c++) 270 { 271 int frame; 272 int nb_frames = frame_size/freq_size; 273 celt_assert(nb_frames*freq_size == frame_size); 274 OPUS_COPY(in, mem+c*overlap, overlap); 275 (*copy_channel_in)(x, 1, pcm, channels, c, len, NULL); 276 celt_preemphasis(x, in+overlap, frame_size, 1, upsample, celt_mode->preemph, preemph_mem+c, 0); 277 #ifndef FIXED_POINT 278 { 279 opus_val32 sum; 280 sum = celt_inner_prod(in, in, frame_size+overlap, 0); 281 /* This should filter out both NaNs and ridiculous signals that could 282 cause NaNs further down. */ 283 if (!(sum < 1e18f) || celt_isnan(sum)) 284 { 285 OPUS_CLEAR(in, frame_size+overlap); 286 preemph_mem[c] = 0; 287 } 288 } 289 #endif 290 OPUS_CLEAR(bandE, 21); 291 for (frame=0;frame<nb_frames;frame++) 292 { 293 opus_val32 tmpE[21]; 294 clt_mdct_forward(&celt_mode->mdct, in+freq_size*frame, freq, celt_mode->window, 295 overlap, celt_mode->maxLM-LM, 1, arch); 296 if (upsample != 1) 297 { 298 int bound = freq_size/upsample; 299 for (i=0;i<bound;i++) 300 freq[i] *= upsample; 301 for (;i<freq_size;i++) 302 freq[i] = 0; 303 } 304 305 compute_band_energies(celt_mode, freq, tmpE, 21, 1, LM, arch); 306 /* If we have multiple frames, take the max energy. */ 307 for (i=0;i<21;i++) 308 bandE[i] = MAX32(bandE[i], tmpE[i]); 309 } 310 amp2Log2(celt_mode, 21, 21, bandE, bandLogE+21*c, 1); 311 /* Apply spreading function with -6 dB/band going up and -12 dB/band going down. */ 312 for (i=1;i<21;i++) 313 bandLogE[21*c+i] = MAXG(bandLogE[21*c+i], bandLogE[21*c+i-1]-GCONST(1.f)); 314 for (i=19;i>=0;i--) 315 bandLogE[21*c+i] = MAXG(bandLogE[21*c+i], bandLogE[21*c+i+1]-GCONST(2.f)); 316 if (pos[c]==1) 317 { 318 for (i=0;i<21;i++) 319 maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]); 320 } else if (pos[c]==3) 321 { 322 for (i=0;i<21;i++) 323 maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]); 324 } else if (pos[c]==2) 325 { 326 for (i=0;i<21;i++) 327 { 328 maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]-GCONST(.5f)); 329 maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]-GCONST(.5f)); 330 } 331 } 332 #if 0 333 for (i=0;i<21;i++) 334 printf("%f ", bandLogE[21*c+i]); 335 float sum=0; 336 for (i=0;i<21;i++) 337 sum += bandLogE[21*c+i]; 338 printf("%f ", sum/21); 339 #endif 340 OPUS_COPY(mem+c*overlap, in+frame_size, overlap); 341 } 342 for (i=0;i<21;i++) 343 maskLogE[1][i] = MIN32(maskLogE[0][i],maskLogE[2][i]); 344 channel_offset = HALF16(celt_log2(QCONST32(2.f,14)/(channels-1))); 345 for (c=0;c<3;c++) 346 for (i=0;i<21;i++) 347 maskLogE[c][i] += channel_offset; 348 #if 0 349 for (c=0;c<3;c++) 350 { 351 for (i=0;i<21;i++) 352 printf("%f ", maskLogE[c][i]); 353 } 354 #endif 355 for (c=0;c<channels;c++) 356 { 357 celt_glog *mask; 358 if (pos[c]!=0) 359 { 360 mask = &maskLogE[pos[c]-1][0]; 361 for (i=0;i<21;i++) 362 bandLogE[21*c+i] = bandLogE[21*c+i] - mask[i]; 363 } else { 364 for (i=0;i<21;i++) 365 bandLogE[21*c+i] = 0; 366 } 367 #if 0 368 for (i=0;i<21;i++) 369 printf("%f ", bandLogE[21*c+i]); 370 printf("\n"); 371 #endif 372 #if 0 373 float sum=0; 374 for (i=0;i<21;i++) 375 sum += bandLogE[21*c+i]; 376 printf("%f ", sum/(float)QCONST32(21.f, DB_SHIFT)); 377 printf("\n"); 378 #endif 379 } 380 RESTORE_STACK; 381 } 382 383 opus_int32 opus_multistream_encoder_get_size(int nb_streams, int nb_coupled_streams) 384 { 385 int coupled_size; 386 int mono_size; 387 388 if(nb_streams<1||nb_coupled_streams>nb_streams||nb_coupled_streams<0)return 0; 389 coupled_size = opus_encoder_get_size(2); 390 mono_size = opus_encoder_get_size(1); 391 return align(sizeof(OpusMSEncoder)) 392 + nb_coupled_streams * align(coupled_size) 393 + (nb_streams-nb_coupled_streams) * align(mono_size); 394 } 395 396 opus_int32 opus_multistream_surround_encoder_get_size(int channels, int mapping_family) 397 { 398 int nb_streams; 399 int nb_coupled_streams; 400 opus_int32 size; 401 402 if (mapping_family==0) 403 { 404 if (channels==1) 405 { 406 nb_streams=1; 407 nb_coupled_streams=0; 408 } else if (channels==2) 409 { 410 nb_streams=1; 411 nb_coupled_streams=1; 412 } else 413 return 0; 414 } else if (mapping_family==1 && channels<=8 && channels>=1) 415 { 416 nb_streams=vorbis_mappings[channels-1].nb_streams; 417 nb_coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams; 418 } else if (mapping_family==255) 419 { 420 nb_streams=channels; 421 nb_coupled_streams=0; 422 } else if (mapping_family==2) 423 { 424 if (!validate_ambisonics(channels, &nb_streams, &nb_coupled_streams)) 425 return 0; 426 } else 427 return 0; 428 size = opus_multistream_encoder_get_size(nb_streams, nb_coupled_streams); 429 if (channels>2) 430 { 431 size += channels*(MAX_OVERLAP*sizeof(opus_val32) + sizeof(opus_val32)); 432 } 433 return size; 434 } 435 436 static int opus_multistream_encoder_init_impl( 437 OpusMSEncoder *st, 438 opus_int32 Fs, 439 int channels, 440 int streams, 441 int coupled_streams, 442 const unsigned char *mapping, 443 int application, 444 MappingType mapping_type 445 ) 446 { 447 int coupled_size; 448 int mono_size; 449 int i, ret; 450 char *ptr; 451 452 if ((channels>255) || (channels<1) || (coupled_streams>streams) || 453 (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams) || 454 (streams+coupled_streams>channels)) 455 return OPUS_BAD_ARG; 456 457 coupled_size = opus_encoder_init(NULL, Fs, 2, application); 458 if (coupled_size < 0) 459 return coupled_size; 460 mono_size = opus_encoder_init(NULL, Fs, 1, application); 461 if (mono_size < 0) 462 return mono_size; 463 if (st == NULL) 464 { 465 int surround_size=0; 466 if (mapping_type == MAPPING_TYPE_SURROUND) { 467 surround_size = channels*(MAX_OVERLAP*sizeof(opus_val32) + sizeof(opus_val32)); 468 } 469 470 return align(sizeof(OpusMSEncoder)) + coupled_streams*align(coupled_size) 471 + (streams-coupled_streams)*align(mono_size) + surround_size; 472 } 473 474 st->arch = opus_select_arch(); 475 st->layout.nb_channels = channels; 476 st->layout.nb_streams = streams; 477 st->layout.nb_coupled_streams = coupled_streams; 478 if (mapping_type != MAPPING_TYPE_SURROUND) 479 st->lfe_stream = -1; 480 st->bitrate_bps = OPUS_AUTO; 481 st->application = application; 482 st->Fs = Fs; 483 st->variable_duration = OPUS_FRAMESIZE_ARG; 484 for (i=0;i<st->layout.nb_channels;i++) 485 st->layout.mapping[i] = mapping[i]; 486 if (!validate_layout(&st->layout)) 487 return OPUS_BAD_ARG; 488 if (!validate_encoder_layout(&st->layout)) 489 return OPUS_BAD_ARG; 490 if (mapping_type == MAPPING_TYPE_AMBISONICS && 491 !validate_ambisonics(st->layout.nb_channels, NULL, NULL)) 492 return OPUS_BAD_ARG; 493 ptr = (char*)st + align(sizeof(OpusMSEncoder)); 494 for (i=0;i<st->layout.nb_coupled_streams;i++) 495 { 496 ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 2, application); 497 if(ret!=OPUS_OK)return ret; 498 if (i==st->lfe_stream) 499 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1)); 500 ptr += align(coupled_size); 501 } 502 for (;i<st->layout.nb_streams;i++) 503 { 504 ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 1, application); 505 if(ret!=OPUS_OK)return ret; 506 if (i==st->lfe_stream) 507 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1)); 508 ptr += align(mono_size); 509 } 510 if (mapping_type == MAPPING_TYPE_SURROUND) 511 { 512 OPUS_CLEAR(ms_get_preemph_mem(st), channels); 513 OPUS_CLEAR(ms_get_window_mem(st), channels*MAX_OVERLAP); 514 } 515 st->mapping_type = mapping_type; 516 return OPUS_OK; 517 } 518 519 int opus_multistream_encoder_init( 520 OpusMSEncoder *st, 521 opus_int32 Fs, 522 int channels, 523 int streams, 524 int coupled_streams, 525 const unsigned char *mapping, 526 int application 527 ) 528 { 529 return opus_multistream_encoder_init_impl(st, Fs, channels, streams, 530 coupled_streams, mapping, 531 application, MAPPING_TYPE_NONE); 532 } 533 534 int opus_multistream_surround_encoder_init( 535 OpusMSEncoder *st, 536 opus_int32 Fs, 537 int channels, 538 int mapping_family, 539 int *streams, 540 int *coupled_streams, 541 unsigned char *mapping, 542 int application 543 ) 544 { 545 MappingType mapping_type; 546 int lfe_stream; 547 548 if ((channels>255) || (channels<1)) 549 return OPUS_BAD_ARG; 550 lfe_stream = -1; 551 if (mapping_family==0) 552 { 553 if (channels==1) 554 { 555 *streams=1; 556 *coupled_streams=0; 557 mapping[0]=0; 558 } else if (channels==2) 559 { 560 *streams=1; 561 *coupled_streams=1; 562 mapping[0]=0; 563 mapping[1]=1; 564 } else 565 return OPUS_UNIMPLEMENTED; 566 } else if (mapping_family==1 && channels<=8 && channels>=1) 567 { 568 int i; 569 *streams=vorbis_mappings[channels-1].nb_streams; 570 *coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams; 571 for (i=0;i<channels;i++) 572 mapping[i] = vorbis_mappings[channels-1].mapping[i]; 573 if (channels>=6) 574 lfe_stream = *streams-1; 575 } else if (mapping_family==255) 576 { 577 int i; 578 *streams=channels; 579 *coupled_streams=0; 580 for(i=0;i<channels;i++) 581 mapping[i] = i; 582 } else if (mapping_family==2) 583 { 584 int i; 585 if (!validate_ambisonics(channels, streams, coupled_streams)) 586 return OPUS_BAD_ARG; 587 for(i = 0; i < (*streams - *coupled_streams); i++) 588 mapping[i] = i + (*coupled_streams * 2); 589 for(i = 0; i < *coupled_streams * 2; i++) 590 mapping[i + (*streams - *coupled_streams)] = i; 591 } else 592 return OPUS_UNIMPLEMENTED; 593 594 if (channels>2 && mapping_family==1) { 595 mapping_type = MAPPING_TYPE_SURROUND; 596 } else if (mapping_family==2) 597 { 598 mapping_type = MAPPING_TYPE_AMBISONICS; 599 } else 600 { 601 mapping_type = MAPPING_TYPE_NONE; 602 } 603 if (st != NULL) { 604 st->lfe_stream = lfe_stream; 605 } 606 return opus_multistream_encoder_init_impl(st, Fs, channels, *streams, 607 *coupled_streams, mapping, 608 application, mapping_type); 609 } 610 611 OpusMSEncoder *opus_multistream_encoder_create( 612 opus_int32 Fs, 613 int channels, 614 int streams, 615 int coupled_streams, 616 const unsigned char *mapping, 617 int application, 618 int *error 619 ) 620 { 621 int ret; 622 OpusMSEncoder *st; 623 opus_int32 size; 624 if ((channels>255) || (channels<1) || (coupled_streams>streams) || 625 (streams<1) || (coupled_streams<0) || (streams>255-coupled_streams) || 626 (streams+coupled_streams>channels)) 627 { 628 if (error) 629 *error = OPUS_BAD_ARG; 630 return NULL; 631 } 632 size = opus_multistream_encoder_init(NULL, Fs, channels, streams, coupled_streams, mapping, application); 633 if (size < 0) 634 { 635 if (error) 636 *error = size; 637 return NULL; 638 } 639 st = (OpusMSEncoder *)opus_alloc(size); 640 if (st==NULL) 641 { 642 if (error) 643 *error = OPUS_ALLOC_FAIL; 644 return NULL; 645 } 646 ret = opus_multistream_encoder_init(st, Fs, channels, streams, coupled_streams, mapping, application); 647 if (ret != OPUS_OK) 648 { 649 opus_free(st); 650 st = NULL; 651 } 652 if (error) 653 *error = ret; 654 return st; 655 } 656 657 OpusMSEncoder *opus_multistream_surround_encoder_create( 658 opus_int32 Fs, 659 int channels, 660 int mapping_family, 661 int *streams, 662 int *coupled_streams, 663 unsigned char *mapping, 664 int application, 665 int *error 666 ) 667 { 668 int ret; 669 opus_int32 size; 670 OpusMSEncoder *st; 671 if ((channels>255) || (channels<1)) 672 { 673 if (error) 674 *error = OPUS_BAD_ARG; 675 return NULL; 676 } 677 size = opus_multistream_surround_encoder_init(NULL, Fs, channels, mapping_family, streams, coupled_streams, mapping, application); 678 if (size < 0) 679 { 680 if (error) 681 *error = size; 682 return NULL; 683 } 684 st = (OpusMSEncoder *)opus_alloc(size); 685 if (st==NULL) 686 { 687 if (error) 688 *error = OPUS_ALLOC_FAIL; 689 return NULL; 690 } 691 ret = opus_multistream_surround_encoder_init(st, Fs, channels, mapping_family, streams, coupled_streams, mapping, application); 692 if (ret != OPUS_OK) 693 { 694 opus_free(st); 695 st = NULL; 696 } 697 if (error) 698 *error = ret; 699 return st; 700 } 701 702 static void surround_rate_allocation( 703 OpusMSEncoder *st, 704 opus_int32 *rate, 705 int frame_size, 706 opus_int32 Fs 707 ) 708 { 709 int i; 710 opus_int32 channel_rate; 711 int stream_offset; 712 int lfe_offset; 713 int coupled_ratio; /* Q8 */ 714 int lfe_ratio; /* Q8 */ 715 int nb_lfe; 716 int nb_uncoupled; 717 int nb_coupled; 718 int nb_normal; 719 opus_int32 channel_offset; 720 opus_int32 bitrate; 721 int total; 722 723 nb_lfe = (st->lfe_stream!=-1); 724 nb_coupled = st->layout.nb_coupled_streams; 725 nb_uncoupled = st->layout.nb_streams-nb_coupled-nb_lfe; 726 nb_normal = 2*nb_coupled + nb_uncoupled; 727 728 /* Give each non-LFE channel enough bits per channel for coding band energy. */ 729 channel_offset = 40*IMAX(50, Fs/frame_size); 730 731 if (st->bitrate_bps==OPUS_AUTO) 732 { 733 bitrate = nb_normal*(channel_offset + Fs + 10000) + 8000*nb_lfe; 734 } else if (st->bitrate_bps==OPUS_BITRATE_MAX) 735 { 736 bitrate = nb_normal*300000 + nb_lfe*128000; 737 } else { 738 bitrate = st->bitrate_bps; 739 } 740 741 /* Give LFE some basic stream_channel allocation but never exceed 1/20 of the 742 total rate for the non-energy part to avoid problems at really low rate. */ 743 lfe_offset = IMIN(bitrate/20, 3000) + 15*IMAX(50, Fs/frame_size); 744 745 /* We give each stream (coupled or uncoupled) a starting bitrate. 746 This models the main saving of coupled channels over uncoupled. */ 747 stream_offset = (bitrate - channel_offset*nb_normal - lfe_offset*nb_lfe)/nb_normal/2; 748 stream_offset = IMAX(0, IMIN(20000, stream_offset)); 749 750 /* Coupled streams get twice the mono rate after the offset is allocated. */ 751 coupled_ratio = 512; 752 /* Should depend on the bitrate, for now we assume LFE gets 1/8 the bits of mono */ 753 lfe_ratio = 32; 754 755 total = (nb_uncoupled<<8) /* mono */ 756 + coupled_ratio*nb_coupled /* stereo */ 757 + nb_lfe*lfe_ratio; 758 channel_rate = 256*(opus_int64)(bitrate - lfe_offset*nb_lfe - stream_offset*(nb_coupled+nb_uncoupled) - channel_offset*nb_normal)/total; 759 760 for (i=0;i<st->layout.nb_streams;i++) 761 { 762 if (i<st->layout.nb_coupled_streams) 763 rate[i] = 2*channel_offset + IMAX(0, stream_offset+(channel_rate*coupled_ratio>>8)); 764 else if (i!=st->lfe_stream) 765 rate[i] = channel_offset + IMAX(0, stream_offset + channel_rate); 766 else 767 rate[i] = IMAX(0, lfe_offset+(channel_rate*lfe_ratio>>8)); 768 } 769 } 770 771 static void ambisonics_rate_allocation( 772 OpusMSEncoder *st, 773 opus_int32 *rate, 774 int frame_size, 775 opus_int32 Fs 776 ) 777 { 778 int i; 779 opus_int32 total_rate; 780 opus_int32 per_stream_rate; 781 782 const int nb_channels = st->layout.nb_streams + st->layout.nb_coupled_streams; 783 784 if (st->bitrate_bps==OPUS_AUTO) 785 { 786 total_rate = (st->layout.nb_coupled_streams + st->layout.nb_streams) * 787 (Fs+60*Fs/frame_size) + st->layout.nb_streams * (opus_int32)15000; 788 } else if (st->bitrate_bps==OPUS_BITRATE_MAX) 789 { 790 total_rate = nb_channels * 320000; 791 } else 792 { 793 total_rate = st->bitrate_bps; 794 } 795 796 /* Allocate equal number of bits to Ambisonic (uncoupled) and non-diegetic 797 * (coupled) streams */ 798 per_stream_rate = total_rate / st->layout.nb_streams; 799 for (i = 0; i < st->layout.nb_streams; i++) 800 { 801 rate[i] = per_stream_rate; 802 } 803 } 804 805 static opus_int32 rate_allocation( 806 OpusMSEncoder *st, 807 opus_int32 *rate, 808 int frame_size 809 ) 810 { 811 int i; 812 opus_int32 rate_sum=0; 813 opus_int32 Fs; 814 char *ptr; 815 816 ptr = (char*)st + align(sizeof(OpusMSEncoder)); 817 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs)); 818 819 if (st->mapping_type == MAPPING_TYPE_AMBISONICS) { 820 ambisonics_rate_allocation(st, rate, frame_size, Fs); 821 } else 822 { 823 surround_rate_allocation(st, rate, frame_size, Fs); 824 } 825 826 for (i=0;i<st->layout.nb_streams;i++) 827 { 828 rate[i] = IMAX(rate[i], 500); 829 rate_sum += rate[i]; 830 } 831 return rate_sum; 832 } 833 834 /* Max size in case the encoder decides to return six frames (6 x 20 ms = 120 ms) */ 835 #define MS_FRAME_TMP (6*1275+12) 836 int opus_multistream_encode_native 837 ( 838 OpusMSEncoder *st, 839 opus_copy_channel_in_func copy_channel_in, 840 const void *pcm, 841 int analysis_frame_size, 842 unsigned char *data, 843 opus_int32 max_data_bytes, 844 int lsb_depth, 845 downmix_func downmix, 846 int float_api, 847 void *user_data 848 ) 849 { 850 opus_int32 Fs; 851 int coupled_size; 852 int mono_size; 853 int s; 854 char *ptr; 855 int tot_size; 856 VARDECL(opus_res, buf); 857 VARDECL(celt_glog, bandSMR); 858 unsigned char tmp_data[MS_FRAME_TMP]; 859 OpusRepacketizer rp; 860 opus_int32 vbr; 861 const CELTMode *celt_mode=NULL; 862 opus_int32 bitrates[256]; 863 celt_glog bandLogE[42]; 864 opus_val32 *mem = NULL; 865 opus_val32 *preemph_mem=NULL; 866 int frame_size; 867 opus_int32 rate_sum; 868 opus_int32 smallest_packet; 869 ALLOC_STACK; 870 871 if (st->mapping_type == MAPPING_TYPE_SURROUND) 872 { 873 preemph_mem = ms_get_preemph_mem(st); 874 mem = ms_get_window_mem(st); 875 } 876 877 ptr = (char*)st + align(sizeof(OpusMSEncoder)); 878 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs)); 879 opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_VBR(&vbr)); 880 if (st->application != OPUS_APPLICATION_RESTRICTED_SILK) 881 opus_encoder_ctl((OpusEncoder*)ptr, CELT_GET_MODE(&celt_mode)); 882 883 frame_size = frame_size_select(st->application, analysis_frame_size, st->variable_duration, Fs); 884 if (frame_size <= 0) 885 { 886 RESTORE_STACK; 887 return OPUS_BAD_ARG; 888 } 889 890 /* Smallest packet the encoder can produce. */ 891 smallest_packet = st->layout.nb_streams*2-1; 892 /* 100 ms needs an extra byte per stream for the ToC. */ 893 if (Fs/frame_size == 10) 894 smallest_packet += st->layout.nb_streams; 895 if (max_data_bytes < smallest_packet) 896 { 897 RESTORE_STACK; 898 return OPUS_BUFFER_TOO_SMALL; 899 } 900 ALLOC(buf, 2*frame_size, opus_res); 901 coupled_size = opus_encoder_init(NULL, st->Fs, 2, st->application); 902 mono_size = opus_encoder_init(NULL, st->Fs, 1, st->application); 903 904 ALLOC(bandSMR, 21*st->layout.nb_channels, celt_glog); 905 if (st->mapping_type == MAPPING_TYPE_SURROUND && st->application != OPUS_APPLICATION_RESTRICTED_SILK) 906 { 907 surround_analysis(celt_mode, pcm, bandSMR, mem, preemph_mem, frame_size, celt_mode->overlap, st->layout.nb_channels, Fs, copy_channel_in, st->arch); 908 } 909 910 /* Compute bitrate allocation between streams (this could be a lot better) */ 911 rate_sum = rate_allocation(st, bitrates, frame_size); 912 913 if (!vbr) 914 { 915 if (st->bitrate_bps == OPUS_AUTO) 916 { 917 max_data_bytes = IMIN(max_data_bytes, (bitrate_to_bits(rate_sum, Fs, frame_size)+4)/8); 918 } else if (st->bitrate_bps != OPUS_BITRATE_MAX) 919 { 920 max_data_bytes = IMIN(max_data_bytes, IMAX(smallest_packet, 921 (bitrate_to_bits(st->bitrate_bps, Fs, frame_size)+4)/8)); 922 } 923 } 924 ptr = (char*)st + align(sizeof(OpusMSEncoder)); 925 for (s=0;s<st->layout.nb_streams;s++) 926 { 927 OpusEncoder *enc; 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 opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrates[s])); 934 if (st->mapping_type == MAPPING_TYPE_SURROUND) 935 { 936 opus_int32 equiv_rate; 937 equiv_rate = st->bitrate_bps; 938 if (frame_size*50 < Fs) 939 equiv_rate -= 60*(Fs/frame_size - 50)*st->layout.nb_channels; 940 if (equiv_rate > 10000*st->layout.nb_channels) 941 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND)); 942 else if (equiv_rate > 7000*st->layout.nb_channels) 943 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_SUPERWIDEBAND)); 944 else if (equiv_rate > 5000*st->layout.nb_channels) 945 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_WIDEBAND)); 946 else 947 opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND)); 948 if (s < st->layout.nb_coupled_streams) 949 { 950 /* To preserve the spatial image, force stereo CELT on coupled streams */ 951 opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY)); 952 opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(2)); 953 } 954 } 955 else if (st->mapping_type == MAPPING_TYPE_AMBISONICS) { 956 opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY)); 957 } 958 } 959 960 ptr = (char*)st + align(sizeof(OpusMSEncoder)); 961 /* Counting ToC */ 962 tot_size = 0; 963 for (s=0;s<st->layout.nb_streams;s++) 964 { 965 OpusEncoder *enc; 966 int len; 967 int curr_max; 968 int c1, c2; 969 int ret; 970 971 opus_repacketizer_init(&rp); 972 enc = (OpusEncoder*)ptr; 973 if (s < st->layout.nb_coupled_streams) 974 { 975 int i; 976 int left, right; 977 left = get_left_channel(&st->layout, s, -1); 978 right = get_right_channel(&st->layout, s, -1); 979 (*copy_channel_in)(buf, 2, 980 pcm, st->layout.nb_channels, left, frame_size, user_data); 981 (*copy_channel_in)(buf+1, 2, 982 pcm, st->layout.nb_channels, right, frame_size, user_data); 983 ptr += align(coupled_size); 984 if (st->mapping_type == MAPPING_TYPE_SURROUND && st->application != OPUS_APPLICATION_RESTRICTED_SILK) 985 { 986 for (i=0;i<21;i++) 987 { 988 bandLogE[i] = bandSMR[21*left+i]; 989 bandLogE[21+i] = bandSMR[21*right+i]; 990 } 991 } 992 c1 = left; 993 c2 = right; 994 } else { 995 int i; 996 int chan = get_mono_channel(&st->layout, s, -1); 997 (*copy_channel_in)(buf, 1, 998 pcm, st->layout.nb_channels, chan, frame_size, user_data); 999 ptr += align(mono_size); 1000 if (st->mapping_type == MAPPING_TYPE_SURROUND && st->application != OPUS_APPLICATION_RESTRICTED_SILK) 1001 { 1002 for (i=0;i<21;i++) 1003 bandLogE[i] = bandSMR[21*chan+i]; 1004 } 1005 c1 = chan; 1006 c2 = -1; 1007 } 1008 if (st->mapping_type == MAPPING_TYPE_SURROUND && st->application != OPUS_APPLICATION_RESTRICTED_SILK) 1009 opus_encoder_ctl(enc, OPUS_SET_ENERGY_MASK(bandLogE)); 1010 /* number of bytes left (+Toc) */ 1011 curr_max = max_data_bytes - tot_size; 1012 /* Reserve one byte for the last stream and two for the others */ 1013 curr_max -= IMAX(0,2*(st->layout.nb_streams-s-1)-1); 1014 /* For 100 ms, reserve an extra byte per stream for the ToC */ 1015 if (Fs/frame_size == 10) 1016 curr_max -= st->layout.nb_streams-s-1; 1017 curr_max = IMIN(curr_max,MS_FRAME_TMP); 1018 /* Repacketizer will add one or two bytes for self-delimited frames */ 1019 if (s != st->layout.nb_streams-1) curr_max -= curr_max>253 ? 2 : 1; 1020 if (!vbr && s == st->layout.nb_streams-1) 1021 opus_encoder_ctl(enc, OPUS_SET_BITRATE(bits_to_bitrate(curr_max*8, Fs, frame_size))); 1022 len = opus_encode_native(enc, buf, frame_size, tmp_data, curr_max, lsb_depth, 1023 pcm, analysis_frame_size, c1, c2, st->layout.nb_channels, downmix, float_api); 1024 if (len<0) 1025 { 1026 RESTORE_STACK; 1027 return len; 1028 } 1029 /* We need to use the repacketizer to add the self-delimiting lengths 1030 while taking into account the fact that the encoder can now return 1031 more than one frame at a time (e.g. 60 ms CELT-only) */ 1032 ret = opus_repacketizer_cat(&rp, tmp_data, len); 1033 /* If the opus_repacketizer_cat() fails, then something's seriously wrong 1034 with the encoder. */ 1035 if (ret != OPUS_OK) 1036 { 1037 RESTORE_STACK; 1038 return OPUS_INTERNAL_ERROR; 1039 } 1040 len = opus_repacketizer_out_range_impl(&rp, 0, opus_repacketizer_get_nb_frames(&rp), 1041 data, max_data_bytes-tot_size, s != st->layout.nb_streams-1, !vbr && s == st->layout.nb_streams-1, NULL, 0); 1042 data += len; 1043 tot_size += len; 1044 } 1045 /*printf("\n");*/ 1046 RESTORE_STACK; 1047 return tot_size; 1048 } 1049 1050 #if !defined(DISABLE_FLOAT_API) 1051 static void opus_copy_channel_in_float( 1052 opus_res *dst, 1053 int dst_stride, 1054 const void *src, 1055 int src_stride, 1056 int src_channel, 1057 int frame_size, 1058 void *user_data 1059 ) 1060 { 1061 const float *float_src; 1062 opus_int32 i; 1063 (void)user_data; 1064 float_src = (const float *)src; 1065 for (i=0;i<frame_size;i++) 1066 dst[i*dst_stride] = FLOAT2RES(float_src[i*src_stride+src_channel]); 1067 } 1068 #endif 1069 1070 static void opus_copy_channel_in_short( 1071 opus_res *dst, 1072 int dst_stride, 1073 const void *src, 1074 int src_stride, 1075 int src_channel, 1076 int frame_size, 1077 void *user_data 1078 ) 1079 { 1080 const opus_int16 *short_src; 1081 opus_int32 i; 1082 (void)user_data; 1083 short_src = (const opus_int16 *)src; 1084 for (i=0;i<frame_size;i++) 1085 dst[i*dst_stride] = INT16TORES(short_src[i*src_stride+src_channel]); 1086 } 1087 1088 static void opus_copy_channel_in_int24( 1089 opus_res *dst, 1090 int dst_stride, 1091 const void *src, 1092 int src_stride, 1093 int src_channel, 1094 int frame_size, 1095 void *user_data 1096 ) 1097 { 1098 const opus_int32 *short_src; 1099 opus_int32 i; 1100 (void)user_data; 1101 short_src = (const opus_int32 *)src; 1102 for (i=0;i<frame_size;i++) 1103 dst[i*dst_stride] = INT24TORES(short_src[i*src_stride+src_channel]); 1104 } 1105 1106 int opus_multistream_encode( 1107 OpusMSEncoder *st, 1108 const opus_int16 *pcm, 1109 int frame_size, 1110 unsigned char *data, 1111 opus_int32 max_data_bytes 1112 ) 1113 { 1114 return opus_multistream_encode_native(st, opus_copy_channel_in_short, 1115 pcm, frame_size, data, max_data_bytes, 16, downmix_int, 0, NULL); 1116 } 1117 1118 int opus_multistream_encode24( 1119 OpusMSEncoder *st, 1120 const opus_int32 *pcm, 1121 int frame_size, 1122 unsigned char *data, 1123 opus_int32 max_data_bytes 1124 ) 1125 { 1126 return opus_multistream_encode_native(st, opus_copy_channel_in_int24, 1127 pcm, frame_size, data, max_data_bytes, MAX_ENCODING_DEPTH, downmix_int24, 0, NULL); 1128 } 1129 1130 #ifndef DISABLE_FLOAT_API 1131 int opus_multistream_encode_float( 1132 OpusMSEncoder *st, 1133 const float *pcm, 1134 int frame_size, 1135 unsigned char *data, 1136 opus_int32 max_data_bytes 1137 ) 1138 { 1139 return opus_multistream_encode_native(st, opus_copy_channel_in_float, 1140 pcm, frame_size, data, max_data_bytes, MAX_ENCODING_DEPTH, downmix_float, 1, NULL); 1141 } 1142 #endif 1143 1144 int opus_multistream_encoder_ctl_va_list(OpusMSEncoder *st, int request, 1145 va_list ap) 1146 { 1147 int coupled_size, mono_size; 1148 char *ptr; 1149 int ret = OPUS_OK; 1150 1151 coupled_size = opus_encoder_init(NULL, st->Fs, 2, st->application); 1152 mono_size = opus_encoder_init(NULL, st->Fs, 1, st->application); 1153 ptr = (char*)st + align(sizeof(OpusMSEncoder)); 1154 switch (request) 1155 { 1156 case OPUS_SET_BITRATE_REQUEST: 1157 { 1158 opus_int32 value = va_arg(ap, opus_int32); 1159 if (value != OPUS_AUTO && value != OPUS_BITRATE_MAX) 1160 { 1161 if (value <= 0) 1162 goto bad_arg; 1163 value = IMIN(300000*st->layout.nb_channels, IMAX(500*st->layout.nb_channels, value)); 1164 } 1165 st->bitrate_bps = value; 1166 } 1167 break; 1168 case OPUS_GET_BITRATE_REQUEST: 1169 { 1170 int s; 1171 opus_int32 *value = va_arg(ap, opus_int32*); 1172 if (!value) 1173 { 1174 goto bad_arg; 1175 } 1176 *value = 0; 1177 for (s=0;s<st->layout.nb_streams;s++) 1178 { 1179 opus_int32 rate; 1180 OpusEncoder *enc; 1181 enc = (OpusEncoder*)ptr; 1182 if (s < st->layout.nb_coupled_streams) 1183 ptr += align(coupled_size); 1184 else 1185 ptr += align(mono_size); 1186 opus_encoder_ctl(enc, request, &rate); 1187 *value += rate; 1188 } 1189 } 1190 break; 1191 case OPUS_GET_LSB_DEPTH_REQUEST: 1192 case OPUS_GET_VBR_REQUEST: 1193 case OPUS_GET_APPLICATION_REQUEST: 1194 case OPUS_GET_BANDWIDTH_REQUEST: 1195 case OPUS_GET_COMPLEXITY_REQUEST: 1196 case OPUS_GET_PACKET_LOSS_PERC_REQUEST: 1197 case OPUS_GET_DTX_REQUEST: 1198 case OPUS_GET_VOICE_RATIO_REQUEST: 1199 case OPUS_GET_VBR_CONSTRAINT_REQUEST: 1200 case OPUS_GET_SIGNAL_REQUEST: 1201 case OPUS_GET_LOOKAHEAD_REQUEST: 1202 case OPUS_GET_SAMPLE_RATE_REQUEST: 1203 case OPUS_GET_INBAND_FEC_REQUEST: 1204 case OPUS_GET_FORCE_CHANNELS_REQUEST: 1205 case OPUS_GET_PREDICTION_DISABLED_REQUEST: 1206 case OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST: 1207 case OPUS_GET_QEXT_REQUEST: 1208 { 1209 OpusEncoder *enc; 1210 /* For int32* GET params, just query the first stream */ 1211 opus_int32 *value = va_arg(ap, opus_int32*); 1212 enc = (OpusEncoder*)ptr; 1213 ret = opus_encoder_ctl(enc, request, value); 1214 } 1215 break; 1216 case OPUS_GET_FINAL_RANGE_REQUEST: 1217 { 1218 int s; 1219 opus_uint32 *value = va_arg(ap, opus_uint32*); 1220 opus_uint32 tmp; 1221 if (!value) 1222 { 1223 goto bad_arg; 1224 } 1225 *value=0; 1226 for (s=0;s<st->layout.nb_streams;s++) 1227 { 1228 OpusEncoder *enc; 1229 enc = (OpusEncoder*)ptr; 1230 if (s < st->layout.nb_coupled_streams) 1231 ptr += align(coupled_size); 1232 else 1233 ptr += align(mono_size); 1234 ret = opus_encoder_ctl(enc, request, &tmp); 1235 if (ret != OPUS_OK) break; 1236 *value ^= tmp; 1237 } 1238 } 1239 break; 1240 case OPUS_SET_LSB_DEPTH_REQUEST: 1241 case OPUS_SET_COMPLEXITY_REQUEST: 1242 case OPUS_SET_VBR_REQUEST: 1243 case OPUS_SET_VBR_CONSTRAINT_REQUEST: 1244 case OPUS_SET_MAX_BANDWIDTH_REQUEST: 1245 case OPUS_SET_BANDWIDTH_REQUEST: 1246 case OPUS_SET_SIGNAL_REQUEST: 1247 case OPUS_SET_APPLICATION_REQUEST: 1248 case OPUS_SET_INBAND_FEC_REQUEST: 1249 case OPUS_SET_PACKET_LOSS_PERC_REQUEST: 1250 case OPUS_SET_DTX_REQUEST: 1251 case OPUS_SET_FORCE_MODE_REQUEST: 1252 case OPUS_SET_FORCE_CHANNELS_REQUEST: 1253 case OPUS_SET_PREDICTION_DISABLED_REQUEST: 1254 case OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST: 1255 case OPUS_SET_QEXT_REQUEST: 1256 { 1257 int s; 1258 /* This works for int32 params */ 1259 opus_int32 value = va_arg(ap, opus_int32); 1260 for (s=0;s<st->layout.nb_streams;s++) 1261 { 1262 OpusEncoder *enc; 1263 1264 enc = (OpusEncoder*)ptr; 1265 if (s < st->layout.nb_coupled_streams) 1266 ptr += align(coupled_size); 1267 else 1268 ptr += align(mono_size); 1269 ret = opus_encoder_ctl(enc, request, value); 1270 if (ret != OPUS_OK) 1271 break; 1272 } 1273 } 1274 break; 1275 case OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST: 1276 { 1277 int s; 1278 opus_int32 stream_id; 1279 OpusEncoder **value; 1280 stream_id = va_arg(ap, opus_int32); 1281 if (stream_id<0 || stream_id >= st->layout.nb_streams) 1282 goto bad_arg; 1283 value = va_arg(ap, OpusEncoder**); 1284 if (!value) 1285 { 1286 goto bad_arg; 1287 } 1288 for (s=0;s<stream_id;s++) 1289 { 1290 if (s < st->layout.nb_coupled_streams) 1291 ptr += align(coupled_size); 1292 else 1293 ptr += align(mono_size); 1294 } 1295 *value = (OpusEncoder*)ptr; 1296 } 1297 break; 1298 case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST: 1299 { 1300 opus_int32 value = va_arg(ap, opus_int32); 1301 st->variable_duration = value; 1302 } 1303 break; 1304 case OPUS_GET_EXPERT_FRAME_DURATION_REQUEST: 1305 { 1306 opus_int32 *value = va_arg(ap, opus_int32*); 1307 if (!value) 1308 { 1309 goto bad_arg; 1310 } 1311 *value = st->variable_duration; 1312 } 1313 break; 1314 case OPUS_RESET_STATE: 1315 { 1316 int s; 1317 if (st->mapping_type == MAPPING_TYPE_SURROUND) 1318 { 1319 OPUS_CLEAR(ms_get_preemph_mem(st), st->layout.nb_channels); 1320 OPUS_CLEAR(ms_get_window_mem(st), st->layout.nb_channels*MAX_OVERLAP); 1321 } 1322 for (s=0;s<st->layout.nb_streams;s++) 1323 { 1324 OpusEncoder *enc; 1325 enc = (OpusEncoder*)ptr; 1326 if (s < st->layout.nb_coupled_streams) 1327 ptr += align(coupled_size); 1328 else 1329 ptr += align(mono_size); 1330 ret = opus_encoder_ctl(enc, OPUS_RESET_STATE); 1331 if (ret != OPUS_OK) 1332 break; 1333 } 1334 } 1335 break; 1336 default: 1337 ret = OPUS_UNIMPLEMENTED; 1338 break; 1339 } 1340 return ret; 1341 bad_arg: 1342 return OPUS_BAD_ARG; 1343 } 1344 1345 int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...) 1346 { 1347 int ret; 1348 va_list ap; 1349 va_start(ap, request); 1350 ret = opus_multistream_encoder_ctl_va_list(st, request, ap); 1351 va_end(ap); 1352 return ret; 1353 } 1354 1355 void opus_multistream_encoder_destroy(OpusMSEncoder *st) 1356 { 1357 opus_free(st); 1358 }