1e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org/* Copyright (c) 2011 Xiph.Org Foundation 2e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org Written by Jean-Marc Valin */ 3e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org/* 4e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org Redistribution and use in source and binary forms, with or without 5e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org modification, are permitted provided that the following conditions 6e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org are met: 7e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 8e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org - Redistributions of source code must retain the above copyright 9e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org notice, this list of conditions and the following disclaimer. 10e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 11e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org - Redistributions in binary form must reproduce the above copyright 12e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org notice, this list of conditions and the following disclaimer in the 13e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org documentation and/or other materials provided with the distribution. 14e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 15e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 19e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 20e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 22e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 23e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 24e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org*/ 27e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 28e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#ifdef HAVE_CONFIG_H 29e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#include "config.h" 30e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif 31e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 32e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#include "opus_multistream.h" 33e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#include "opus.h" 34e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#include "opus_private.h" 35e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#include "stack_alloc.h" 36e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#include <stdarg.h> 37e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#include "float_cast.h" 38e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#include "os_support.h" 39e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#include "mathops.h" 40e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#include "mdct.h" 41e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#include "modes.h" 42e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#include "bands.h" 43e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#include "quant_bands.h" 44e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 45e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgtypedef struct { 46e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int nb_streams; 47e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int nb_coupled_streams; 48e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org unsigned char mapping[8]; 49e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} VorbisLayout; 50e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 51e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org/* Index is nb_channel-1*/ 52e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgstatic const VorbisLayout vorbis_mappings[8] = { 53e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org {1, 0, {0}}, /* 1: mono */ 54e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org {1, 1, {0, 1}}, /* 2: stereo */ 55e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org {2, 1, {0, 2, 1}}, /* 3: 1-d surround */ 56e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org {2, 2, {0, 1, 2, 3}}, /* 4: quadraphonic surround */ 57e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org {3, 2, {0, 4, 1, 2, 3}}, /* 5: 5-channel surround */ 58e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org {4, 2, {0, 4, 1, 2, 3, 5}}, /* 6: 5.1 surround */ 59e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org {4, 3, {0, 4, 1, 2, 3, 5, 6}}, /* 7: 6.1 surround */ 60e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org {5, 3, {0, 6, 1, 2, 3, 4, 5, 7}}, /* 8: 7.1 surround */ 61e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org}; 62e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 63e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgtypedef void (*opus_copy_channel_in_func)( 64e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val16 *dst, 65e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int dst_stride, 66e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org const void *src, 67e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int src_stride, 68e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int src_channel, 69e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int frame_size 70e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org); 71e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 72e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgstruct OpusMSEncoder { 73e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ChannelLayout layout; 74e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int lfe_stream; 75e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int application; 76e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int variable_duration; 77e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int surround; 78e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_int32 bitrate_bps; 793c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com float subframe_mem[3]; 80e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Encoder states go here */ 81e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* then opus_val32 window_mem[channels*120]; */ 82e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* then opus_val32 preemph_mem[channels]; */ 83e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org}; 84e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 85e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgstatic opus_val32 *ms_get_preemph_mem(OpusMSEncoder *st) 86e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{ 87e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int s; 88e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org char *ptr; 89e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int coupled_size, mono_size; 90e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 91e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org coupled_size = opus_encoder_get_size(2); 92e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mono_size = opus_encoder_get_size(1); 93e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ptr = (char*)st + align(sizeof(OpusMSEncoder)); 94e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (s=0;s<st->layout.nb_streams;s++) 95e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 96e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (s < st->layout.nb_coupled_streams) 97e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ptr += align(coupled_size); 98e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org else 99e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ptr += align(mono_size); 100e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 101e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return (opus_val32*)(ptr+st->layout.nb_channels*120*sizeof(opus_val32)); 102e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} 103e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 104e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgstatic opus_val32 *ms_get_window_mem(OpusMSEncoder *st) 105e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{ 106e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int s; 107e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org char *ptr; 108e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int coupled_size, mono_size; 109e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 110e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org coupled_size = opus_encoder_get_size(2); 111e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mono_size = opus_encoder_get_size(1); 112e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ptr = (char*)st + align(sizeof(OpusMSEncoder)); 113e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (s=0;s<st->layout.nb_streams;s++) 114e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 115e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (s < st->layout.nb_coupled_streams) 116e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ptr += align(coupled_size); 117e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org else 118e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ptr += align(mono_size); 119e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 120e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return (opus_val32*)ptr; 121e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} 122e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 123e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgstatic int validate_encoder_layout(const ChannelLayout *layout) 124e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{ 125e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int s; 126e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (s=0;s<layout->nb_streams;s++) 127e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 128e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (s < layout->nb_coupled_streams) 129e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 130e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (get_left_channel(layout, s, -1)==-1) 131e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return 0; 132e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (get_right_channel(layout, s, -1)==-1) 133e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return 0; 134e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } else { 135e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (get_mono_channel(layout, s, -1)==-1) 136e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return 0; 137e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 138e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 139e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return 1; 140e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} 141e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 142e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgstatic void channel_pos(int channels, int pos[8]) 143e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{ 144e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Position in the mix: 0 don't mix, 1: left, 2: center, 3:right */ 145e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (channels==4) 146e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 147e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org pos[0]=1; 148e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org pos[1]=3; 149e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org pos[2]=1; 150e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org pos[3]=3; 151e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } else if (channels==3||channels==5||channels==6) 152e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 153e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org pos[0]=1; 154e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org pos[1]=2; 155e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org pos[2]=3; 156e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org pos[3]=1; 157e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org pos[4]=3; 158e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org pos[5]=0; 159e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } else if (channels==7) 160e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 161e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org pos[0]=1; 162e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org pos[1]=2; 163e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org pos[2]=3; 164e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org pos[3]=1; 165e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org pos[4]=3; 166e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org pos[5]=2; 167e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org pos[6]=0; 168e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } else if (channels==8) 169e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 170e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org pos[0]=1; 171e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org pos[1]=2; 172e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org pos[2]=3; 173e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org pos[3]=1; 174e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org pos[4]=3; 175e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org pos[5]=1; 176e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org pos[6]=3; 177e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org pos[7]=0; 178e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 179e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} 180e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 181e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#if 1 182e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org/* Computes a rough approximation of log2(2^a + 2^b) */ 183e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgstatic opus_val16 logSum(opus_val16 a, opus_val16 b) 184e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{ 185e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val16 max; 186e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val32 diff; 187e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val16 frac; 188e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org static const opus_val16 diff_table[17] = { 189e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org QCONST16(0.5000000f, DB_SHIFT), QCONST16(0.2924813f, DB_SHIFT), QCONST16(0.1609640f, DB_SHIFT), QCONST16(0.0849625f, DB_SHIFT), 190e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org QCONST16(0.0437314f, DB_SHIFT), QCONST16(0.0221971f, DB_SHIFT), QCONST16(0.0111839f, DB_SHIFT), QCONST16(0.0056136f, DB_SHIFT), 191e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org QCONST16(0.0028123f, DB_SHIFT) 192e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org }; 193e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int low; 194e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (a>b) 195e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 196e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org max = a; 197e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org diff = SUB32(EXTEND32(a),EXTEND32(b)); 198e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } else { 199e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org max = b; 200e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org diff = SUB32(EXTEND32(b),EXTEND32(a)); 201e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 202e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (diff >= QCONST16(8.f, DB_SHIFT)) 203e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return max; 204e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#ifdef FIXED_POINT 205e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org low = SHR32(diff, DB_SHIFT-1); 206e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org frac = SHL16(diff - SHL16(low, DB_SHIFT-1), 16-DB_SHIFT); 207e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#else 2083c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com low = (int)floor(2*diff); 209e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org frac = 2*diff - low; 210e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif 211e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return max + diff_table[low] + MULT16_16_Q15(frac, SUB16(diff_table[low+1], diff_table[low])); 212e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} 213e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#else 214e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgopus_val16 logSum(opus_val16 a, opus_val16 b) 215e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{ 216e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return log2(pow(4, a)+ pow(4, b))/2; 217e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} 218e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif 219e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 220e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgvoid surround_analysis(const CELTMode *celt_mode, const void *pcm, opus_val16 *bandLogE, opus_val32 *mem, opus_val32 *preemph_mem, 221e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int len, int overlap, int channels, int rate, opus_copy_channel_in_func copy_channel_in 222e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org) 223e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{ 224e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int c; 225e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int i; 226e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int LM; 227e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int pos[8] = {0}; 228e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int upsample; 229e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int frame_size; 230e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val16 channel_offset; 231e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val32 bandE[21]; 232e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val16 maskLogE[3][21]; 233e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org VARDECL(opus_val32, in); 234e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org VARDECL(opus_val16, x); 235e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org VARDECL(opus_val32, freq); 236e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org SAVE_STACK; 237e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 238e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org upsample = resampling_factor(rate); 239e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org frame_size = len*upsample; 240e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 2413c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com for (LM=0;LM<celt_mode->maxLM;LM++) 242e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (celt_mode->shortMdctSize<<LM==frame_size) 243e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org break; 244e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 245e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ALLOC(in, frame_size+overlap, opus_val32); 246e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ALLOC(x, len, opus_val16); 247e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ALLOC(freq, frame_size, opus_val32); 248e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 249e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org channel_pos(channels, pos); 250e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 251e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (c=0;c<3;c++) 252e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (i=0;i<21;i++) 253e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org maskLogE[c][i] = -QCONST16(28.f, DB_SHIFT); 254e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 255e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (c=0;c<channels;c++) 256e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 257e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org OPUS_COPY(in, mem+c*overlap, overlap); 258e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org (*copy_channel_in)(x, 1, pcm, channels, c, len); 2593c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com celt_preemphasis(x, in+overlap, frame_size, 1, upsample, celt_mode->preemph, preemph_mem+c, 0); 260e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org clt_mdct_forward(&celt_mode->mdct, in, freq, celt_mode->window, overlap, celt_mode->maxLM-LM, 1); 261e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (upsample != 1) 262e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 263e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int bound = len; 264e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (i=0;i<bound;i++) 265e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org freq[i] *= upsample; 266e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (;i<frame_size;i++) 267e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org freq[i] = 0; 268e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 269e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 270e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org compute_band_energies(celt_mode, freq, bandE, 21, 1, 1<<LM); 271e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org amp2Log2(celt_mode, 21, 21, bandE, bandLogE+21*c, 1); 272e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Apply spreading function with -6 dB/band going up and -12 dB/band going down. */ 273e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (i=1;i<21;i++) 274e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org bandLogE[21*c+i] = MAX16(bandLogE[21*c+i], bandLogE[21*c+i-1]-QCONST16(1.f, DB_SHIFT)); 275e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (i=19;i>=0;i--) 276e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org bandLogE[21*c+i] = MAX16(bandLogE[21*c+i], bandLogE[21*c+i+1]-QCONST16(2.f, DB_SHIFT)); 277e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (pos[c]==1) 278e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 279e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (i=0;i<21;i++) 280e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]); 281e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } else if (pos[c]==3) 282e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 283e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (i=0;i<21;i++) 284e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]); 285e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } else if (pos[c]==2) 286e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 287e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (i=0;i<21;i++) 288e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 289e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]-QCONST16(.5f, DB_SHIFT)); 290e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]-QCONST16(.5f, DB_SHIFT)); 291e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 292e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 293e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#if 0 294e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (i=0;i<21;i++) 295e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org printf("%f ", bandLogE[21*c+i]); 296e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org float sum=0; 297e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (i=0;i<21;i++) 298e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org sum += bandLogE[21*c+i]; 299e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org printf("%f ", sum/21); 300e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif 301e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org OPUS_COPY(mem+c*overlap, in+frame_size, overlap); 302e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 303e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (i=0;i<21;i++) 304e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org maskLogE[1][i] = MIN32(maskLogE[0][i],maskLogE[2][i]); 305e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org channel_offset = HALF16(celt_log2(QCONST32(2.f,14)/(channels-1))); 306e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (c=0;c<3;c++) 307e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (i=0;i<21;i++) 308e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org maskLogE[c][i] += channel_offset; 309e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#if 0 310e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (c=0;c<3;c++) 311e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 312e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (i=0;i<21;i++) 313e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org printf("%f ", maskLogE[c][i]); 314e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 315e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif 316e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (c=0;c<channels;c++) 317e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 318e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val16 *mask; 319e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (pos[c]!=0) 320e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 321e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mask = &maskLogE[pos[c]-1][0]; 322e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (i=0;i<21;i++) 323e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org bandLogE[21*c+i] = bandLogE[21*c+i] - mask[i]; 324e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } else { 325e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (i=0;i<21;i++) 326e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org bandLogE[21*c+i] = 0; 327e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 328e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#if 0 329e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (i=0;i<21;i++) 330e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org printf("%f ", bandLogE[21*c+i]); 331e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org printf("\n"); 332e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif 333e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#if 0 334e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org float sum=0; 335e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (i=0;i<21;i++) 336e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org sum += bandLogE[21*c+i]; 337e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org printf("%f ", sum/(float)QCONST32(21.f, DB_SHIFT)); 338e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org printf("\n"); 339e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif 340e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 341e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org RESTORE_STACK; 342e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} 343e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 344e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgopus_int32 opus_multistream_encoder_get_size(int nb_streams, int nb_coupled_streams) 345e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{ 346e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int coupled_size; 347e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int mono_size; 348e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 349e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if(nb_streams<1||nb_coupled_streams>nb_streams||nb_coupled_streams<0)return 0; 350e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org coupled_size = opus_encoder_get_size(2); 351e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mono_size = opus_encoder_get_size(1); 352e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return align(sizeof(OpusMSEncoder)) 353e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org + nb_coupled_streams * align(coupled_size) 354e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org + (nb_streams-nb_coupled_streams) * align(mono_size); 355e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} 356e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 357e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgopus_int32 opus_multistream_surround_encoder_get_size(int channels, int mapping_family) 358e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{ 359e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int nb_streams; 360e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int nb_coupled_streams; 361e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_int32 size; 362e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 363e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (mapping_family==0) 364e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 365e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (channels==1) 366e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 367e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org nb_streams=1; 368e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org nb_coupled_streams=0; 369e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } else if (channels==2) 370e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 371e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org nb_streams=1; 372e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org nb_coupled_streams=1; 373e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } else 374e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return 0; 375e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } else if (mapping_family==1 && channels<=8 && channels>=1) 376e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 377e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org nb_streams=vorbis_mappings[channels-1].nb_streams; 378e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org nb_coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams; 379e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } else if (mapping_family==255) 380e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 381e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org nb_streams=channels; 382e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org nb_coupled_streams=0; 383e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } else 384e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return 0; 385e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org size = opus_multistream_encoder_get_size(nb_streams, nb_coupled_streams); 386e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (channels>2) 387e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 388e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org size += channels*(120*sizeof(opus_val32) + sizeof(opus_val32)); 389e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 390e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return size; 391e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} 392e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 393e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 394e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgstatic int opus_multistream_encoder_init_impl( 395e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org OpusMSEncoder *st, 396e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_int32 Fs, 397e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int channels, 398e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int streams, 399e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int coupled_streams, 400e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org const unsigned char *mapping, 401e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int application, 402e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int surround 403e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org) 404e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{ 405e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int coupled_size; 406e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int mono_size; 407e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int i, ret; 408e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org char *ptr; 409e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 410e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if ((channels>255) || (channels<1) || (coupled_streams>streams) || 411e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0)) 412e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return OPUS_BAD_ARG; 413e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 414e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org st->layout.nb_channels = channels; 415e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org st->layout.nb_streams = streams; 416e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org st->layout.nb_coupled_streams = coupled_streams; 417e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org st->subframe_mem[0]=st->subframe_mem[1]=st->subframe_mem[2]=0; 418e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (!surround) 419e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org st->lfe_stream = -1; 420e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org st->bitrate_bps = OPUS_AUTO; 421e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org st->application = application; 422e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org st->variable_duration = OPUS_FRAMESIZE_ARG; 423e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (i=0;i<st->layout.nb_channels;i++) 424e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org st->layout.mapping[i] = mapping[i]; 425e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (!validate_layout(&st->layout) || !validate_encoder_layout(&st->layout)) 426e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return OPUS_BAD_ARG; 427e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ptr = (char*)st + align(sizeof(OpusMSEncoder)); 428e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org coupled_size = opus_encoder_get_size(2); 429e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mono_size = opus_encoder_get_size(1); 430e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 431e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (i=0;i<st->layout.nb_coupled_streams;i++) 432e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 433e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 2, application); 434e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if(ret!=OPUS_OK)return ret; 435e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (i==st->lfe_stream) 436e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1)); 437e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ptr += align(coupled_size); 438e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 439e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (;i<st->layout.nb_streams;i++) 440e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 441e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 1, application); 442e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (i==st->lfe_stream) 443e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1)); 444e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if(ret!=OPUS_OK)return ret; 445e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ptr += align(mono_size); 446e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 447e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (surround) 448e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 449e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org OPUS_CLEAR(ms_get_preemph_mem(st), channels); 450e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org OPUS_CLEAR(ms_get_window_mem(st), channels*120); 451e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 452e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org st->surround = surround; 453e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return OPUS_OK; 454e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} 455e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 456e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgint opus_multistream_encoder_init( 457e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org OpusMSEncoder *st, 458e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_int32 Fs, 459e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int channels, 460e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int streams, 461e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int coupled_streams, 462e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org const unsigned char *mapping, 463e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int application 464e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org) 465e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{ 466e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return opus_multistream_encoder_init_impl(st, Fs, channels, streams, coupled_streams, mapping, application, 0); 467e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} 468e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 469e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgint opus_multistream_surround_encoder_init( 470e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org OpusMSEncoder *st, 471e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_int32 Fs, 472e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int channels, 473e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int mapping_family, 474e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int *streams, 475e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int *coupled_streams, 476e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org unsigned char *mapping, 477e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int application 478e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org) 479e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{ 480e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if ((channels>255) || (channels<1)) 481e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return OPUS_BAD_ARG; 482e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org st->lfe_stream = -1; 483e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (mapping_family==0) 484e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 485e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (channels==1) 486e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 487e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org *streams=1; 488e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org *coupled_streams=0; 489e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mapping[0]=0; 490e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } else if (channels==2) 491e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 492e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org *streams=1; 493e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org *coupled_streams=1; 494e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mapping[0]=0; 495e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mapping[1]=1; 496e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } else 497e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return OPUS_UNIMPLEMENTED; 498e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } else if (mapping_family==1 && channels<=8 && channels>=1) 499e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 500e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int i; 501e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org *streams=vorbis_mappings[channels-1].nb_streams; 502e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org *coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams; 503e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (i=0;i<channels;i++) 504e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mapping[i] = vorbis_mappings[channels-1].mapping[i]; 505e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (channels>=6) 506e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org st->lfe_stream = *streams-1; 507e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } else if (mapping_family==255) 508e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 509e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int i; 510e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org *streams=channels; 511e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org *coupled_streams=0; 512e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for(i=0;i<channels;i++) 513e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mapping[i] = i; 514e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } else 515e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return OPUS_UNIMPLEMENTED; 516e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return opus_multistream_encoder_init_impl(st, Fs, channels, *streams, *coupled_streams, 517e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mapping, application, channels>2&&mapping_family==1); 518e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} 519e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 520e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgOpusMSEncoder *opus_multistream_encoder_create( 521e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_int32 Fs, 522e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int channels, 523e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int streams, 524e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int coupled_streams, 525e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org const unsigned char *mapping, 526e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int application, 527e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int *error 528e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org) 529e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{ 530e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int ret; 531e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org OpusMSEncoder *st; 532e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if ((channels>255) || (channels<1) || (coupled_streams>streams) || 533e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0)) 534e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 535e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (error) 536e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org *error = OPUS_BAD_ARG; 537e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return NULL; 538e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 539e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org st = (OpusMSEncoder *)opus_alloc(opus_multistream_encoder_get_size(streams, coupled_streams)); 540e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (st==NULL) 541e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 542e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (error) 543e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org *error = OPUS_ALLOC_FAIL; 544e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return NULL; 545e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 546e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ret = opus_multistream_encoder_init(st, Fs, channels, streams, coupled_streams, mapping, application); 547e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (ret != OPUS_OK) 548e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 549e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_free(st); 550e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org st = NULL; 551e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 552e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (error) 553e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org *error = ret; 554e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return st; 555e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} 556e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 557e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgOpusMSEncoder *opus_multistream_surround_encoder_create( 558e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_int32 Fs, 559e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int channels, 560e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int mapping_family, 561e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int *streams, 562e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int *coupled_streams, 563e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org unsigned char *mapping, 564e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int application, 565e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int *error 566e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org) 567e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{ 568e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int ret; 569e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org OpusMSEncoder *st; 570e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if ((channels>255) || (channels<1)) 571e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 572e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (error) 573e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org *error = OPUS_BAD_ARG; 574e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return NULL; 575e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 576e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org st = (OpusMSEncoder *)opus_alloc(opus_multistream_surround_encoder_get_size(channels, mapping_family)); 577e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (st==NULL) 578e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 579e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (error) 580e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org *error = OPUS_ALLOC_FAIL; 581e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return NULL; 582e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 583e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ret = opus_multistream_surround_encoder_init(st, Fs, channels, mapping_family, streams, coupled_streams, mapping, application); 584e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (ret != OPUS_OK) 585e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 586e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_free(st); 587e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org st = NULL; 588e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 589e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (error) 590e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org *error = ret; 591e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return st; 592e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} 593e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 594e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgstatic void surround_rate_allocation( 595e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org OpusMSEncoder *st, 596e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_int32 *rate, 597e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int frame_size 598e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ) 599e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{ 600e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int i; 601e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_int32 channel_rate; 602e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_int32 Fs; 603e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org char *ptr; 604e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int stream_offset; 605e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int lfe_offset; 606e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int coupled_ratio; /* Q8 */ 607e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int lfe_ratio; /* Q8 */ 608e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 609e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ptr = (char*)st + align(sizeof(OpusMSEncoder)); 610e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs)); 611e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 612e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (st->bitrate_bps > st->layout.nb_channels*40000) 613e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org stream_offset = 20000; 614e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org else 615e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org stream_offset = st->bitrate_bps/st->layout.nb_channels/2; 6163c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com stream_offset += 60*(Fs/frame_size-50); 617e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* We start by giving each stream (coupled or uncoupled) the same bitrate. 618e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org This models the main saving of coupled channels over uncoupled. */ 619e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* The LFE stream is an exception to the above and gets fewer bits. */ 6203c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com lfe_offset = 3500 + 60*(Fs/frame_size-50); 621e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Coupled streams get twice the mono rate after the first 20 kb/s. */ 622e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org coupled_ratio = 512; 623e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Should depend on the bitrate, for now we assume LFE gets 1/8 the bits of mono */ 624e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org lfe_ratio = 32; 625e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 626e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Compute bitrate allocation between streams */ 627e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (st->bitrate_bps==OPUS_AUTO) 628e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 629e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org channel_rate = Fs+60*Fs/frame_size; 630e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } else if (st->bitrate_bps==OPUS_BITRATE_MAX) 631e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 632e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org channel_rate = 300000; 633e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } else { 634e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int nb_lfe; 635e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int nb_uncoupled; 636e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int nb_coupled; 637e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int total; 638e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org nb_lfe = (st->lfe_stream!=-1); 639e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org nb_coupled = st->layout.nb_coupled_streams; 640e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org nb_uncoupled = st->layout.nb_streams-nb_coupled-nb_lfe; 641e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org total = (nb_uncoupled<<8) /* mono */ 642e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org + coupled_ratio*nb_coupled /* stereo */ 643e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org + nb_lfe*lfe_ratio; 644e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org channel_rate = 256*(st->bitrate_bps-lfe_offset*nb_lfe-stream_offset*(nb_coupled+nb_uncoupled))/total; 645e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 646e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#ifndef FIXED_POINT 647e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (st->variable_duration==OPUS_FRAMESIZE_VARIABLE && frame_size != Fs/50) 648e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 649e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_int32 bonus; 650e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org bonus = 60*(Fs/frame_size-50); 651e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org channel_rate += bonus; 652e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 653e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif 654e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 655e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (i=0;i<st->layout.nb_streams;i++) 656e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 657e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (i<st->layout.nb_coupled_streams) 658e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org rate[i] = stream_offset+(channel_rate*coupled_ratio>>8); 659e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org else if (i!=st->lfe_stream) 660e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org rate[i] = stream_offset+channel_rate; 661e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org else 662e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org rate[i] = lfe_offset+(channel_rate*lfe_ratio>>8); 663e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 664e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} 665e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 666e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org/* Max size in case the encoder decides to return three frames */ 667e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#define MS_FRAME_TMP (3*1275+7) 668e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgstatic int opus_multistream_encode_native 669e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org( 670e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org OpusMSEncoder *st, 671e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_copy_channel_in_func copy_channel_in, 672e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org const void *pcm, 673e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int analysis_frame_size, 674e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org unsigned char *data, 675e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_int32 max_data_bytes, 676e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int lsb_depth, 677e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org downmix_func downmix 678e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org) 679e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{ 680e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_int32 Fs; 681e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int coupled_size; 682e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int mono_size; 683e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int s; 684e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org char *ptr; 685e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int tot_size; 686e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org VARDECL(opus_val16, buf); 687e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org VARDECL(opus_val16, bandSMR); 688e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org unsigned char tmp_data[MS_FRAME_TMP]; 689e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org OpusRepacketizer rp; 6903c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com opus_int32 vbr; 691e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org const CELTMode *celt_mode; 692e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_int32 bitrates[256]; 693e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val16 bandLogE[42]; 694e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val32 *mem = NULL; 695e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val32 *preemph_mem=NULL; 696e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int frame_size; 697e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ALLOC_STACK; 698e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 699e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (st->surround) 700e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 701e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org preemph_mem = ms_get_preemph_mem(st); 702e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mem = ms_get_window_mem(st); 703e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 704e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 705e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ptr = (char*)st + align(sizeof(OpusMSEncoder)); 706e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs)); 7073c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_VBR(&vbr)); 708e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_encoder_ctl((OpusEncoder*)ptr, CELT_GET_MODE(&celt_mode)); 709e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 710e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 711e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_int32 delay_compensation; 712e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int channels; 713e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 714e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org channels = st->layout.nb_streams + st->layout.nb_coupled_streams; 715e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_LOOKAHEAD(&delay_compensation)); 716e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org delay_compensation -= Fs/400; 717e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org frame_size = compute_frame_size(pcm, analysis_frame_size, 718e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org st->variable_duration, channels, Fs, st->bitrate_bps, 7193c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com delay_compensation, downmix 7203c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com#ifndef DISABLE_FLOAT_API 7213c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com , st->subframe_mem 7223c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com#endif 7233c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com ); 724e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 725e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 726e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (400*frame_size < Fs) 727e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 728e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org RESTORE_STACK; 729e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return OPUS_BAD_ARG; 730e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 731e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Validate frame_size before using it to allocate stack space. 732e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org This mirrors the checks in opus_encode[_float](). */ 733e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (400*frame_size != Fs && 200*frame_size != Fs && 734e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 100*frame_size != Fs && 50*frame_size != Fs && 735e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 25*frame_size != Fs && 50*frame_size != 3*Fs) 736e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 737e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org RESTORE_STACK; 738e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return OPUS_BAD_ARG; 739e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 740e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ALLOC(buf, 2*frame_size, opus_val16); 741e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org coupled_size = opus_encoder_get_size(2); 742e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mono_size = opus_encoder_get_size(1); 743e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 744e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ALLOC(bandSMR, 21*st->layout.nb_channels, opus_val16); 745e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (st->surround) 746e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 747e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org surround_analysis(celt_mode, pcm, bandSMR, mem, preemph_mem, frame_size, 120, st->layout.nb_channels, Fs, copy_channel_in); 748e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 749e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 750e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (max_data_bytes < 4*st->layout.nb_streams-1) 751e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 752e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org RESTORE_STACK; 753e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return OPUS_BUFFER_TOO_SMALL; 754e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 755e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 756e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Compute bitrate allocation between streams (this could be a lot better) */ 757e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org surround_rate_allocation(st, bitrates, frame_size); 758e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 7593c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com if (!vbr) 7603c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com max_data_bytes = IMIN(max_data_bytes, 3*st->bitrate_bps/(3*8*Fs/frame_size)); 7613c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com 762e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ptr = (char*)st + align(sizeof(OpusMSEncoder)); 763e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (s=0;s<st->layout.nb_streams;s++) 764e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 765e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org OpusEncoder *enc; 766e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org enc = (OpusEncoder*)ptr; 767e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (s < st->layout.nb_coupled_streams) 768e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ptr += align(coupled_size); 769e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org else 770e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ptr += align(mono_size); 771e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrates[s])); 772e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (st->surround) 773e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 774e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_int32 equiv_rate; 775e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org equiv_rate = st->bitrate_bps; 776e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (frame_size*50 < Fs) 777e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org equiv_rate -= 60*(Fs/frame_size - 50)*st->layout.nb_channels; 7783c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com if (equiv_rate > 10000*st->layout.nb_channels) 779e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND)); 7803c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com else if (equiv_rate > 7000*st->layout.nb_channels) 781e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_SUPERWIDEBAND)); 7823c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com else if (equiv_rate > 5000*st->layout.nb_channels) 783e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_WIDEBAND)); 784e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org else 785e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND)); 786e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (s < st->layout.nb_coupled_streams) 787e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 788e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* To preserve the spatial image, force stereo CELT on coupled streams */ 789e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY)); 790e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(2)); 791e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 792e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 793e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 794e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 795e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ptr = (char*)st + align(sizeof(OpusMSEncoder)); 796e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Counting ToC */ 797e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org tot_size = 0; 798e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (s=0;s<st->layout.nb_streams;s++) 799e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 800e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org OpusEncoder *enc; 801e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int len; 802e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int curr_max; 803e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int c1, c2; 804e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 805e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_repacketizer_init(&rp); 806e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org enc = (OpusEncoder*)ptr; 807e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (s < st->layout.nb_coupled_streams) 808e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 809e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int i; 810e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int left, right; 811e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org left = get_left_channel(&st->layout, s, -1); 812e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org right = get_right_channel(&st->layout, s, -1); 813e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org (*copy_channel_in)(buf, 2, 814e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org pcm, st->layout.nb_channels, left, frame_size); 815e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org (*copy_channel_in)(buf+1, 2, 816e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org pcm, st->layout.nb_channels, right, frame_size); 817e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ptr += align(coupled_size); 818e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (st->surround) 819e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 820e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (i=0;i<21;i++) 821e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 822e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org bandLogE[i] = bandSMR[21*left+i]; 823e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org bandLogE[21+i] = bandSMR[21*right+i]; 824e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 825e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 826e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org c1 = left; 827e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org c2 = right; 828e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } else { 829e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int i; 830e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int chan = get_mono_channel(&st->layout, s, -1); 831e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org (*copy_channel_in)(buf, 1, 832e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org pcm, st->layout.nb_channels, chan, frame_size); 833e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ptr += align(mono_size); 834e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (st->surround) 835e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 836e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (i=0;i<21;i++) 837e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org bandLogE[i] = bandSMR[21*chan+i]; 838e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 839e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org c1 = chan; 840e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org c2 = -1; 841e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 842e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (st->surround) 843e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_encoder_ctl(enc, OPUS_SET_ENERGY_MASK(bandLogE)); 844e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* number of bytes left (+Toc) */ 845e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org curr_max = max_data_bytes - tot_size; 846e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* Reserve three bytes for the last stream and four for the others */ 847e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org curr_max -= IMAX(0,4*(st->layout.nb_streams-s-1)-1); 848e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org curr_max = IMIN(curr_max,MS_FRAME_TMP); 8493c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com if (!vbr && s == st->layout.nb_streams-1) 8503c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com opus_encoder_ctl(enc, OPUS_SET_BITRATE(curr_max*(8*Fs/frame_size))); 851e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org len = opus_encode_native(enc, buf, frame_size, tmp_data, curr_max, lsb_depth, 852e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org pcm, analysis_frame_size, c1, c2, st->layout.nb_channels, downmix); 853e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (len<0) 854e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 855e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org RESTORE_STACK; 856e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return len; 857e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 858e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* We need to use the repacketizer to add the self-delimiting lengths 859e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org while taking into account the fact that the encoder can now return 860e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org more than one frame at a time (e.g. 60 ms CELT-only) */ 861e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_repacketizer_cat(&rp, tmp_data, len); 8623c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com len = opus_repacketizer_out_range_impl(&rp, 0, opus_repacketizer_get_nb_frames(&rp), 8633c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com data, max_data_bytes-tot_size, s != st->layout.nb_streams-1, !vbr && s == st->layout.nb_streams-1); 864e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org data += len; 865e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org tot_size += len; 866e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 867e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /*printf("\n");*/ 868e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org RESTORE_STACK; 869e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return tot_size; 870e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} 871e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 872e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#if !defined(DISABLE_FLOAT_API) 873e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgstatic void opus_copy_channel_in_float( 874e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val16 *dst, 875e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int dst_stride, 876e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org const void *src, 877e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int src_stride, 878e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int src_channel, 879e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int frame_size 880e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org) 881e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{ 882e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org const float *float_src; 883e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_int32 i; 884e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org float_src = (const float *)src; 885e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (i=0;i<frame_size;i++) 886e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#if defined(FIXED_POINT) 887e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org dst[i*dst_stride] = FLOAT2INT16(float_src[i*src_stride+src_channel]); 888e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#else 889e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org dst[i*dst_stride] = float_src[i*src_stride+src_channel]; 890e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif 891e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} 892e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif 893e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 894e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgstatic void opus_copy_channel_in_short( 895e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_val16 *dst, 896e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int dst_stride, 897e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org const void *src, 898e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int src_stride, 899e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int src_channel, 900e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int frame_size 901e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org) 902e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{ 903e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org const opus_int16 *short_src; 904e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_int32 i; 905e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org short_src = (const opus_int16 *)src; 906e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (i=0;i<frame_size;i++) 907e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#if defined(FIXED_POINT) 908e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org dst[i*dst_stride] = short_src[i*src_stride+src_channel]; 909e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#else 910e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org dst[i*dst_stride] = (1/32768.f)*short_src[i*src_stride+src_channel]; 911e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif 912e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} 913e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 914e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 915e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#ifdef FIXED_POINT 916e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgint opus_multistream_encode( 917e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org OpusMSEncoder *st, 918e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org const opus_val16 *pcm, 919e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int frame_size, 920e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org unsigned char *data, 921e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_int32 max_data_bytes 922e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org) 923e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{ 924e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return opus_multistream_encode_native(st, opus_copy_channel_in_short, 925e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org pcm, frame_size, data, max_data_bytes, 16, downmix_int); 926e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} 927e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 928e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#ifndef DISABLE_FLOAT_API 929e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgint opus_multistream_encode_float( 930e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org OpusMSEncoder *st, 931e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org const float *pcm, 932e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int frame_size, 933e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org unsigned char *data, 934e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_int32 max_data_bytes 935e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org) 936e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{ 937e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return opus_multistream_encode_native(st, opus_copy_channel_in_float, 938e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org pcm, frame_size, data, max_data_bytes, 16, downmix_float); 939e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} 940e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif 941e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 942e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#else 943e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 944e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgint opus_multistream_encode_float 945e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org( 946e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org OpusMSEncoder *st, 947e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org const opus_val16 *pcm, 948e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int frame_size, 949e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org unsigned char *data, 950e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_int32 max_data_bytes 951e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org) 952e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{ 953e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return opus_multistream_encode_native(st, opus_copy_channel_in_float, 954e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org pcm, frame_size, data, max_data_bytes, 24, downmix_float); 955e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} 956e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 957e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgint opus_multistream_encode( 958e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org OpusMSEncoder *st, 959e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org const opus_int16 *pcm, 960e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int frame_size, 961e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org unsigned char *data, 962e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_int32 max_data_bytes 963e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org) 964e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{ 965e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return opus_multistream_encode_native(st, opus_copy_channel_in_short, 966e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org pcm, frame_size, data, max_data_bytes, 16, downmix_int); 967e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} 968e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org#endif 969e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 970e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgint opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...) 971e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{ 972e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org va_list ap; 973e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int coupled_size, mono_size; 974e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org char *ptr; 975e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int ret = OPUS_OK; 976e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 977e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org va_start(ap, request); 978e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 979e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org coupled_size = opus_encoder_get_size(2); 980e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org mono_size = opus_encoder_get_size(1); 981e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ptr = (char*)st + align(sizeof(OpusMSEncoder)); 982e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org switch (request) 983e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 984e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org case OPUS_SET_BITRATE_REQUEST: 985e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 986e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_int32 value = va_arg(ap, opus_int32); 987e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (value<0 && value!=OPUS_AUTO && value!=OPUS_BITRATE_MAX) 988e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 989e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org goto bad_arg; 990e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 991e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org st->bitrate_bps = value; 992e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 993e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org break; 994e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org case OPUS_GET_BITRATE_REQUEST: 995e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 996e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int s; 997e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_int32 *value = va_arg(ap, opus_int32*); 998e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (!value) 999e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 1000e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org goto bad_arg; 1001e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 1002e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org *value = 0; 1003e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (s=0;s<st->layout.nb_streams;s++) 1004e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 1005e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_int32 rate; 1006e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org OpusEncoder *enc; 1007e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org enc = (OpusEncoder*)ptr; 1008e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (s < st->layout.nb_coupled_streams) 1009e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ptr += align(coupled_size); 1010e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org else 1011e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ptr += align(mono_size); 1012e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_encoder_ctl(enc, request, &rate); 1013e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org *value += rate; 1014e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 1015e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 1016e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org break; 1017e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org case OPUS_GET_LSB_DEPTH_REQUEST: 1018e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org case OPUS_GET_VBR_REQUEST: 1019e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org case OPUS_GET_APPLICATION_REQUEST: 1020e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org case OPUS_GET_BANDWIDTH_REQUEST: 1021e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org case OPUS_GET_COMPLEXITY_REQUEST: 1022e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org case OPUS_GET_PACKET_LOSS_PERC_REQUEST: 1023e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org case OPUS_GET_DTX_REQUEST: 1024e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org case OPUS_GET_VOICE_RATIO_REQUEST: 1025e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org case OPUS_GET_VBR_CONSTRAINT_REQUEST: 1026e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org case OPUS_GET_SIGNAL_REQUEST: 1027e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org case OPUS_GET_LOOKAHEAD_REQUEST: 1028e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org case OPUS_GET_SAMPLE_RATE_REQUEST: 1029e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org case OPUS_GET_INBAND_FEC_REQUEST: 1030e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org case OPUS_GET_FORCE_CHANNELS_REQUEST: 10313c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com case OPUS_GET_PREDICTION_DISABLED_REQUEST: 1032e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 1033e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org OpusEncoder *enc; 1034e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* For int32* GET params, just query the first stream */ 1035e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_int32 *value = va_arg(ap, opus_int32*); 1036e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org enc = (OpusEncoder*)ptr; 1037e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ret = opus_encoder_ctl(enc, request, value); 1038e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 1039e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org break; 1040e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org case OPUS_GET_FINAL_RANGE_REQUEST: 1041e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 1042e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int s; 1043e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_uint32 *value = va_arg(ap, opus_uint32*); 1044e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_uint32 tmp; 1045e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (!value) 1046e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 1047e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org goto bad_arg; 1048e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 1049e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org *value=0; 1050e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (s=0;s<st->layout.nb_streams;s++) 1051e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 1052e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org OpusEncoder *enc; 1053e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org enc = (OpusEncoder*)ptr; 1054e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (s < st->layout.nb_coupled_streams) 1055e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ptr += align(coupled_size); 1056e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org else 1057e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ptr += align(mono_size); 1058e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ret = opus_encoder_ctl(enc, request, &tmp); 1059e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (ret != OPUS_OK) break; 1060e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org *value ^= tmp; 1061e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 1062e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 1063e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org break; 1064e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org case OPUS_SET_LSB_DEPTH_REQUEST: 1065e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org case OPUS_SET_COMPLEXITY_REQUEST: 1066e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org case OPUS_SET_VBR_REQUEST: 1067e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org case OPUS_SET_VBR_CONSTRAINT_REQUEST: 1068e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org case OPUS_SET_MAX_BANDWIDTH_REQUEST: 1069e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org case OPUS_SET_BANDWIDTH_REQUEST: 1070e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org case OPUS_SET_SIGNAL_REQUEST: 1071e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org case OPUS_SET_APPLICATION_REQUEST: 1072e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org case OPUS_SET_INBAND_FEC_REQUEST: 1073e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org case OPUS_SET_PACKET_LOSS_PERC_REQUEST: 1074e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org case OPUS_SET_DTX_REQUEST: 1075e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org case OPUS_SET_FORCE_MODE_REQUEST: 1076e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org case OPUS_SET_FORCE_CHANNELS_REQUEST: 10773c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com case OPUS_SET_PREDICTION_DISABLED_REQUEST: 1078e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 1079e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int s; 1080e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org /* This works for int32 params */ 1081e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_int32 value = va_arg(ap, opus_int32); 1082e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (s=0;s<st->layout.nb_streams;s++) 1083e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 1084e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org OpusEncoder *enc; 1085e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 1086e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org enc = (OpusEncoder*)ptr; 1087e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (s < st->layout.nb_coupled_streams) 1088e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ptr += align(coupled_size); 1089e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org else 1090e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ptr += align(mono_size); 1091e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ret = opus_encoder_ctl(enc, request, value); 1092e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (ret != OPUS_OK) 1093e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org break; 1094e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 1095e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 1096e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org break; 1097e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org case OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST: 1098e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 1099e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org int s; 1100e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_int32 stream_id; 1101e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org OpusEncoder **value; 1102e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org stream_id = va_arg(ap, opus_int32); 1103e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (stream_id<0 || stream_id >= st->layout.nb_streams) 1104e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ret = OPUS_BAD_ARG; 1105e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org value = va_arg(ap, OpusEncoder**); 1106e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (!value) 1107e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 1108e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org goto bad_arg; 1109e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 1110e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org for (s=0;s<stream_id;s++) 1111e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 1112e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (s < st->layout.nb_coupled_streams) 1113e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ptr += align(coupled_size); 1114e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org else 1115e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ptr += align(mono_size); 1116e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 1117e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org *value = (OpusEncoder*)ptr; 1118e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 1119e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org break; 1120e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST: 1121e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 1122e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_int32 value = va_arg(ap, opus_int32); 1123e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org st->variable_duration = value; 1124e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 1125e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org break; 1126e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org case OPUS_GET_EXPERT_FRAME_DURATION_REQUEST: 1127e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 1128e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_int32 *value = va_arg(ap, opus_int32*); 1129e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org if (!value) 1130e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org { 1131e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org goto bad_arg; 1132e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 1133e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org *value = st->variable_duration; 1134e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 1135e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org break; 11363c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com case OPUS_RESET_STATE: 11373c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com { 11383c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com int s; 11393c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com st->subframe_mem[0] = st->subframe_mem[1] = st->subframe_mem[2] = 0; 11403c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com if (st->surround) 11413c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com { 11423c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com OPUS_CLEAR(ms_get_preemph_mem(st), st->layout.nb_channels); 11433c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com OPUS_CLEAR(ms_get_window_mem(st), st->layout.nb_channels*120); 11443c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com } 11453c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com for (s=0;s<st->layout.nb_streams;s++) 11463c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com { 11473c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com OpusEncoder *enc; 11483c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com enc = (OpusEncoder*)ptr; 11493c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com if (s < st->layout.nb_coupled_streams) 11503c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com ptr += align(coupled_size); 11513c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com else 11523c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com ptr += align(mono_size); 11533c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com ret = opus_encoder_ctl(enc, OPUS_RESET_STATE); 11543c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com if (ret != OPUS_OK) 11553c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com break; 11563c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com } 11573c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com } 11583c3902f0ac13428394f14f78f0fab05ef3468d69tlegrand@google.com break; 1159e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org default: 1160e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org ret = OPUS_UNIMPLEMENTED; 1161e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org break; 1162e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org } 1163e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 1164e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org va_end(ap); 1165e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return ret; 1166e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgbad_arg: 1167e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org va_end(ap); 1168e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org return OPUS_BAD_ARG; 1169e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} 1170e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org 1171e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.orgvoid opus_multistream_encoder_destroy(OpusMSEncoder *st) 1172e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org{ 1173e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org opus_free(st); 1174e3ea049fcaee2247e45f0ce793d4313babb4ef69tlegrand@chromium.org} 1175