12bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian/* Copyright (c) 2010-2011 Xiph.Org Foundation, Skype Limited
22bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   Written by Jean-Marc Valin and Koen Vos */
32bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian/*
42bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   Redistribution and use in source and binary forms, with or without
52bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   modification, are permitted provided that the following conditions
62bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   are met:
72bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
82bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   - Redistributions of source code must retain the above copyright
92bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   notice, this list of conditions and the following disclaimer.
102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   - Redistributions in binary form must reproduce the above copyright
122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   notice, this list of conditions and the following disclaimer in the
132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   documentation and/or other materials provided with the distribution.
142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian*/
272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifdef HAVE_CONFIG_H
292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#include "config.h"
302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#include <stdarg.h>
332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#include "celt.h"
342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#include "entenc.h"
352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#include "modes.h"
362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#include "API.h"
372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#include "stack_alloc.h"
382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#include "float_cast.h"
392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#include "opus.h"
402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#include "arch.h"
412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#include "opus_private.h"
422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#include "os_support.h"
432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#include "cpu_support.h"
442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#include "analysis.h"
452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#include "mathops.h"
462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#include "tuning_parameters.h"
472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifdef FIXED_POINT
482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#include "fixed/structs_FIX.h"
492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#else
502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#include "float/structs_FLP.h"
512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#define MAX_ENCODER_BUFFER 480
542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramaniantypedef struct {
562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   opus_val32 XX, XY, YY;
572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   opus_val16 smoothed_width;
582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   opus_val16 max_follower;
592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian} StereoWidthState;
602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianstruct OpusEncoder {
622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int          celt_enc_offset;
632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int          silk_enc_offset;
642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    silk_EncControlStruct silk_mode;
652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int          application;
662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int          channels;
672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int          delay_compensation;
682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int          force_channels;
692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int          signal_type;
702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int          user_bandwidth;
712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int          max_bandwidth;
722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int          user_forced_mode;
732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int          voice_ratio;
742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    opus_int32   Fs;
752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int          use_vbr;
762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int          vbr_constraint;
772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int          variable_duration;
782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    opus_int32   bitrate_bps;
792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    opus_int32   user_bitrate_bps;
802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int          lsb_depth;
812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int          encoder_buffer;
822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int          lfe;
832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#define OPUS_ENCODER_RESET_START stream_channels
852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int          stream_channels;
862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    opus_int16   hybrid_stereo_width_Q14;
872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    opus_int32   variable_HP_smth2_Q15;
882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    opus_val16   prev_HB_gain;
892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    opus_val32   hp_mem[4];
902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int          mode;
912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int          prev_mode;
922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int          prev_channels;
932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int          prev_framesize;
942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int          bandwidth;
952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int          silk_bw_switch;
962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    /* Sampling rate (at the API level) */
972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int          first;
982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    opus_val16 * energy_masking;
992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    StereoWidthState width_mem;
1002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    opus_val16   delay_buffer[MAX_ENCODER_BUFFER*2];
1012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifndef DISABLE_FLOAT_API
1022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    TonalityAnalysisState analysis;
1032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int          detected_bandwidth;
1042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int          analysis_offset;
1052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
1062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    opus_uint32  rangeFinal;
1072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int          arch;
1082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian};
1092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
1102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian/* Transition tables for the voice and music. First column is the
1112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   middle (memoriless) threshold. The second column is the hysteresis
1122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   (difference with the middle) */
1132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianstatic const opus_int32 mono_voice_bandwidth_thresholds[8] = {
1142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        11000, 1000, /* NB<->MB */
1152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        14000, 1000, /* MB<->WB */
1162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        17000, 1000, /* WB<->SWB */
1172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        21000, 2000, /* SWB<->FB */
1182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian};
1192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianstatic const opus_int32 mono_music_bandwidth_thresholds[8] = {
1202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        12000, 1000, /* NB<->MB */
1212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        15000, 1000, /* MB<->WB */
1222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        18000, 2000, /* WB<->SWB */
1232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        22000, 2000, /* SWB<->FB */
1242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian};
1252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianstatic const opus_int32 stereo_voice_bandwidth_thresholds[8] = {
1262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        11000, 1000, /* NB<->MB */
1272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        14000, 1000, /* MB<->WB */
1282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        21000, 2000, /* WB<->SWB */
1292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        28000, 2000, /* SWB<->FB */
1302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian};
1312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianstatic const opus_int32 stereo_music_bandwidth_thresholds[8] = {
1322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        12000, 1000, /* NB<->MB */
1332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        18000, 2000, /* MB<->WB */
1342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        21000, 2000, /* WB<->SWB */
1352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        30000, 2000, /* SWB<->FB */
1362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian};
1372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian/* Threshold bit-rates for switching between mono and stereo */
1382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianstatic const opus_int32 stereo_voice_threshold = 30000;
1392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianstatic const opus_int32 stereo_music_threshold = 30000;
1402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
1412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian/* Threshold bit-rate for switching between SILK/hybrid and CELT-only */
1422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianstatic const opus_int32 mode_thresholds[2][2] = {
1432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      /* voice */ /* music */
1442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {  64000,      16000}, /* mono */
1452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {  36000,      16000}, /* stereo */
1462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian};
1472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
1482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianint opus_encoder_get_size(int channels)
1492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
1502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int silkEncSizeBytes, celtEncSizeBytes;
1512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int ret;
1522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (channels<1 || channels > 2)
1532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        return 0;
1542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    ret = silk_Get_Encoder_Size( &silkEncSizeBytes );
1552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (ret)
1562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        return 0;
1572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    silkEncSizeBytes = align(silkEncSizeBytes);
1582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    celtEncSizeBytes = celt_encoder_get_size(channels);
1592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    return align(sizeof(OpusEncoder))+silkEncSizeBytes+celtEncSizeBytes;
1602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
1612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
1622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianint opus_encoder_init(OpusEncoder* st, opus_int32 Fs, int channels, int application)
1632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
1642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    void *silk_enc;
1652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    CELTEncoder *celt_enc;
1662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int err;
1672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int ret, silkEncSizeBytes;
1682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
1692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)||(channels!=1&&channels!=2)||
1702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        (application != OPUS_APPLICATION_VOIP && application != OPUS_APPLICATION_AUDIO
1712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        && application != OPUS_APPLICATION_RESTRICTED_LOWDELAY))
1722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        return OPUS_BAD_ARG;
1732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
1742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    OPUS_CLEAR((char*)st, opus_encoder_get_size(channels));
1752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    /* Create SILK encoder */
1762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    ret = silk_Get_Encoder_Size( &silkEncSizeBytes );
1772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (ret)
1782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        return OPUS_BAD_ARG;
1792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    silkEncSizeBytes = align(silkEncSizeBytes);
1802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->silk_enc_offset = align(sizeof(OpusEncoder));
1812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->celt_enc_offset = st->silk_enc_offset+silkEncSizeBytes;
1822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    silk_enc = (char*)st+st->silk_enc_offset;
1832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset);
1842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
1852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->stream_channels = st->channels = channels;
1862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
1872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->Fs = Fs;
1882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
1892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->arch = opus_select_arch();
1902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
1912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    ret = silk_InitEncoder( silk_enc, st->arch, &st->silk_mode );
1922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if(ret)return OPUS_INTERNAL_ERROR;
1932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
1942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    /* default SILK parameters */
1952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->silk_mode.nChannelsAPI              = channels;
1962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->silk_mode.nChannelsInternal         = channels;
1972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->silk_mode.API_sampleRate            = st->Fs;
1982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->silk_mode.maxInternalSampleRate     = 16000;
1992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->silk_mode.minInternalSampleRate     = 8000;
2002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->silk_mode.desiredInternalSampleRate = 16000;
2012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->silk_mode.payloadSize_ms            = 20;
2022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->silk_mode.bitRate                   = 25000;
2032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->silk_mode.packetLossPercentage      = 0;
2042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->silk_mode.complexity                = 9;
2052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->silk_mode.useInBandFEC              = 0;
2062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->silk_mode.useDTX                    = 0;
2072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->silk_mode.useCBR                    = 0;
2082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->silk_mode.reducedDependency         = 0;
2092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
2102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    /* Create CELT encoder */
2112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    /* Initialize CELT encoder */
2122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    err = celt_encoder_init(celt_enc, Fs, channels, st->arch);
2132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if(err!=OPUS_OK)return OPUS_INTERNAL_ERROR;
2142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
2152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    celt_encoder_ctl(celt_enc, CELT_SET_SIGNALLING(0));
2162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    celt_encoder_ctl(celt_enc, OPUS_SET_COMPLEXITY(st->silk_mode.complexity));
2172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
2182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->use_vbr = 1;
2192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    /* Makes constrained VBR the default (safer for real-time use) */
2202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->vbr_constraint = 1;
2212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->user_bitrate_bps = OPUS_AUTO;
2222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->bitrate_bps = 3000+Fs*channels;
2232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->application = application;
2242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->signal_type = OPUS_AUTO;
2252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->user_bandwidth = OPUS_AUTO;
2262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->max_bandwidth = OPUS_BANDWIDTH_FULLBAND;
2272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->force_channels = OPUS_AUTO;
2282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->user_forced_mode = OPUS_AUTO;
2292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->voice_ratio = -1;
2302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->encoder_buffer = st->Fs/100;
2312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->lsb_depth = 24;
2322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->variable_duration = OPUS_FRAMESIZE_ARG;
2332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
2342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    /* Delay compensation of 4 ms (2.5 ms for SILK's extra look-ahead
2352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       + 1.5 ms for SILK resamplers and stereo prediction) */
2362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->delay_compensation = st->Fs/250;
2372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
2382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->hybrid_stereo_width_Q14 = 1 << 14;
2392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->prev_HB_gain = Q15ONE;
2402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->variable_HP_smth2_Q15 = silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 );
2412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->first = 1;
2422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->mode = MODE_HYBRID;
2432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->bandwidth = OPUS_BANDWIDTH_FULLBAND;
2442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
2452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    return OPUS_OK;
2462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
2472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
2482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianstatic unsigned char gen_toc(int mode, int framerate, int bandwidth, int channels)
2492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
2502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int period;
2512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   unsigned char toc;
2522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   period = 0;
2532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   while (framerate < 400)
2542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
2552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       framerate <<= 1;
2562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       period++;
2572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
2582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (mode == MODE_SILK_ONLY)
2592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
2602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       toc = (bandwidth-OPUS_BANDWIDTH_NARROWBAND)<<5;
2612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       toc |= (period-2)<<3;
2622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   } else if (mode == MODE_CELT_ONLY)
2632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
2642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       int tmp = bandwidth-OPUS_BANDWIDTH_MEDIUMBAND;
2652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       if (tmp < 0)
2662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           tmp = 0;
2672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       toc = 0x80;
2682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       toc |= tmp << 5;
2692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       toc |= period<<3;
2702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   } else /* Hybrid */
2712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
2722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       toc = 0x60;
2732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       toc |= (bandwidth-OPUS_BANDWIDTH_SUPERWIDEBAND)<<4;
2742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       toc |= (period-2)<<3;
2752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
2762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   toc |= (channels==2)<<2;
2772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   return toc;
2782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
2792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
2802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifndef FIXED_POINT
2812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianstatic void silk_biquad_float(
2822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    const opus_val16      *in,            /* I:    Input signal                   */
2832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    const opus_int32      *B_Q28,         /* I:    MA coefficients [3]            */
2842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    const opus_int32      *A_Q28,         /* I:    AR coefficients [2]            */
2852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    opus_val32            *S,             /* I/O:  State vector [2]               */
2862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    opus_val16            *out,           /* O:    Output signal                  */
2872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    const opus_int32      len,            /* I:    Signal length (must be even)   */
2882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int stride
2892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian)
2902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
2912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    /* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */
2922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    opus_int   k;
2932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    opus_val32 vout;
2942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    opus_val32 inval;
2952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    opus_val32 A[2], B[3];
2962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
2972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    A[0] = (opus_val32)(A_Q28[0] * (1.f/((opus_int32)1<<28)));
2982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    A[1] = (opus_val32)(A_Q28[1] * (1.f/((opus_int32)1<<28)));
2992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    B[0] = (opus_val32)(B_Q28[0] * (1.f/((opus_int32)1<<28)));
3002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    B[1] = (opus_val32)(B_Q28[1] * (1.f/((opus_int32)1<<28)));
3012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    B[2] = (opus_val32)(B_Q28[2] * (1.f/((opus_int32)1<<28)));
3022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
3032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    /* Negate A_Q28 values and split in two parts */
3042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
3052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    for( k = 0; k < len; k++ ) {
3062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        /* S[ 0 ], S[ 1 ]: Q12 */
3072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        inval = in[ k*stride ];
3082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        vout = S[ 0 ] + B[0]*inval;
3092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
3102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        S[ 0 ] = S[1] - vout*A[0] + B[1]*inval;
3112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
3122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        S[ 1 ] = - vout*A[1] + B[2]*inval + VERY_SMALL;
3132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
3142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        /* Scale back to Q0 and saturate */
3152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        out[ k*stride ] = vout;
3162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
3172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
3182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
3192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
3202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianstatic void hp_cutoff(const opus_val16 *in, opus_int32 cutoff_Hz, opus_val16 *out, opus_val32 *hp_mem, int len, int channels, opus_int32 Fs)
3212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
3222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   opus_int32 B_Q28[ 3 ], A_Q28[ 2 ];
3232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   opus_int32 Fc_Q19, r_Q28, r_Q22;
3242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
3252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   silk_assert( cutoff_Hz <= silk_int32_MAX / SILK_FIX_CONST( 1.5 * 3.14159 / 1000, 19 ) );
3262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   Fc_Q19 = silk_DIV32_16( silk_SMULBB( SILK_FIX_CONST( 1.5 * 3.14159 / 1000, 19 ), cutoff_Hz ), Fs/1000 );
3272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   silk_assert( Fc_Q19 > 0 && Fc_Q19 < 32768 );
3282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
3292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   r_Q28 = SILK_FIX_CONST( 1.0, 28 ) - silk_MUL( SILK_FIX_CONST( 0.92, 9 ), Fc_Q19 );
3302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
3312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   /* b = r * [ 1; -2; 1 ]; */
3322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   /* a = [ 1; -2 * r * ( 1 - 0.5 * Fc^2 ); r^2 ]; */
3332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   B_Q28[ 0 ] = r_Q28;
3342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   B_Q28[ 1 ] = silk_LSHIFT( -r_Q28, 1 );
3352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   B_Q28[ 2 ] = r_Q28;
3362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
3372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   /* -r * ( 2 - Fc * Fc ); */
3382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   r_Q22  = silk_RSHIFT( r_Q28, 6 );
3392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   A_Q28[ 0 ] = silk_SMULWW( r_Q22, silk_SMULWW( Fc_Q19, Fc_Q19 ) - SILK_FIX_CONST( 2.0,  22 ) );
3402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   A_Q28[ 1 ] = silk_SMULWW( r_Q22, r_Q22 );
3412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
3422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifdef FIXED_POINT
3432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   silk_biquad_alt( in, B_Q28, A_Q28, hp_mem, out, len, channels );
3442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if( channels == 2 ) {
3452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       silk_biquad_alt( in+1, B_Q28, A_Q28, hp_mem+2, out+1, len, channels );
3462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
3472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#else
3482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   silk_biquad_float( in, B_Q28, A_Q28, hp_mem, out, len, channels );
3492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if( channels == 2 ) {
3502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       silk_biquad_float( in+1, B_Q28, A_Q28, hp_mem+2, out+1, len, channels );
3512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
3522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
3532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
3542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
3552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifdef FIXED_POINT
3562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianstatic void dc_reject(const opus_val16 *in, opus_int32 cutoff_Hz, opus_val16 *out, opus_val32 *hp_mem, int len, int channels, opus_int32 Fs)
3572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
3582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int c, i;
3592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int shift;
3602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
3612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   /* Approximates -round(log2(4.*cutoff_Hz/Fs)) */
3622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   shift=celt_ilog2(Fs/(cutoff_Hz*3));
3632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   for (c=0;c<channels;c++)
3642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
3652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      for (i=0;i<len;i++)
3662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
3672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         opus_val32 x, tmp, y;
3682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         x = SHL32(EXTEND32(in[channels*i+c]), 15);
3692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         /* First stage */
3702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         tmp = x-hp_mem[2*c];
3712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         hp_mem[2*c] = hp_mem[2*c] + PSHR32(x - hp_mem[2*c], shift);
3722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         /* Second stage */
3732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         y = tmp - hp_mem[2*c+1];
3742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         hp_mem[2*c+1] = hp_mem[2*c+1] + PSHR32(tmp - hp_mem[2*c+1], shift);
3752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         out[channels*i+c] = EXTRACT16(SATURATE(PSHR32(y, 15), 32767));
3762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      }
3772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
3782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
3792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
3802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#else
3812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianstatic void dc_reject(const opus_val16 *in, opus_int32 cutoff_Hz, opus_val16 *out, opus_val32 *hp_mem, int len, int channels, opus_int32 Fs)
3822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
3832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int c, i;
3842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   float coef;
3852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
3862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   coef = 4.0f*cutoff_Hz/Fs;
3872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   for (c=0;c<channels;c++)
3882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
3892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      for (i=0;i<len;i++)
3902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
3912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         opus_val32 x, tmp, y;
3922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         x = in[channels*i+c];
3932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         /* First stage */
3942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         tmp = x-hp_mem[2*c];
3952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         hp_mem[2*c] = hp_mem[2*c] + coef*(x - hp_mem[2*c]) + VERY_SMALL;
3962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         /* Second stage */
3972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         y = tmp - hp_mem[2*c+1];
3982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         hp_mem[2*c+1] = hp_mem[2*c+1] + coef*(tmp - hp_mem[2*c+1]) + VERY_SMALL;
3992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         out[channels*i+c] = y;
4002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      }
4012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
4022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
4032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
4042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
4052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianstatic void stereo_fade(const opus_val16 *in, opus_val16 *out, opus_val16 g1, opus_val16 g2,
4062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        int overlap48, int frame_size, int channels, const opus_val16 *window, opus_int32 Fs)
4072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
4082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int i;
4092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int overlap;
4102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int inc;
4112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    inc = 48000/Fs;
4122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    overlap=overlap48/inc;
4132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    g1 = Q15ONE-g1;
4142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    g2 = Q15ONE-g2;
4152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    for (i=0;i<overlap;i++)
4162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    {
4172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       opus_val32 diff;
4182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       opus_val16 g, w;
4192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       w = MULT16_16_Q15(window[i*inc], window[i*inc]);
4202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       g = SHR32(MAC16_16(MULT16_16(w,g2),
4212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian             Q15ONE-w, g1), 15);
4222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       diff = EXTRACT16(HALF32((opus_val32)in[i*channels] - (opus_val32)in[i*channels+1]));
4232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       diff = MULT16_16_Q15(g, diff);
4242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       out[i*channels] = out[i*channels] - diff;
4252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       out[i*channels+1] = out[i*channels+1] + diff;
4262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
4272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    for (;i<frame_size;i++)
4282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    {
4292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       opus_val32 diff;
4302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       diff = EXTRACT16(HALF32((opus_val32)in[i*channels] - (opus_val32)in[i*channels+1]));
4312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       diff = MULT16_16_Q15(g2, diff);
4322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       out[i*channels] = out[i*channels] - diff;
4332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       out[i*channels+1] = out[i*channels+1] + diff;
4342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
4352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
4362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
4372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianstatic void gain_fade(const opus_val16 *in, opus_val16 *out, opus_val16 g1, opus_val16 g2,
4382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        int overlap48, int frame_size, int channels, const opus_val16 *window, opus_int32 Fs)
4392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
4402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int i;
4412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int inc;
4422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int overlap;
4432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int c;
4442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    inc = 48000/Fs;
4452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    overlap=overlap48/inc;
4462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (channels==1)
4472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    {
4482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       for (i=0;i<overlap;i++)
4492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       {
4502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          opus_val16 g, w;
4512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          w = MULT16_16_Q15(window[i*inc], window[i*inc]);
4522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          g = SHR32(MAC16_16(MULT16_16(w,g2),
4532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                Q15ONE-w, g1), 15);
4542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          out[i] = MULT16_16_Q15(g, in[i]);
4552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       }
4562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    } else {
4572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       for (i=0;i<overlap;i++)
4582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       {
4592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          opus_val16 g, w;
4602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          w = MULT16_16_Q15(window[i*inc], window[i*inc]);
4612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          g = SHR32(MAC16_16(MULT16_16(w,g2),
4622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                Q15ONE-w, g1), 15);
4632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          out[i*2] = MULT16_16_Q15(g, in[i*2]);
4642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          out[i*2+1] = MULT16_16_Q15(g, in[i*2+1]);
4652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       }
4662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
4672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    c=0;do {
4682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       for (i=overlap;i<frame_size;i++)
4692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       {
4702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          out[i*channels+c] = MULT16_16_Q15(g2, in[i*channels+c]);
4712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       }
4722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
4732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    while (++c<channels);
4742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
4752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
4762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh VenkatasubramanianOpusEncoder *opus_encoder_create(opus_int32 Fs, int channels, int application, int *error)
4772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
4782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int ret;
4792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   OpusEncoder *st;
4802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)||(channels!=1&&channels!=2)||
4812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       (application != OPUS_APPLICATION_VOIP && application != OPUS_APPLICATION_AUDIO
4822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       && application != OPUS_APPLICATION_RESTRICTED_LOWDELAY))
4832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
4842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (error)
4852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         *error = OPUS_BAD_ARG;
4862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      return NULL;
4872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
4882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   st = (OpusEncoder *)opus_alloc(opus_encoder_get_size(channels));
4892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (st == NULL)
4902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
4912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (error)
4922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         *error = OPUS_ALLOC_FAIL;
4932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      return NULL;
4942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
4952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   ret = opus_encoder_init(st, Fs, channels, application);
4962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (error)
4972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      *error = ret;
4982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (ret != OPUS_OK)
4992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
5002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      opus_free(st);
5012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      st = NULL;
5022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
5032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   return st;
5042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
5052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
5062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianstatic opus_int32 user_bitrate_to_bitrate(OpusEncoder *st, int frame_size, int max_data_bytes)
5072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
5082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian  if(!frame_size)frame_size=st->Fs/400;
5092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian  if (st->user_bitrate_bps==OPUS_AUTO)
5102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    return 60*st->Fs/frame_size + st->Fs*st->channels;
5112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian  else if (st->user_bitrate_bps==OPUS_BITRATE_MAX)
5122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    return max_data_bytes*8*st->Fs/frame_size;
5132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian  else
5142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    return st->user_bitrate_bps;
5152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
5162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
5172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifndef DISABLE_FLOAT_API
5182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian/* Don't use more than 60 ms for the frame size analysis */
5192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#define MAX_DYNAMIC_FRAMESIZE 24
5202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian/* Estimates how much the bitrate will be boosted based on the sub-frame energy */
5212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianstatic float transient_boost(const float *E, const float *E_1, int LM, int maxM)
5222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
5232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int i;
5242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int M;
5252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   float sumE=0, sumE_1=0;
5262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   float metric;
5272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
5282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   M = IMIN(maxM, (1<<LM)+1);
5292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   for (i=0;i<M;i++)
5302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
5312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      sumE += E[i];
5322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      sumE_1 += E_1[i];
5332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
5342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   metric = sumE*sumE_1/(M*M);
5352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   /*if (LM==3)
5362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      printf("%f\n", metric);*/
5372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   /*return metric>10 ? 1 : 0;*/
5382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   /*return MAX16(0,1-exp(-.25*(metric-2.)));*/
5392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   return MIN16(1,(float)sqrt(MAX16(0,.05f*(metric-2))));
5402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
5412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
5422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian/* Viterbi decoding trying to find the best frame size combination using look-ahead
5432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
5442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   State numbering:
5452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    0: unused
5462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    1:  2.5 ms
5472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    2:  5 ms (#1)
5482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    3:  5 ms (#2)
5492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    4: 10 ms (#1)
5502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    5: 10 ms (#2)
5512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    6: 10 ms (#3)
5522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    7: 10 ms (#4)
5532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    8: 20 ms (#1)
5542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    9: 20 ms (#2)
5552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   10: 20 ms (#3)
5562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   11: 20 ms (#4)
5572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   12: 20 ms (#5)
5582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   13: 20 ms (#6)
5592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   14: 20 ms (#7)
5602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   15: 20 ms (#8)
5612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian*/
5622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianstatic int transient_viterbi(const float *E, const float *E_1, int N, int frame_cost, int rate)
5632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
5642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int i;
5652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   float cost[MAX_DYNAMIC_FRAMESIZE][16];
5662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int states[MAX_DYNAMIC_FRAMESIZE][16];
5672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   float best_cost;
5682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int best_state;
5692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   float factor;
5702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   /* Take into account that we damp VBR in the 32 kb/s to 64 kb/s range. */
5712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (rate<80)
5722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      factor=0;
5732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   else if (rate>160)
5742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      factor=1;
5752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   else
5762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      factor = (rate-80.f)/80.f;
5772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   /* Makes variable framesize less aggressive at lower bitrates, but I can't
5782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      find any valid theoretical justification for this (other than it seems
5792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      to help) */
5802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   for (i=0;i<16;i++)
5812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
5822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      /* Impossible state */
5832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      states[0][i] = -1;
5842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      cost[0][i] = 1e10;
5852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
5862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   for (i=0;i<4;i++)
5872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
5882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      cost[0][1<<i] = (frame_cost + rate*(1<<i))*(1+factor*transient_boost(E, E_1, i, N+1));
5892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      states[0][1<<i] = i;
5902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
5912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   for (i=1;i<N;i++)
5922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
5932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      int j;
5942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
5952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      /* Follow continuations */
5962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      for (j=2;j<16;j++)
5972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
5982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         cost[i][j] = cost[i-1][j-1];
5992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         states[i][j] = j-1;
6002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      }
6012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
6022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      /* New frames */
6032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      for(j=0;j<4;j++)
6042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
6052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         int k;
6062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         float min_cost;
6072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         float curr_cost;
6082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         states[i][1<<j] = 1;
6092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         min_cost = cost[i-1][1];
6102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         for(k=1;k<4;k++)
6112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         {
6122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            float tmp = cost[i-1][(1<<(k+1))-1];
6132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (tmp < min_cost)
6142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
6152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               states[i][1<<j] = (1<<(k+1))-1;
6162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               min_cost = tmp;
6172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
6182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         }
6192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         curr_cost = (frame_cost + rate*(1<<j))*(1+factor*transient_boost(E+i, E_1+i, j, N-i+1));
6202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         cost[i][1<<j] = min_cost;
6212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         /* If part of the frame is outside the analysis window, only count part of the cost */
6222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         if (N-i < (1<<j))
6232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            cost[i][1<<j] += curr_cost*(float)(N-i)/(1<<j);
6242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         else
6252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            cost[i][1<<j] += curr_cost;
6262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      }
6272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
6282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
6292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   best_state=1;
6302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   best_cost = cost[N-1][1];
6312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   /* Find best end state (doesn't force a frame to end at N-1) */
6322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   for (i=2;i<16;i++)
6332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
6342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (cost[N-1][i]<best_cost)
6352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
6362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         best_cost = cost[N-1][i];
6372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         best_state = i;
6382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      }
6392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
6402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
6412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   /* Follow transitions back */
6422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   for (i=N-1;i>=0;i--)
6432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
6442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      /*printf("%d ", best_state);*/
6452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      best_state = states[i][best_state];
6462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
6472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   /*printf("%d\n", best_state);*/
6482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   return best_state;
6492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
6502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
6512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianint optimize_framesize(const opus_val16 *x, int len, int C, opus_int32 Fs,
6522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                int bitrate, opus_val16 tonality, float *mem, int buffering,
6532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                downmix_func downmix)
6542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
6552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int N;
6562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int i;
6572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   float e[MAX_DYNAMIC_FRAMESIZE+4];
6582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   float e_1[MAX_DYNAMIC_FRAMESIZE+3];
6592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   opus_val32 memx;
6602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int bestLM=0;
6612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int subframe;
6622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int pos;
6632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   VARDECL(opus_val32, sub);
6642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
6652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   subframe = Fs/400;
6662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   ALLOC(sub, subframe, opus_val32);
6672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   e[0]=mem[0];
6682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   e_1[0]=1.f/(EPSILON+mem[0]);
6692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (buffering)
6702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
6712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      /* Consider the CELT delay when not in restricted-lowdelay */
6722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      /* We assume the buffering is between 2.5 and 5 ms */
6732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      int offset = 2*subframe - buffering;
6742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      celt_assert(offset>=0 && offset <= subframe);
6752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      x += C*offset;
6762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      len -= offset;
6772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      e[1]=mem[1];
6782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      e_1[1]=1.f/(EPSILON+mem[1]);
6792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      e[2]=mem[2];
6802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      e_1[2]=1.f/(EPSILON+mem[2]);
6812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      pos = 3;
6822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   } else {
6832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      pos=1;
6842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
6852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   N=IMIN(len/subframe, MAX_DYNAMIC_FRAMESIZE);
6862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   /* Just silencing a warning, it's really initialized later */
6872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   memx = 0;
6882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   for (i=0;i<N;i++)
6892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
6902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      float tmp;
6912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      opus_val32 tmpx;
6922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      int j;
6932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      tmp=EPSILON;
6942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
6952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      downmix(x, sub, subframe, i*subframe, 0, -2, C);
6962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      if (i==0)
6972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         memx = sub[0];
6982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      for (j=0;j<subframe;j++)
6992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
7002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         tmpx = sub[j];
7012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         tmp += (tmpx-memx)*(float)(tmpx-memx);
7022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         memx = tmpx;
7032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      }
7042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      e[i+pos] = tmp;
7052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      e_1[i+pos] = 1.f/tmp;
7062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
7072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   /* Hack to get 20 ms working with APPLICATION_AUDIO
7082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      The real problem is that the corresponding memory needs to use 1.5 ms
7092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      from this frame and 1 ms from the next frame */
7102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   e[i+pos] = e[i+pos-1];
7112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (buffering)
7122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      N=IMIN(MAX_DYNAMIC_FRAMESIZE, N+2);
7132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   bestLM = transient_viterbi(e, e_1, N, (int)((1.f+.5f*tonality)*(60*C+40)), bitrate/400);
7142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   mem[0] = e[1<<bestLM];
7152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (buffering)
7162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
7172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      mem[1] = e[(1<<bestLM)+1];
7182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      mem[2] = e[(1<<bestLM)+2];
7192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
7202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   return bestLM;
7212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
7222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
7232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
7242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
7252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifndef DISABLE_FLOAT_API
7262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifdef FIXED_POINT
7272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#define PCM2VAL(x) FLOAT2INT16(x)
7282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#else
7292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#define PCM2VAL(x) SCALEIN(x)
7302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
7312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianvoid downmix_float(const void *_x, opus_val32 *sub, int subframe, int offset, int c1, int c2, int C)
7322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
7332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   const float *x;
7342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   opus_val32 scale;
7352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int j;
7362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   x = (const float *)_x;
7372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   for (j=0;j<subframe;j++)
7382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      sub[j] = PCM2VAL(x[(j+offset)*C+c1]);
7392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (c2>-1)
7402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
7412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      for (j=0;j<subframe;j++)
7422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         sub[j] += PCM2VAL(x[(j+offset)*C+c2]);
7432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   } else if (c2==-2)
7442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
7452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      int c;
7462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      for (c=1;c<C;c++)
7472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
7482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         for (j=0;j<subframe;j++)
7492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            sub[j] += PCM2VAL(x[(j+offset)*C+c]);
7502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      }
7512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
7522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifdef FIXED_POINT
7532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   scale = (1<<SIG_SHIFT);
7542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#else
7552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   scale = 1.f;
7562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
7572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (C==-2)
7582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      scale /= C;
7592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   else
7602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      scale /= 2;
7612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   for (j=0;j<subframe;j++)
7622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      sub[j] *= scale;
7632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
7642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
7652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
7662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianvoid downmix_int(const void *_x, opus_val32 *sub, int subframe, int offset, int c1, int c2, int C)
7672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
7682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   const opus_int16 *x;
7692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   opus_val32 scale;
7702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int j;
7712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   x = (const opus_int16 *)_x;
7722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   for (j=0;j<subframe;j++)
7732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      sub[j] = x[(j+offset)*C+c1];
7742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (c2>-1)
7752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
7762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      for (j=0;j<subframe;j++)
7772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         sub[j] += x[(j+offset)*C+c2];
7782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   } else if (c2==-2)
7792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
7802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      int c;
7812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      for (c=1;c<C;c++)
7822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      {
7832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         for (j=0;j<subframe;j++)
7842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            sub[j] += x[(j+offset)*C+c];
7852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      }
7862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
7872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifdef FIXED_POINT
7882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   scale = (1<<SIG_SHIFT);
7892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#else
7902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   scale = 1.f/32768;
7912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
7922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (C==-2)
7932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      scale /= C;
7942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   else
7952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      scale /= 2;
7962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   for (j=0;j<subframe;j++)
7972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      sub[j] *= scale;
7982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
7992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
8002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianopus_int32 frame_size_select(opus_int32 frame_size, int variable_duration, opus_int32 Fs)
8012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
8022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int new_size;
8032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (frame_size<Fs/400)
8042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      return -1;
8052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (variable_duration == OPUS_FRAMESIZE_ARG)
8062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      new_size = frame_size;
8072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   else if (variable_duration == OPUS_FRAMESIZE_VARIABLE)
8082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      new_size = Fs/50;
8092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   else if (variable_duration >= OPUS_FRAMESIZE_2_5_MS && variable_duration <= OPUS_FRAMESIZE_60_MS)
8102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      new_size = IMIN(3*Fs/50, (Fs/400)<<(variable_duration-OPUS_FRAMESIZE_2_5_MS));
8112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   else
8122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      return -1;
8132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (new_size>frame_size)
8142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      return -1;
8152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (400*new_size!=Fs && 200*new_size!=Fs && 100*new_size!=Fs &&
8162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            50*new_size!=Fs && 25*new_size!=Fs && 50*new_size!=3*Fs)
8172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      return -1;
8182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   return new_size;
8192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
8202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
8212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianopus_int32 compute_frame_size(const void *analysis_pcm, int frame_size,
8222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      int variable_duration, int C, opus_int32 Fs, int bitrate_bps,
8232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      int delay_compensation, downmix_func downmix
8242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifndef DISABLE_FLOAT_API
8252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      , float *subframe_mem
8262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
8272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      )
8282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
8292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifndef DISABLE_FLOAT_API
8302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (variable_duration == OPUS_FRAMESIZE_VARIABLE && frame_size >= Fs/200)
8312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
8322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      int LM = 3;
8332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      LM = optimize_framesize(analysis_pcm, frame_size, C, Fs, bitrate_bps,
8342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            0, subframe_mem, delay_compensation, downmix);
8352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      while ((Fs/400<<LM)>frame_size)
8362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         LM--;
8372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      frame_size = (Fs/400<<LM);
8382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   } else
8392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
8402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
8412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      frame_size = frame_size_select(frame_size, variable_duration, Fs);
8422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
8432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (frame_size<0)
8442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      return -1;
8452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   return frame_size;
8462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
8472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
8482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianopus_val16 compute_stereo_width(const opus_val16 *pcm, int frame_size, opus_int32 Fs, StereoWidthState *mem)
8492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
8502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   opus_val16 corr;
8512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   opus_val16 ldiff;
8522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   opus_val16 width;
8532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   opus_val32 xx, xy, yy;
8542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   opus_val16 sqrt_xx, sqrt_yy;
8552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   opus_val16 qrrt_xx, qrrt_yy;
8562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int frame_rate;
8572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int i;
8582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   opus_val16 short_alpha;
8592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
8602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   frame_rate = Fs/frame_size;
8612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   short_alpha = Q15ONE - 25*Q15ONE/IMAX(50,frame_rate);
8622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   xx=xy=yy=0;
8632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   for (i=0;i<frame_size;i+=4)
8642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
8652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      opus_val32 pxx=0;
8662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      opus_val32 pxy=0;
8672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      opus_val32 pyy=0;
8682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      opus_val16 x, y;
8692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      x = pcm[2*i];
8702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      y = pcm[2*i+1];
8712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      pxx = SHR32(MULT16_16(x,x),2);
8722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      pxy = SHR32(MULT16_16(x,y),2);
8732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      pyy = SHR32(MULT16_16(y,y),2);
8742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      x = pcm[2*i+2];
8752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      y = pcm[2*i+3];
8762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      pxx += SHR32(MULT16_16(x,x),2);
8772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      pxy += SHR32(MULT16_16(x,y),2);
8782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      pyy += SHR32(MULT16_16(y,y),2);
8792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      x = pcm[2*i+4];
8802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      y = pcm[2*i+5];
8812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      pxx += SHR32(MULT16_16(x,x),2);
8822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      pxy += SHR32(MULT16_16(x,y),2);
8832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      pyy += SHR32(MULT16_16(y,y),2);
8842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      x = pcm[2*i+6];
8852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      y = pcm[2*i+7];
8862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      pxx += SHR32(MULT16_16(x,x),2);
8872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      pxy += SHR32(MULT16_16(x,y),2);
8882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      pyy += SHR32(MULT16_16(y,y),2);
8892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
8902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      xx += SHR32(pxx, 10);
8912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      xy += SHR32(pxy, 10);
8922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      yy += SHR32(pyy, 10);
8932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
8942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   mem->XX += MULT16_32_Q15(short_alpha, xx-mem->XX);
8952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   mem->XY += MULT16_32_Q15(short_alpha, xy-mem->XY);
8962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   mem->YY += MULT16_32_Q15(short_alpha, yy-mem->YY);
8972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   mem->XX = MAX32(0, mem->XX);
8982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   mem->XY = MAX32(0, mem->XY);
8992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   mem->YY = MAX32(0, mem->YY);
9002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (MAX32(mem->XX, mem->YY)>QCONST16(8e-4f, 18))
9012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   {
9022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      sqrt_xx = celt_sqrt(mem->XX);
9032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      sqrt_yy = celt_sqrt(mem->YY);
9042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      qrrt_xx = celt_sqrt(sqrt_xx);
9052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      qrrt_yy = celt_sqrt(sqrt_yy);
9062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      /* Inter-channel correlation */
9072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      mem->XY = MIN32(mem->XY, sqrt_xx*sqrt_yy);
9082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      corr = SHR32(frac_div32(mem->XY,EPSILON+MULT16_16(sqrt_xx,sqrt_yy)),16);
9092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      /* Approximate loudness difference */
9102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      ldiff = Q15ONE*ABS16(qrrt_xx-qrrt_yy)/(EPSILON+qrrt_xx+qrrt_yy);
9112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      width = MULT16_16_Q15(celt_sqrt(QCONST32(1.f,30)-MULT16_16(corr,corr)), ldiff);
9122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      /* Smoothing over one second */
9132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      mem->smoothed_width += (width-mem->smoothed_width)/frame_rate;
9142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      /* Peak follower */
9152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      mem->max_follower = MAX16(mem->max_follower-QCONST16(.02f,15)/frame_rate, mem->smoothed_width);
9162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   } else {
9172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      width = 0;
9182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      corr=Q15ONE;
9192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      ldiff=0;
9202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   }
9212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   /*printf("%f %f %f %f %f ", corr/(float)Q15ONE, ldiff/(float)Q15ONE, width/(float)Q15ONE, mem->smoothed_width/(float)Q15ONE, mem->max_follower/(float)Q15ONE);*/
9222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   return EXTRACT16(MIN32(Q15ONE,20*mem->max_follower));
9232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
9242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
9252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianopus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_size,
9262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                unsigned char *data, opus_int32 out_data_bytes, int lsb_depth,
9272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                const void *analysis_pcm, opus_int32 analysis_size, int c1, int c2, int analysis_channels, downmix_func downmix)
9282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
9292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    void *silk_enc;
9302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    CELTEncoder *celt_enc;
9312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int i;
9322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int ret=0;
9332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    opus_int32 nBytes;
9342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    ec_enc enc;
9352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int bytes_target;
9362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int prefill=0;
9372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int start_band = 0;
9382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int redundancy = 0;
9392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int redundancy_bytes = 0; /* Number of bytes to use for redundancy frame */
9402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int celt_to_silk = 0;
9412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    VARDECL(opus_val16, pcm_buf);
9422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int nb_compr_bytes;
9432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int to_celt = 0;
9442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    opus_uint32 redundant_rng = 0;
9452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int cutoff_Hz, hp_freq_smth1;
9462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int voice_est; /* Probability of voice in Q7 */
9472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    opus_int32 equiv_rate;
9482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int delay_compensation;
9492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int frame_rate;
9502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    opus_int32 max_rate; /* Max bitrate we're allowed to use */
9512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int curr_bandwidth;
9522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    opus_val16 HB_gain;
9532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    opus_int32 max_data_bytes; /* Max number of bytes we're allowed to use */
9542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int total_buffer;
9552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    opus_val16 stereo_width;
9562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    const CELTMode *celt_mode;
9572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    AnalysisInfo analysis_info;
9582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int analysis_read_pos_bak=-1;
9592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int analysis_read_subframe_bak=-1;
9602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    VARDECL(opus_val16, tmp_prefill);
9612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
9622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    ALLOC_STACK;
9632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
9642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    max_data_bytes = IMIN(1276, out_data_bytes);
9652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
9662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->rangeFinal = 0;
9672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if ((!st->variable_duration && 400*frame_size != st->Fs && 200*frame_size != st->Fs && 100*frame_size != st->Fs &&
9682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         50*frame_size != st->Fs &&  25*frame_size != st->Fs &&  50*frame_size != 3*st->Fs)
9692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         || (400*frame_size < st->Fs)
9702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         || max_data_bytes<=0
9712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         )
9722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    {
9732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       RESTORE_STACK;
9742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       return OPUS_BAD_ARG;
9752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
9762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    silk_enc = (char*)st+st->silk_enc_offset;
9772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset);
9782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)
9792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       delay_compensation = 0;
9802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    else
9812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       delay_compensation = st->delay_compensation;
9822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
9832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    lsb_depth = IMIN(lsb_depth, st->lsb_depth);
9842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
9852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    analysis_info.valid = 0;
9862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    celt_encoder_ctl(celt_enc, CELT_GET_MODE(&celt_mode));
9872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifndef DISABLE_FLOAT_API
9882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifdef FIXED_POINT
9892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (st->silk_mode.complexity >= 10 && st->Fs==48000)
9902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#else
9912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (st->silk_mode.complexity >= 7 && st->Fs==48000)
9922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
9932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    {
9942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       analysis_read_pos_bak = st->analysis.read_pos;
9952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       analysis_read_subframe_bak = st->analysis.read_subframe;
9962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       run_analysis(&st->analysis, celt_mode, analysis_pcm, analysis_size, frame_size,
9972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian             c1, c2, analysis_channels, st->Fs,
9982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian             lsb_depth, downmix, &analysis_info);
9992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
10002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
10012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
10022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->voice_ratio = -1;
10032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
10042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifndef DISABLE_FLOAT_API
10052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->detected_bandwidth = 0;
10062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (analysis_info.valid)
10072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    {
10082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       int analysis_bandwidth;
10092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       if (st->signal_type == OPUS_AUTO)
10102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          st->voice_ratio = (int)floor(.5+100*(1-analysis_info.music_prob));
10112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
10122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       analysis_bandwidth = analysis_info.bandwidth;
10132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       if (analysis_bandwidth<=12)
10142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          st->detected_bandwidth = OPUS_BANDWIDTH_NARROWBAND;
10152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       else if (analysis_bandwidth<=14)
10162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          st->detected_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND;
10172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       else if (analysis_bandwidth<=16)
10182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          st->detected_bandwidth = OPUS_BANDWIDTH_WIDEBAND;
10192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       else if (analysis_bandwidth<=18)
10202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          st->detected_bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND;
10212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       else
10222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          st->detected_bandwidth = OPUS_BANDWIDTH_FULLBAND;
10232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
10242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
10252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
10262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (st->channels==2 && st->force_channels!=1)
10272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       stereo_width = compute_stereo_width(pcm, frame_size, st->Fs, &st->width_mem);
10282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    else
10292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       stereo_width = 0;
10302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    total_buffer = delay_compensation;
10312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->bitrate_bps = user_bitrate_to_bitrate(st, frame_size, max_data_bytes);
10322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
10332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    frame_rate = st->Fs/frame_size;
10342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (max_data_bytes<3 || st->bitrate_bps < 3*frame_rate*8
10352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       || (frame_rate<50 && (max_data_bytes*frame_rate<300 || st->bitrate_bps < 2400)))
10362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    {
10372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       /*If the space is too low to do something useful, emit 'PLC' frames.*/
10382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       int tocmode = st->mode;
10392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       int bw = st->bandwidth == 0 ? OPUS_BANDWIDTH_NARROWBAND : st->bandwidth;
10402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       if (tocmode==0)
10412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          tocmode = MODE_SILK_ONLY;
10422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       if (frame_rate>100)
10432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          tocmode = MODE_CELT_ONLY;
10442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       if (frame_rate < 50)
10452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          tocmode = MODE_SILK_ONLY;
10462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       if(tocmode==MODE_SILK_ONLY&&bw>OPUS_BANDWIDTH_WIDEBAND)
10472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          bw=OPUS_BANDWIDTH_WIDEBAND;
10482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       else if (tocmode==MODE_CELT_ONLY&&bw==OPUS_BANDWIDTH_MEDIUMBAND)
10492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          bw=OPUS_BANDWIDTH_NARROWBAND;
10502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       else if (bw<=OPUS_BANDWIDTH_SUPERWIDEBAND)
10512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          bw=OPUS_BANDWIDTH_SUPERWIDEBAND;
10522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       data[0] = gen_toc(tocmode, frame_rate, bw, st->stream_channels);
10532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       RESTORE_STACK;
10542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       return 1;
10552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
10562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (!st->use_vbr)
10572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    {
10582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       int cbrBytes;
10592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       cbrBytes = IMIN( (st->bitrate_bps + 4*frame_rate)/(8*frame_rate) , max_data_bytes);
10602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       st->bitrate_bps = cbrBytes * (8*frame_rate);
10612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       max_data_bytes = cbrBytes;
10622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
10632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    max_rate = frame_rate*max_data_bytes*8;
10642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
10652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    /* Equivalent 20-ms rate for mode/channel/bandwidth decisions */
10662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    equiv_rate = st->bitrate_bps - (40*st->channels+20)*(st->Fs/frame_size - 50);
10672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
10682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (st->signal_type == OPUS_SIGNAL_VOICE)
10692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       voice_est = 127;
10702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    else if (st->signal_type == OPUS_SIGNAL_MUSIC)
10712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       voice_est = 0;
10722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    else if (st->voice_ratio >= 0)
10732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    {
10742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       voice_est = st->voice_ratio*327>>8;
10752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       /* For AUDIO, never be more than 90% confident of having speech */
10762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       if (st->application == OPUS_APPLICATION_AUDIO)
10772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          voice_est = IMIN(voice_est, 115);
10782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    } else if (st->application == OPUS_APPLICATION_VOIP)
10792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       voice_est = 115;
10802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    else
10812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       voice_est = 48;
10822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
10832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (st->force_channels!=OPUS_AUTO && st->channels == 2)
10842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    {
10852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        st->stream_channels = st->force_channels;
10862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    } else {
10872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifdef FUZZING
10882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       /* Random mono/stereo decision */
10892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       if (st->channels == 2 && (rand()&0x1F)==0)
10902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          st->stream_channels = 3-st->stream_channels;
10912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#else
10922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       /* Rate-dependent mono-stereo decision */
10932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       if (st->channels == 2)
10942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       {
10952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          opus_int32 stereo_threshold;
10962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          stereo_threshold = stereo_music_threshold + ((voice_est*voice_est*(stereo_voice_threshold-stereo_music_threshold))>>14);
10972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          if (st->stream_channels == 2)
10982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian             stereo_threshold -= 1000;
10992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          else
11002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian             stereo_threshold += 1000;
11012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          st->stream_channels = (equiv_rate > stereo_threshold) ? 2 : 1;
11022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       } else {
11032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          st->stream_channels = st->channels;
11042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       }
11052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
11062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
11072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    equiv_rate = st->bitrate_bps - (40*st->stream_channels+20)*(st->Fs/frame_size - 50);
11082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
11092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    /* Mode selection depending on application and signal type */
11102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)
11112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    {
11122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       st->mode = MODE_CELT_ONLY;
11132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    } else if (st->user_forced_mode == OPUS_AUTO)
11142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    {
11152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifdef FUZZING
11162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       /* Random mode switching */
11172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       if ((rand()&0xF)==0)
11182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       {
11192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          if ((rand()&0x1)==0)
11202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian             st->mode = MODE_CELT_ONLY;
11212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          else
11222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian             st->mode = MODE_SILK_ONLY;
11232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       } else {
11242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          if (st->prev_mode==MODE_CELT_ONLY)
11252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian             st->mode = MODE_CELT_ONLY;
11262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          else
11272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian             st->mode = MODE_SILK_ONLY;
11282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       }
11292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#else
11302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       opus_int32 mode_voice, mode_music;
11312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       opus_int32 threshold;
11322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
11332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       /* Interpolate based on stereo width */
11342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       mode_voice = (opus_int32)(MULT16_32_Q15(Q15ONE-stereo_width,mode_thresholds[0][0])
11352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian             + MULT16_32_Q15(stereo_width,mode_thresholds[1][0]));
11362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       mode_music = (opus_int32)(MULT16_32_Q15(Q15ONE-stereo_width,mode_thresholds[1][1])
11372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian             + MULT16_32_Q15(stereo_width,mode_thresholds[1][1]));
11382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       /* Interpolate based on speech/music probability */
11392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       threshold = mode_music + ((voice_est*voice_est*(mode_voice-mode_music))>>14);
11402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       /* Bias towards SILK for VoIP because of some useful features */
11412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       if (st->application == OPUS_APPLICATION_VOIP)
11422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          threshold += 8000;
11432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
11442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       /*printf("%f %d\n", stereo_width/(float)Q15ONE, threshold);*/
11452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       /* Hysteresis */
11462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       if (st->prev_mode == MODE_CELT_ONLY)
11472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           threshold -= 4000;
11482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       else if (st->prev_mode>0)
11492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           threshold += 4000;
11502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
11512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       st->mode = (equiv_rate >= threshold) ? MODE_CELT_ONLY: MODE_SILK_ONLY;
11522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
11532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       /* When FEC is enabled and there's enough packet loss, use SILK */
11542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       if (st->silk_mode.useInBandFEC && st->silk_mode.packetLossPercentage > (128-voice_est)>>4)
11552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          st->mode = MODE_SILK_ONLY;
11562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       /* When encoding voice and DTX is enabled, set the encoder to SILK mode (at least for now) */
11572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       if (st->silk_mode.useDTX && voice_est > 100)
11582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          st->mode = MODE_SILK_ONLY;
11592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
11602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    } else {
11612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       st->mode = st->user_forced_mode;
11622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
11632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
11642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    /* Override the chosen mode to make sure we meet the requested frame size */
11652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (st->mode != MODE_CELT_ONLY && frame_size < st->Fs/100)
11662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       st->mode = MODE_CELT_ONLY;
11672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (st->lfe)
11682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       st->mode = MODE_CELT_ONLY;
11692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    /* If max_data_bytes represents less than 8 kb/s, switch to CELT-only mode */
11702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (max_data_bytes < (frame_rate > 50 ? 12000 : 8000)*frame_size / (st->Fs * 8))
11712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       st->mode = MODE_CELT_ONLY;
11722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
11732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (st->stream_channels == 1 && st->prev_channels ==2 && st->silk_mode.toMono==0
11742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          && st->mode != MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY)
11752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    {
11762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       /* Delay stereo->mono transition by two frames so that SILK can do a smooth downmix */
11772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       st->silk_mode.toMono = 1;
11782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       st->stream_channels = 2;
11792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    } else {
11802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       st->silk_mode.toMono = 0;
11812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
11822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
11832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (st->prev_mode > 0 &&
11842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        ((st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) ||
11852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    (st->mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY)))
11862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    {
11872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        redundancy = 1;
11882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        celt_to_silk = (st->mode != MODE_CELT_ONLY);
11892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        if (!celt_to_silk)
11902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
11912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            /* Switch to SILK/hybrid if frame size is 10 ms or more*/
11922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (frame_size >= st->Fs/100)
11932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
11942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                st->mode = st->prev_mode;
11952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                to_celt = 1;
11962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            } else {
11972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                redundancy=0;
11982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
11992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
12002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
12012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    /* For the first frame at a new SILK bandwidth */
12022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (st->silk_bw_switch)
12032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    {
12042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       redundancy = 1;
12052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       celt_to_silk = 1;
12062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       st->silk_bw_switch = 0;
12072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       prefill=1;
12082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
12092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
12102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (redundancy)
12112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    {
12122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       /* Fair share of the max size allowed */
12132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       redundancy_bytes = IMIN(257, max_data_bytes*(opus_int32)(st->Fs/200)/(frame_size+st->Fs/200));
12142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       /* For VBR, target the actual bitrate (subject to the limit above) */
12152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       if (st->use_vbr)
12162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          redundancy_bytes = IMIN(redundancy_bytes, st->bitrate_bps/1600);
12172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
12182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
12192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY)
12202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    {
12212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        silk_EncControlStruct dummy;
12222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        silk_InitEncoder( silk_enc, st->arch, &dummy);
12232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        prefill=1;
12242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
12252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
12262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    /* Automatic (rate-dependent) bandwidth selection */
12272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (st->mode == MODE_CELT_ONLY || st->first || st->silk_mode.allowBandwidthSwitch)
12282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    {
12292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        const opus_int32 *voice_bandwidth_thresholds, *music_bandwidth_thresholds;
12302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        opus_int32 bandwidth_thresholds[8];
12312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        int bandwidth = OPUS_BANDWIDTH_FULLBAND;
12322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        opus_int32 equiv_rate2;
12332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
12342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        equiv_rate2 = equiv_rate;
12352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        if (st->mode != MODE_CELT_ONLY)
12362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
12372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           /* Adjust the threshold +/- 10% depending on complexity */
12382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           equiv_rate2 = equiv_rate2 * (45+st->silk_mode.complexity)/50;
12392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           /* CBR is less efficient by ~1 kb/s */
12402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           if (!st->use_vbr)
12412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian              equiv_rate2 -= 1000;
12422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
12432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        if (st->channels==2 && st->force_channels!=1)
12442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
12452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           voice_bandwidth_thresholds = stereo_voice_bandwidth_thresholds;
12462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           music_bandwidth_thresholds = stereo_music_bandwidth_thresholds;
12472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        } else {
12482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           voice_bandwidth_thresholds = mono_voice_bandwidth_thresholds;
12492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           music_bandwidth_thresholds = mono_music_bandwidth_thresholds;
12502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
12512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        /* Interpolate bandwidth thresholds depending on voice estimation */
12522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        for (i=0;i<8;i++)
12532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
12542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           bandwidth_thresholds[i] = music_bandwidth_thresholds[i]
12552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                    + ((voice_est*voice_est*(voice_bandwidth_thresholds[i]-music_bandwidth_thresholds[i]))>>14);
12562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
12572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        do {
12582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            int threshold, hysteresis;
12592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            threshold = bandwidth_thresholds[2*(bandwidth-OPUS_BANDWIDTH_MEDIUMBAND)];
12602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            hysteresis = bandwidth_thresholds[2*(bandwidth-OPUS_BANDWIDTH_MEDIUMBAND)+1];
12612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (!st->first)
12622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
12632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                if (st->bandwidth >= bandwidth)
12642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                    threshold -= hysteresis;
12652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                else
12662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                    threshold += hysteresis;
12672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
12682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (equiv_rate2 >= threshold)
12692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                break;
12702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        } while (--bandwidth>OPUS_BANDWIDTH_NARROWBAND);
12712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        st->bandwidth = bandwidth;
12722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        /* Prevents any transition to SWB/FB until the SILK layer has fully
12732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           switched to WB mode and turned the variable LP filter off */
12742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        if (!st->first && st->mode != MODE_CELT_ONLY && !st->silk_mode.inWBmodeWithoutVariableLP && st->bandwidth > OPUS_BANDWIDTH_WIDEBAND)
12752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            st->bandwidth = OPUS_BANDWIDTH_WIDEBAND;
12762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
12772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
12782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (st->bandwidth>st->max_bandwidth)
12792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       st->bandwidth = st->max_bandwidth;
12802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
12812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (st->user_bandwidth != OPUS_AUTO)
12822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        st->bandwidth = st->user_bandwidth;
12832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
12842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    /* This prevents us from using hybrid at unsafe CBR/max rates */
12852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (st->mode != MODE_CELT_ONLY && max_rate < 15000)
12862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    {
12872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       st->bandwidth = IMIN(st->bandwidth, OPUS_BANDWIDTH_WIDEBAND);
12882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
12892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
12902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    /* Prevents Opus from wasting bits on frequencies that are above
12912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       the Nyquist rate of the input signal */
12922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (st->Fs <= 24000 && st->bandwidth > OPUS_BANDWIDTH_SUPERWIDEBAND)
12932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        st->bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND;
12942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (st->Fs <= 16000 && st->bandwidth > OPUS_BANDWIDTH_WIDEBAND)
12952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        st->bandwidth = OPUS_BANDWIDTH_WIDEBAND;
12962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (st->Fs <= 12000 && st->bandwidth > OPUS_BANDWIDTH_MEDIUMBAND)
12972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        st->bandwidth = OPUS_BANDWIDTH_MEDIUMBAND;
12982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (st->Fs <= 8000 && st->bandwidth > OPUS_BANDWIDTH_NARROWBAND)
12992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        st->bandwidth = OPUS_BANDWIDTH_NARROWBAND;
13002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifndef DISABLE_FLOAT_API
13012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    /* Use detected bandwidth to reduce the encoded bandwidth. */
13022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (st->detected_bandwidth && st->user_bandwidth == OPUS_AUTO)
13032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    {
13042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       int min_detected_bandwidth;
13052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       /* Makes bandwidth detection more conservative just in case the detector
13062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          gets it wrong when we could have coded a high bandwidth transparently.
13072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          When operating in SILK/hybrid mode, we don't go below wideband to avoid
13082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          more complicated switches that require redundancy. */
13092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       if (equiv_rate <= 18000*st->stream_channels && st->mode == MODE_CELT_ONLY)
13102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          min_detected_bandwidth = OPUS_BANDWIDTH_NARROWBAND;
13112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       else if (equiv_rate <= 24000*st->stream_channels && st->mode == MODE_CELT_ONLY)
13122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          min_detected_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND;
13132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       else if (equiv_rate <= 30000*st->stream_channels)
13142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          min_detected_bandwidth = OPUS_BANDWIDTH_WIDEBAND;
13152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       else if (equiv_rate <= 44000*st->stream_channels)
13162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          min_detected_bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND;
13172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       else
13182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          min_detected_bandwidth = OPUS_BANDWIDTH_FULLBAND;
13192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
13202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       st->detected_bandwidth = IMAX(st->detected_bandwidth, min_detected_bandwidth);
13212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       st->bandwidth = IMIN(st->bandwidth, st->detected_bandwidth);
13222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
13232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
13242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    celt_encoder_ctl(celt_enc, OPUS_SET_LSB_DEPTH(lsb_depth));
13252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
13262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    /* CELT mode doesn't support mediumband, use wideband instead */
13272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (st->mode == MODE_CELT_ONLY && st->bandwidth == OPUS_BANDWIDTH_MEDIUMBAND)
13282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        st->bandwidth = OPUS_BANDWIDTH_WIDEBAND;
13292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (st->lfe)
13302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       st->bandwidth = OPUS_BANDWIDTH_NARROWBAND;
13312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
13322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    /* Can't support higher than wideband for >20 ms frames */
13332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (frame_size > st->Fs/50 && (st->mode == MODE_CELT_ONLY || st->bandwidth > OPUS_BANDWIDTH_WIDEBAND))
13342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    {
13352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       VARDECL(unsigned char, tmp_data);
13362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       int nb_frames;
13372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       int bak_mode, bak_bandwidth, bak_channels, bak_to_mono;
13382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       VARDECL(OpusRepacketizer, rp);
13392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       opus_int32 bytes_per_frame;
13402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       opus_int32 repacketize_len;
13412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
13422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifndef DISABLE_FLOAT_API
13432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       if (analysis_read_pos_bak!= -1)
13442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       {
13452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          st->analysis.read_pos = analysis_read_pos_bak;
13462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          st->analysis.read_subframe = analysis_read_subframe_bak;
13472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       }
13482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
13492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
13502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       nb_frames = frame_size > st->Fs/25 ? 3 : 2;
13512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       bytes_per_frame = IMIN(1276,(out_data_bytes-3)/nb_frames);
13522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
13532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       ALLOC(tmp_data, nb_frames*bytes_per_frame, unsigned char);
13542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
13552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       ALLOC(rp, 1, OpusRepacketizer);
13562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       opus_repacketizer_init(rp);
13572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
13582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       bak_mode = st->user_forced_mode;
13592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       bak_bandwidth = st->user_bandwidth;
13602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       bak_channels = st->force_channels;
13612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
13622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       st->user_forced_mode = st->mode;
13632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       st->user_bandwidth = st->bandwidth;
13642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       st->force_channels = st->stream_channels;
13652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       bak_to_mono = st->silk_mode.toMono;
13662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
13672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       if (bak_to_mono)
13682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          st->force_channels = 1;
13692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       else
13702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          st->prev_channels = st->stream_channels;
13712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       for (i=0;i<nb_frames;i++)
13722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       {
13732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          int tmp_len;
13742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          st->silk_mode.toMono = 0;
13752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          /* When switching from SILK/Hybrid to CELT, only ask for a switch at the last frame */
13762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          if (to_celt && i==nb_frames-1)
13772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian             st->user_forced_mode = MODE_CELT_ONLY;
13782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          tmp_len = opus_encode_native(st, pcm+i*(st->channels*st->Fs/50), st->Fs/50,
13792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                tmp_data+i*bytes_per_frame, bytes_per_frame, lsb_depth,
13802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                NULL, 0, c1, c2, analysis_channels, downmix);
13812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          if (tmp_len<0)
13822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          {
13832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian             RESTORE_STACK;
13842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian             return OPUS_INTERNAL_ERROR;
13852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          }
13862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          ret = opus_repacketizer_cat(rp, tmp_data+i*bytes_per_frame, tmp_len);
13872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          if (ret<0)
13882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          {
13892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian             RESTORE_STACK;
13902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian             return OPUS_INTERNAL_ERROR;
13912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          }
13922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       }
13932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       if (st->use_vbr)
13942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          repacketize_len = out_data_bytes;
13952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       else
13962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          repacketize_len = IMIN(3*st->bitrate_bps/(3*8*50/nb_frames), out_data_bytes);
13972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       ret = opus_repacketizer_out_range_impl(rp, 0, nb_frames, data, repacketize_len, 0, !st->use_vbr);
13982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       if (ret<0)
13992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       {
14002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          RESTORE_STACK;
14012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          return OPUS_INTERNAL_ERROR;
14022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       }
14032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       st->user_forced_mode = bak_mode;
14042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       st->user_bandwidth = bak_bandwidth;
14052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       st->force_channels = bak_channels;
14062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       st->silk_mode.toMono = bak_to_mono;
14072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       RESTORE_STACK;
14082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       return ret;
14092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
14102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    curr_bandwidth = st->bandwidth;
14112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
14122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    /* Chooses the appropriate mode for speech
14132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       *NEVER* switch to/from CELT-only mode here as this will invalidate some assumptions */
14142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (st->mode == MODE_SILK_ONLY && curr_bandwidth > OPUS_BANDWIDTH_WIDEBAND)
14152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        st->mode = MODE_HYBRID;
14162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (st->mode == MODE_HYBRID && curr_bandwidth <= OPUS_BANDWIDTH_WIDEBAND)
14172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        st->mode = MODE_SILK_ONLY;
14182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
14192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    /* printf("%d %d %d %d\n", st->bitrate_bps, st->stream_channels, st->mode, curr_bandwidth); */
14202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    bytes_target = IMIN(max_data_bytes-redundancy_bytes, st->bitrate_bps * frame_size / (st->Fs * 8)) - 1;
14212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
14222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    data += 1;
14232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
14242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    ec_enc_init(&enc, data, max_data_bytes-1);
14252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
14262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    ALLOC(pcm_buf, (total_buffer+frame_size)*st->channels, opus_val16);
14272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    for (i=0;i<total_buffer*st->channels;i++)
14282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       pcm_buf[i] = st->delay_buffer[(st->encoder_buffer-total_buffer)*st->channels+i];
14292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
14302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (st->mode == MODE_CELT_ONLY)
14312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       hp_freq_smth1 = silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 );
14322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    else
14332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       hp_freq_smth1 = ((silk_encoder*)silk_enc)->state_Fxx[0].sCmn.variable_HP_smth1_Q15;
14342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
14352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->variable_HP_smth2_Q15 = silk_SMLAWB( st->variable_HP_smth2_Q15,
14362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          hp_freq_smth1 - st->variable_HP_smth2_Q15, SILK_FIX_CONST( VARIABLE_HP_SMTH_COEF2, 16 ) );
14372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
14382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    /* convert from log scale to Hertz */
14392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    cutoff_Hz = silk_log2lin( silk_RSHIFT( st->variable_HP_smth2_Q15, 8 ) );
14402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
14412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (st->application == OPUS_APPLICATION_VOIP)
14422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    {
14432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       hp_cutoff(pcm, cutoff_Hz, &pcm_buf[total_buffer*st->channels], st->hp_mem, frame_size, st->channels, st->Fs);
14442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    } else {
14452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       dc_reject(pcm, 3, &pcm_buf[total_buffer*st->channels], st->hp_mem, frame_size, st->channels, st->Fs);
14462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
14472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
14482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
14492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
14502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    /* SILK processing */
14512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    HB_gain = Q15ONE;
14522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (st->mode != MODE_CELT_ONLY)
14532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    {
14542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        opus_int32 total_bitRate, celt_rate;
14552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifdef FIXED_POINT
14562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       const opus_int16 *pcm_silk;
14572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#else
14582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       VARDECL(opus_int16, pcm_silk);
14592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       ALLOC(pcm_silk, st->channels*frame_size, opus_int16);
14602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
14612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
14622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        /* Distribute bits between SILK and CELT */
14632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        total_bitRate = 8 * bytes_target * frame_rate;
14642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        if( st->mode == MODE_HYBRID ) {
14652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            int HB_gain_ref;
14662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            /* Base rate for SILK */
14672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            st->silk_mode.bitRate = st->stream_channels * ( 5000 + 1000 * ( st->Fs == 100 * frame_size ) );
14682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if( curr_bandwidth == OPUS_BANDWIDTH_SUPERWIDEBAND ) {
14692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                /* SILK gets 2/3 of the remaining bits */
14702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                st->silk_mode.bitRate += ( total_bitRate - st->silk_mode.bitRate ) * 2 / 3;
14712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            } else { /* FULLBAND */
14722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                /* SILK gets 3/5 of the remaining bits */
14732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                st->silk_mode.bitRate += ( total_bitRate - st->silk_mode.bitRate ) * 3 / 5;
14742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
14752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            /* Don't let SILK use more than 80% */
14762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if( st->silk_mode.bitRate > total_bitRate * 4/5 ) {
14772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                st->silk_mode.bitRate = total_bitRate * 4/5;
14782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
14792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (!st->energy_masking)
14802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
14812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               /* Increasingly attenuate high band when it gets allocated fewer bits */
14822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               celt_rate = total_bitRate - st->silk_mode.bitRate;
14832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               HB_gain_ref = (curr_bandwidth == OPUS_BANDWIDTH_SUPERWIDEBAND) ? 3000 : 3600;
14842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               HB_gain = SHL32((opus_val32)celt_rate, 9) / SHR32((opus_val32)celt_rate + st->stream_channels * HB_gain_ref, 6);
14852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               HB_gain = HB_gain < Q15ONE*6/7 ? HB_gain + Q15ONE/7 : Q15ONE;
14862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
14872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        } else {
14882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            /* SILK gets all bits */
14892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            st->silk_mode.bitRate = total_bitRate;
14902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
14912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
14922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        /* Surround masking for SILK */
14932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        if (st->energy_masking && st->use_vbr && !st->lfe)
14942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
14952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           opus_val32 mask_sum=0;
14962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           opus_val16 masking_depth;
14972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           opus_int32 rate_offset;
14982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           int c;
14992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           int end = 17;
15002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           opus_int16 srate = 16000;
15012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           if (st->bandwidth == OPUS_BANDWIDTH_NARROWBAND)
15022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           {
15032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian              end = 13;
15042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian              srate = 8000;
15052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           } else if (st->bandwidth == OPUS_BANDWIDTH_MEDIUMBAND)
15062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           {
15072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian              end = 15;
15082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian              srate = 12000;
15092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           }
15102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           for (c=0;c<st->channels;c++)
15112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           {
15122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian              for(i=0;i<end;i++)
15132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian              {
15142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                 opus_val16 mask;
15152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                 mask = MAX16(MIN16(st->energy_masking[21*c+i],
15162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                        QCONST16(.5f, DB_SHIFT)), -QCONST16(2.0f, DB_SHIFT));
15172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                 if (mask > 0)
15182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                    mask = HALF16(mask);
15192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                 mask_sum += mask;
15202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian              }
15212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           }
15222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           /* Conservative rate reduction, we cut the masking in half */
15232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           masking_depth = mask_sum / end*st->channels;
15242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           masking_depth += QCONST16(.2f, DB_SHIFT);
15252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           rate_offset = (opus_int32)PSHR32(MULT16_16(srate, masking_depth), DB_SHIFT);
15262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           rate_offset = MAX32(rate_offset, -2*st->silk_mode.bitRate/3);
15272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           /* Split the rate change between the SILK and CELT part for hybrid. */
15282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           if (st->bandwidth==OPUS_BANDWIDTH_SUPERWIDEBAND || st->bandwidth==OPUS_BANDWIDTH_FULLBAND)
15292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian              st->silk_mode.bitRate += 3*rate_offset/5;
15302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           else
15312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian              st->silk_mode.bitRate += rate_offset;
15322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           bytes_target += rate_offset * frame_size / (8 * st->Fs);
15332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
15342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
15352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        st->silk_mode.payloadSize_ms = 1000 * frame_size / st->Fs;
15362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        st->silk_mode.nChannelsAPI = st->channels;
15372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        st->silk_mode.nChannelsInternal = st->stream_channels;
15382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        if (curr_bandwidth == OPUS_BANDWIDTH_NARROWBAND) {
15392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            st->silk_mode.desiredInternalSampleRate = 8000;
15402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        } else if (curr_bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) {
15412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            st->silk_mode.desiredInternalSampleRate = 12000;
15422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        } else {
15432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            silk_assert( st->mode == MODE_HYBRID || curr_bandwidth == OPUS_BANDWIDTH_WIDEBAND );
15442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            st->silk_mode.desiredInternalSampleRate = 16000;
15452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
15462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        if( st->mode == MODE_HYBRID ) {
15472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            /* Don't allow bandwidth reduction at lowest bitrates in hybrid mode */
15482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            st->silk_mode.minInternalSampleRate = 16000;
15492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        } else {
15502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            st->silk_mode.minInternalSampleRate = 8000;
15512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
15522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
15532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        if (st->mode == MODE_SILK_ONLY)
15542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
15552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           opus_int32 effective_max_rate = max_rate;
15562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           st->silk_mode.maxInternalSampleRate = 16000;
15572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           if (frame_rate > 50)
15582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian              effective_max_rate = effective_max_rate*2/3;
15592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           if (effective_max_rate < 13000)
15602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           {
15612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian              st->silk_mode.maxInternalSampleRate = 12000;
15622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian              st->silk_mode.desiredInternalSampleRate = IMIN(12000, st->silk_mode.desiredInternalSampleRate);
15632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           }
15642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           if (effective_max_rate < 9600)
15652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           {
15662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian              st->silk_mode.maxInternalSampleRate = 8000;
15672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian              st->silk_mode.desiredInternalSampleRate = IMIN(8000, st->silk_mode.desiredInternalSampleRate);
15682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           }
15692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        } else {
15702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           st->silk_mode.maxInternalSampleRate = 16000;
15712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
15722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
15732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        st->silk_mode.useCBR = !st->use_vbr;
15742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
15752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        /* Call SILK encoder for the low band */
15762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        nBytes = IMIN(1275, max_data_bytes-1-redundancy_bytes);
15772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
15782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        st->silk_mode.maxBits = nBytes*8;
15792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        /* Only allow up to 90% of the bits for hybrid mode*/
15802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        if (st->mode == MODE_HYBRID)
15812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           st->silk_mode.maxBits = (opus_int32)st->silk_mode.maxBits*9/10;
15822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        if (st->silk_mode.useCBR)
15832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
15842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           st->silk_mode.maxBits = (st->silk_mode.bitRate * frame_size / (st->Fs * 8))*8;
15852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           /* Reduce the initial target to make it easier to reach the CBR rate */
15862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           st->silk_mode.bitRate = IMAX(1, st->silk_mode.bitRate-2000);
15872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
15882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
15892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        if (prefill)
15902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
15912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_int32 zero=0;
15922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            int prefill_offset;
15932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            /* Use a smooth onset for the SILK prefill to avoid the encoder trying to encode
15942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               a discontinuity. The exact location is what we need to avoid leaving any "gap"
15952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               in the audio when mixing with the redundant CELT frame. Here we can afford to
15962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               overwrite st->delay_buffer because the only thing that uses it before it gets
15972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               rewritten is tmp_prefill[] and even then only the part after the ramp really
15982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               gets used (rather than sent to the encoder and discarded) */
15992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            prefill_offset = st->channels*(st->encoder_buffer-st->delay_compensation-st->Fs/400);
16002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            gain_fade(st->delay_buffer+prefill_offset, st->delay_buffer+prefill_offset,
16012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                  0, Q15ONE, celt_mode->overlap, st->Fs/400, st->channels, celt_mode->window, st->Fs);
16022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            for(i=0;i<prefill_offset;i++)
16032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               st->delay_buffer[i]=0;
16042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifdef FIXED_POINT
16052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            pcm_silk = st->delay_buffer;
16062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#else
16072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            for (i=0;i<st->encoder_buffer*st->channels;i++)
16082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                pcm_silk[i] = FLOAT2INT16(st->delay_buffer[i]);
16092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
16102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            silk_Encode( silk_enc, &st->silk_mode, pcm_silk, st->encoder_buffer, NULL, &zero, 1 );
16112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
16122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
16132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifdef FIXED_POINT
16142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        pcm_silk = pcm_buf+total_buffer*st->channels;
16152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#else
16162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        for (i=0;i<frame_size*st->channels;i++)
16172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            pcm_silk[i] = FLOAT2INT16(pcm_buf[total_buffer*st->channels + i]);
16182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
16192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        ret = silk_Encode( silk_enc, &st->silk_mode, pcm_silk, frame_size, &enc, &nBytes, 0 );
16202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        if( ret ) {
16212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            /*fprintf (stderr, "SILK encode error: %d\n", ret);*/
16222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            /* Handle error */
16232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           RESTORE_STACK;
16242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           return OPUS_INTERNAL_ERROR;
16252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
16262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        if (nBytes==0)
16272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
16282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           st->rangeFinal = 0;
16292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           data[-1] = gen_toc(st->mode, st->Fs/frame_size, curr_bandwidth, st->stream_channels);
16302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           RESTORE_STACK;
16312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           return 1;
16322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
16332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        /* Extract SILK internal bandwidth for signaling in first byte */
16342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        if( st->mode == MODE_SILK_ONLY ) {
16352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if( st->silk_mode.internalSampleRate == 8000 ) {
16362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               curr_bandwidth = OPUS_BANDWIDTH_NARROWBAND;
16372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            } else if( st->silk_mode.internalSampleRate == 12000 ) {
16382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               curr_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND;
16392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            } else if( st->silk_mode.internalSampleRate == 16000 ) {
16402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               curr_bandwidth = OPUS_BANDWIDTH_WIDEBAND;
16412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
16422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        } else {
16432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            silk_assert( st->silk_mode.internalSampleRate == 16000 );
16442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
16452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
16462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        st->silk_mode.opusCanSwitch = st->silk_mode.switchReady;
16472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        /* FIXME: How do we allocate the redundancy for CBR? */
16482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        if (st->silk_mode.opusCanSwitch)
16492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
16502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           redundancy = 1;
16512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           celt_to_silk = 0;
16522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           st->silk_bw_switch = 1;
16532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
16542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
16552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
16562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    /* CELT processing */
16572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    {
16582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        int endband=21;
16592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
16602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        switch(curr_bandwidth)
16612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
16622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            case OPUS_BANDWIDTH_NARROWBAND:
16632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                endband = 13;
16642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                break;
16652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            case OPUS_BANDWIDTH_MEDIUMBAND:
16662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            case OPUS_BANDWIDTH_WIDEBAND:
16672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                endband = 17;
16682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                break;
16692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            case OPUS_BANDWIDTH_SUPERWIDEBAND:
16702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                endband = 19;
16712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                break;
16722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            case OPUS_BANDWIDTH_FULLBAND:
16732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                endband = 21;
16742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                break;
16752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
16762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        celt_encoder_ctl(celt_enc, CELT_SET_END_BAND(endband));
16772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        celt_encoder_ctl(celt_enc, CELT_SET_CHANNELS(st->stream_channels));
16782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
16792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(OPUS_BITRATE_MAX));
16802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (st->mode != MODE_SILK_ONLY)
16812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    {
16822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        opus_val32 celt_pred=2;
16832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        celt_encoder_ctl(celt_enc, OPUS_SET_VBR(0));
16842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        /* We may still decide to disable prediction later */
16852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        if (st->silk_mode.reducedDependency)
16862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           celt_pred = 0;
16872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(celt_pred));
16882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
16892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        if (st->mode == MODE_HYBRID)
16902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
16912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            int len;
16922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
16932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            len = (ec_tell(&enc)+7)>>3;
16942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (redundancy)
16952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               len += st->mode == MODE_HYBRID ? 3 : 1;
16962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if( st->use_vbr ) {
16972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                nb_compr_bytes = len + bytes_target - (st->silk_mode.bitRate * frame_size) / (8 * st->Fs);
16982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            } else {
16992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                /* check if SILK used up too much */
17002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                nb_compr_bytes = len > bytes_target ? len : bytes_target;
17012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
17022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        } else {
17032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (st->use_vbr)
17042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
17052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                opus_int32 bonus=0;
17062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifndef DISABLE_FLOAT_API
17072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                if (st->variable_duration==OPUS_FRAMESIZE_VARIABLE && frame_size != st->Fs/50)
17082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                {
17092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                   bonus = (60*st->stream_channels+40)*(st->Fs/frame_size-50);
17102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                   if (analysis_info.valid)
17112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                      bonus = (opus_int32)(bonus*(1.f+.5f*analysis_info.tonality));
17122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                }
17132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
17142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                celt_encoder_ctl(celt_enc, OPUS_SET_VBR(1));
17152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                celt_encoder_ctl(celt_enc, OPUS_SET_VBR_CONSTRAINT(st->vbr_constraint));
17162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(st->bitrate_bps+bonus));
17172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                nb_compr_bytes = max_data_bytes-1-redundancy_bytes;
17182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            } else {
17192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                nb_compr_bytes = bytes_target;
17202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
17212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
17222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
17232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    } else {
17242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        nb_compr_bytes = 0;
17252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
17262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
17272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    ALLOC(tmp_prefill, st->channels*st->Fs/400, opus_val16);
17282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (st->mode != MODE_SILK_ONLY && st->mode != st->prev_mode && st->prev_mode > 0)
17292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    {
17302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       for (i=0;i<st->channels*st->Fs/400;i++)
17312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          tmp_prefill[i] = st->delay_buffer[(st->encoder_buffer-total_buffer-st->Fs/400)*st->channels + i];
17322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
17332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
17342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    for (i=0;i<st->channels*(st->encoder_buffer-(frame_size+total_buffer));i++)
17352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        st->delay_buffer[i] = st->delay_buffer[i+st->channels*frame_size];
17362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    for (;i<st->encoder_buffer*st->channels;i++)
17372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        st->delay_buffer[i] = pcm_buf[(frame_size+total_buffer-st->encoder_buffer)*st->channels+i];
17382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
17392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    /* gain_fade() and stereo_fade() need to be after the buffer copying
17402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       because we don't want any of this to affect the SILK part */
17412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if( st->prev_HB_gain < Q15ONE || HB_gain < Q15ONE ) {
17422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       gain_fade(pcm_buf, pcm_buf,
17432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian             st->prev_HB_gain, HB_gain, celt_mode->overlap, frame_size, st->channels, celt_mode->window, st->Fs);
17442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
17452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->prev_HB_gain = HB_gain;
17462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (st->mode != MODE_HYBRID || st->stream_channels==1)
17472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       st->silk_mode.stereoWidth_Q14 = IMIN((1<<14),2*IMAX(0,equiv_rate-30000));
17482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if( !st->energy_masking && st->channels == 2 ) {
17492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        /* Apply stereo width reduction (at low bitrates) */
17502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        if( st->hybrid_stereo_width_Q14 < (1 << 14) || st->silk_mode.stereoWidth_Q14 < (1 << 14) ) {
17512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_val16 g1, g2;
17522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            g1 = st->hybrid_stereo_width_Q14;
17532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            g2 = (opus_val16)(st->silk_mode.stereoWidth_Q14);
17542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifdef FIXED_POINT
17552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            g1 = g1==16384 ? Q15ONE : SHL16(g1,1);
17562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            g2 = g2==16384 ? Q15ONE : SHL16(g2,1);
17572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#else
17582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            g1 *= (1.f/16384);
17592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            g2 *= (1.f/16384);
17602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
17612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            stereo_fade(pcm_buf, pcm_buf, g1, g2, celt_mode->overlap,
17622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                  frame_size, st->channels, celt_mode->window, st->Fs);
17632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            st->hybrid_stereo_width_Q14 = st->silk_mode.stereoWidth_Q14;
17642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
17652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
17662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
17672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if ( st->mode != MODE_CELT_ONLY && ec_tell(&enc)+17+20*(st->mode == MODE_HYBRID) <= 8*(max_data_bytes-1))
17682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    {
17692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        /* For SILK mode, the redundancy is inferred from the length */
17702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        if (st->mode == MODE_HYBRID && (redundancy || ec_tell(&enc)+37 <= 8*nb_compr_bytes))
17712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           ec_enc_bit_logp(&enc, redundancy, 12);
17722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        if (redundancy)
17732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
17742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            int max_redundancy;
17752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            ec_enc_bit_logp(&enc, celt_to_silk, 1);
17762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (st->mode == MODE_HYBRID)
17772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               max_redundancy = (max_data_bytes-1)-nb_compr_bytes;
17782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            else
17792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               max_redundancy = (max_data_bytes-1)-((ec_tell(&enc)+7)>>3);
17802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            /* Target the same bit-rate for redundancy as for the rest,
17812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               up to a max of 257 bytes */
17822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            redundancy_bytes = IMIN(max_redundancy, st->bitrate_bps/1600);
17832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            redundancy_bytes = IMIN(257, IMAX(2, redundancy_bytes));
17842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (st->mode == MODE_HYBRID)
17852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                ec_enc_uint(&enc, redundancy_bytes-2, 256);
17862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
17872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    } else {
17882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        redundancy = 0;
17892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
17902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
17912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (!redundancy)
17922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    {
17932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       st->silk_bw_switch = 0;
17942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       redundancy_bytes = 0;
17952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
17962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (st->mode != MODE_CELT_ONLY)start_band=17;
17972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
17982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (st->mode == MODE_SILK_ONLY)
17992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    {
18002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        ret = (ec_tell(&enc)+7)>>3;
18012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        ec_enc_done(&enc);
18022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        nb_compr_bytes = ret;
18032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    } else {
18042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       nb_compr_bytes = IMIN((max_data_bytes-1)-redundancy_bytes, nb_compr_bytes);
18052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       ec_enc_shrink(&enc, nb_compr_bytes);
18062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
18072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
18082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifndef DISABLE_FLOAT_API
18092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (redundancy || st->mode != MODE_SILK_ONLY)
18102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       celt_encoder_ctl(celt_enc, CELT_SET_ANALYSIS(&analysis_info));
18112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
18122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
18132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    /* 5 ms redundant frame for CELT->SILK */
18142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (redundancy && celt_to_silk)
18152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    {
18162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        int err;
18172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0));
18182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        celt_encoder_ctl(celt_enc, OPUS_SET_VBR(0));
18192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        err = celt_encode_with_ec(celt_enc, pcm_buf, st->Fs/200, data+nb_compr_bytes, redundancy_bytes, NULL);
18202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        if (err < 0)
18212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
18222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           RESTORE_STACK;
18232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           return OPUS_INTERNAL_ERROR;
18242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
18252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        celt_encoder_ctl(celt_enc, OPUS_GET_FINAL_RANGE(&redundant_rng));
18262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        celt_encoder_ctl(celt_enc, OPUS_RESET_STATE);
18272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
18282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
18292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(start_band));
18302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
18312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (st->mode != MODE_SILK_ONLY)
18322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    {
18332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        if (st->mode != st->prev_mode && st->prev_mode > 0)
18342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
18352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           unsigned char dummy[2];
18362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           celt_encoder_ctl(celt_enc, OPUS_RESET_STATE);
18372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
18382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           /* Prefilling */
18392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           celt_encode_with_ec(celt_enc, tmp_prefill, st->Fs/400, dummy, 2, NULL);
18402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(0));
18412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
18422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        /* If false, we already busted the budget and we'll end up with a "PLC packet" */
18432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        if (ec_tell(&enc) <= 8*nb_compr_bytes)
18442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
18452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           ret = celt_encode_with_ec(celt_enc, pcm_buf, frame_size, NULL, nb_compr_bytes, &enc);
18462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           if (ret < 0)
18472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           {
18482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian              RESTORE_STACK;
18492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian              return OPUS_INTERNAL_ERROR;
18502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           }
18512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
18522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
18532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
18542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    /* 5 ms redundant frame for SILK->CELT */
18552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (redundancy && !celt_to_silk)
18562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    {
18572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        int err;
18582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        unsigned char dummy[2];
18592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        int N2, N4;
18602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        N2 = st->Fs/200;
18612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        N4 = st->Fs/400;
18622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
18632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        celt_encoder_ctl(celt_enc, OPUS_RESET_STATE);
18642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0));
18652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(0));
18662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
18672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        /* NOTE: We could speed this up slightly (at the expense of code size) by just adding a function that prefills the buffer */
18682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        celt_encode_with_ec(celt_enc, pcm_buf+st->channels*(frame_size-N2-N4), N4, dummy, 2, NULL);
18692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
18702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        err = celt_encode_with_ec(celt_enc, pcm_buf+st->channels*(frame_size-N2), N2, data+nb_compr_bytes, redundancy_bytes, NULL);
18712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        if (err < 0)
18722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
18732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           RESTORE_STACK;
18742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           return OPUS_INTERNAL_ERROR;
18752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
18762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        celt_encoder_ctl(celt_enc, OPUS_GET_FINAL_RANGE(&redundant_rng));
18772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
18782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
18792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
18802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
18812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    /* Signalling the mode in the first byte */
18822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    data--;
18832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    data[0] = gen_toc(st->mode, st->Fs/frame_size, curr_bandwidth, st->stream_channels);
18842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
18852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->rangeFinal = enc.rng ^ redundant_rng;
18862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
18872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (to_celt)
18882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        st->prev_mode = MODE_CELT_ONLY;
18892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    else
18902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        st->prev_mode = st->mode;
18912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->prev_channels = st->stream_channels;
18922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->prev_framesize = frame_size;
18932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
18942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    st->first = 0;
18952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
18962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    /* In the unlikely case that the SILK encoder busted its target, tell
18972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       the decoder to call the PLC */
18982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (ec_tell(&enc) > (max_data_bytes-1)*8)
18992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    {
19002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       if (max_data_bytes < 2)
19012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       {
19022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          RESTORE_STACK;
19032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          return OPUS_BUFFER_TOO_SMALL;
19042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       }
19052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       data[1] = 0;
19062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       ret = 1;
19072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       st->rangeFinal = 0;
19082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    } else if (st->mode==MODE_SILK_ONLY&&!redundancy)
19092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    {
19102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       /*When in LPC only mode it's perfectly
19112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         reasonable to strip off trailing zero bytes as
19122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         the required range decoder behavior is to
19132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         fill these in. This can't be done when the MDCT
19142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         modes are used because the decoder needs to know
19152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         the actual length for allocation purposes.*/
19162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       while(ret>2&&data[ret]==0)ret--;
19172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
19182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    /* Count ToC and redundancy */
19192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    ret += 1+redundancy_bytes;
19202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    if (!st->use_vbr)
19212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    {
19222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       if (opus_packet_pad(data, ret, max_data_bytes) != OPUS_OK)
19232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
19242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       {
19252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          RESTORE_STACK;
19262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian          return OPUS_INTERNAL_ERROR;
19272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       }
19282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian       ret = max_data_bytes;
19292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
19302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    RESTORE_STACK;
19312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    return ret;
19322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
19332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
19342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifdef FIXED_POINT
19352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
19362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifndef DISABLE_FLOAT_API
19372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianopus_int32 opus_encode_float(OpusEncoder *st, const float *pcm, int analysis_frame_size,
19382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      unsigned char *data, opus_int32 max_data_bytes)
19392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
19402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int i, ret;
19412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int frame_size;
19422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int delay_compensation;
19432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   VARDECL(opus_int16, in);
19442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   ALLOC_STACK;
19452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
19462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)
19472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      delay_compensation = 0;
19482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   else
19492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      delay_compensation = st->delay_compensation;
19502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   frame_size = compute_frame_size(pcm, analysis_frame_size,
19512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         st->variable_duration, st->channels, st->Fs, st->bitrate_bps,
19522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         delay_compensation, downmix_float, st->analysis.subframe_mem);
19532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
19542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   ALLOC(in, frame_size*st->channels, opus_int16);
19552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
19562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   for (i=0;i<frame_size*st->channels;i++)
19572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      in[i] = FLOAT2INT16(pcm[i]);
19582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   ret = opus_encode_native(st, in, frame_size, data, max_data_bytes, 16, pcm, analysis_frame_size, 0, -2, st->channels, downmix_float);
19592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   RESTORE_STACK;
19602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   return ret;
19612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
19622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
19632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
19642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianopus_int32 opus_encode(OpusEncoder *st, const opus_int16 *pcm, int analysis_frame_size,
19652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                unsigned char *data, opus_int32 out_data_bytes)
19662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
19672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int frame_size;
19682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int delay_compensation;
19692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)
19702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      delay_compensation = 0;
19712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   else
19722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      delay_compensation = st->delay_compensation;
19732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   frame_size = compute_frame_size(pcm, analysis_frame_size,
19742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         st->variable_duration, st->channels, st->Fs, st->bitrate_bps,
19752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         delay_compensation, downmix_int
19762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#ifndef DISABLE_FLOAT_API
19772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         , st->analysis.subframe_mem
19782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
19792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         );
19802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   return opus_encode_native(st, pcm, frame_size, data, out_data_bytes, 16, pcm, analysis_frame_size, 0, -2, st->channels, downmix_int);
19812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
19822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
19832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#else
19842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianopus_int32 opus_encode(OpusEncoder *st, const opus_int16 *pcm, int analysis_frame_size,
19852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      unsigned char *data, opus_int32 max_data_bytes)
19862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
19872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int i, ret;
19882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int frame_size;
19892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int delay_compensation;
19902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   VARDECL(float, in);
19912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   ALLOC_STACK;
19922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
19932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)
19942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      delay_compensation = 0;
19952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   else
19962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      delay_compensation = st->delay_compensation;
19972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   frame_size = compute_frame_size(pcm, analysis_frame_size,
19982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         st->variable_duration, st->channels, st->Fs, st->bitrate_bps,
19992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         delay_compensation, downmix_int, st->analysis.subframe_mem);
20002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
20012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   ALLOC(in, frame_size*st->channels, float);
20022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
20032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   for (i=0;i<frame_size*st->channels;i++)
20042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      in[i] = (1.0f/32768)*pcm[i];
20052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   ret = opus_encode_native(st, in, frame_size, data, max_data_bytes, 16, pcm, analysis_frame_size, 0, -2, st->channels, downmix_int);
20062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   RESTORE_STACK;
20072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   return ret;
20082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
20092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianopus_int32 opus_encode_float(OpusEncoder *st, const float *pcm, int analysis_frame_size,
20102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                      unsigned char *data, opus_int32 out_data_bytes)
20112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
20122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int frame_size;
20132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   int delay_compensation;
20142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY)
20152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      delay_compensation = 0;
20162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   else
20172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian      delay_compensation = st->delay_compensation;
20182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   frame_size = compute_frame_size(pcm, analysis_frame_size,
20192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         st->variable_duration, st->channels, st->Fs, st->bitrate_bps,
20202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian         delay_compensation, downmix_float, st->analysis.subframe_mem);
20212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian   return opus_encode_native(st, pcm, frame_size, data, out_data_bytes, 24,
20222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                             pcm, analysis_frame_size, 0, -2, st->channels, downmix_float);
20232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
20242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian#endif
20252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
20262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
20272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianint opus_encoder_ctl(OpusEncoder *st, int request, ...)
20282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
20292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    int ret;
20302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    CELTEncoder *celt_enc;
20312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    va_list ap;
20322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
20332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    ret = OPUS_OK;
20342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    va_start(ap, request);
20352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
20362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset);
20372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
20382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    switch (request)
20392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    {
20402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_SET_APPLICATION_REQUEST:
20412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
20422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_int32 value = va_arg(ap, opus_int32);
20432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (   (value != OPUS_APPLICATION_VOIP && value != OPUS_APPLICATION_AUDIO
20442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                 && value != OPUS_APPLICATION_RESTRICTED_LOWDELAY)
20452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               || (!st->first && st->application != value))
20462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
20472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               ret = OPUS_BAD_ARG;
20482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               break;
20492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
20502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            st->application = value;
20512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
20522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
20532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_GET_APPLICATION_REQUEST:
20542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
20552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_int32 *value = va_arg(ap, opus_int32*);
20562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (!value)
20572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
20582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               goto bad_arg;
20592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
20602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            *value = st->application;
20612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
20622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
20632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_SET_BITRATE_REQUEST:
20642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
20652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_int32 value = va_arg(ap, opus_int32);
20662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (value != OPUS_AUTO && value != OPUS_BITRATE_MAX)
20672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
20682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                if (value <= 0)
20692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                    goto bad_arg;
20702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                else if (value <= 500)
20712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                    value = 500;
20722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                else if (value > (opus_int32)300000*st->channels)
20732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                    value = (opus_int32)300000*st->channels;
20742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
20752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            st->user_bitrate_bps = value;
20762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
20772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
20782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_GET_BITRATE_REQUEST:
20792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
20802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_int32 *value = va_arg(ap, opus_int32*);
20812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (!value)
20822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
20832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               goto bad_arg;
20842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
20852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            *value = user_bitrate_to_bitrate(st, st->prev_framesize, 1276);
20862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
20872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
20882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_SET_FORCE_CHANNELS_REQUEST:
20892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
20902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_int32 value = va_arg(ap, opus_int32);
20912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if((value<1 || value>st->channels) && value != OPUS_AUTO)
20922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
20932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               goto bad_arg;
20942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
20952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            st->force_channels = value;
20962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
20972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
20982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_GET_FORCE_CHANNELS_REQUEST:
20992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
21002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_int32 *value = va_arg(ap, opus_int32*);
21012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (!value)
21022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
21032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               goto bad_arg;
21042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
21052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            *value = st->force_channels;
21062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
21072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
21082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_SET_MAX_BANDWIDTH_REQUEST:
21092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
21102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_int32 value = va_arg(ap, opus_int32);
21112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (value < OPUS_BANDWIDTH_NARROWBAND || value > OPUS_BANDWIDTH_FULLBAND)
21122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
21132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               goto bad_arg;
21142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
21152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            st->max_bandwidth = value;
21162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (st->max_bandwidth == OPUS_BANDWIDTH_NARROWBAND) {
21172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                st->silk_mode.maxInternalSampleRate = 8000;
21182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            } else if (st->max_bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) {
21192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                st->silk_mode.maxInternalSampleRate = 12000;
21202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            } else {
21212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                st->silk_mode.maxInternalSampleRate = 16000;
21222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
21232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
21242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
21252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_GET_MAX_BANDWIDTH_REQUEST:
21262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
21272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_int32 *value = va_arg(ap, opus_int32*);
21282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (!value)
21292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
21302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               goto bad_arg;
21312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
21322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            *value = st->max_bandwidth;
21332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
21342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
21352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_SET_BANDWIDTH_REQUEST:
21362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
21372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_int32 value = va_arg(ap, opus_int32);
21382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if ((value < OPUS_BANDWIDTH_NARROWBAND || value > OPUS_BANDWIDTH_FULLBAND) && value != OPUS_AUTO)
21392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
21402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               goto bad_arg;
21412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
21422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            st->user_bandwidth = value;
21432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (st->user_bandwidth == OPUS_BANDWIDTH_NARROWBAND) {
21442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                st->silk_mode.maxInternalSampleRate = 8000;
21452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            } else if (st->user_bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) {
21462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                st->silk_mode.maxInternalSampleRate = 12000;
21472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            } else {
21482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                st->silk_mode.maxInternalSampleRate = 16000;
21492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
21502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
21512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
21522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_GET_BANDWIDTH_REQUEST:
21532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
21542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_int32 *value = va_arg(ap, opus_int32*);
21552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (!value)
21562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
21572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               goto bad_arg;
21582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
21592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            *value = st->bandwidth;
21602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
21612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
21622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_SET_DTX_REQUEST:
21632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
21642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_int32 value = va_arg(ap, opus_int32);
21652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if(value<0 || value>1)
21662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
21672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               goto bad_arg;
21682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
21692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            st->silk_mode.useDTX = value;
21702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
21712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
21722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_GET_DTX_REQUEST:
21732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
21742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_int32 *value = va_arg(ap, opus_int32*);
21752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (!value)
21762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
21772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               goto bad_arg;
21782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
21792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            *value = st->silk_mode.useDTX;
21802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
21812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
21822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_SET_COMPLEXITY_REQUEST:
21832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
21842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_int32 value = va_arg(ap, opus_int32);
21852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if(value<0 || value>10)
21862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
21872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               goto bad_arg;
21882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
21892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            st->silk_mode.complexity = value;
21902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            celt_encoder_ctl(celt_enc, OPUS_SET_COMPLEXITY(value));
21912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
21922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
21932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_GET_COMPLEXITY_REQUEST:
21942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
21952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_int32 *value = va_arg(ap, opus_int32*);
21962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (!value)
21972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
21982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               goto bad_arg;
21992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
22002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            *value = st->silk_mode.complexity;
22012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
22022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
22032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_SET_INBAND_FEC_REQUEST:
22042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
22052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_int32 value = va_arg(ap, opus_int32);
22062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if(value<0 || value>1)
22072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
22082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               goto bad_arg;
22092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
22102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            st->silk_mode.useInBandFEC = value;
22112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
22122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
22132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_GET_INBAND_FEC_REQUEST:
22142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
22152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_int32 *value = va_arg(ap, opus_int32*);
22162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (!value)
22172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
22182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               goto bad_arg;
22192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
22202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            *value = st->silk_mode.useInBandFEC;
22212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
22222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
22232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_SET_PACKET_LOSS_PERC_REQUEST:
22242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
22252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_int32 value = va_arg(ap, opus_int32);
22262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (value < 0 || value > 100)
22272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
22282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               goto bad_arg;
22292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
22302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            st->silk_mode.packetLossPercentage = value;
22312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            celt_encoder_ctl(celt_enc, OPUS_SET_PACKET_LOSS_PERC(value));
22322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
22332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
22342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_GET_PACKET_LOSS_PERC_REQUEST:
22352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
22362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_int32 *value = va_arg(ap, opus_int32*);
22372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (!value)
22382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
22392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               goto bad_arg;
22402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
22412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            *value = st->silk_mode.packetLossPercentage;
22422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
22432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
22442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_SET_VBR_REQUEST:
22452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
22462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_int32 value = va_arg(ap, opus_int32);
22472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if(value<0 || value>1)
22482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
22492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               goto bad_arg;
22502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
22512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            st->use_vbr = value;
22522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            st->silk_mode.useCBR = 1-value;
22532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
22542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
22552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_GET_VBR_REQUEST:
22562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
22572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_int32 *value = va_arg(ap, opus_int32*);
22582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (!value)
22592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
22602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               goto bad_arg;
22612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
22622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            *value = st->use_vbr;
22632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
22642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
22652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_SET_VOICE_RATIO_REQUEST:
22662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
22672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_int32 value = va_arg(ap, opus_int32);
22682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (value<-1 || value>100)
22692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
22702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               goto bad_arg;
22712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
22722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            st->voice_ratio = value;
22732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
22742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
22752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_GET_VOICE_RATIO_REQUEST:
22762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
22772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_int32 *value = va_arg(ap, opus_int32*);
22782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (!value)
22792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
22802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               goto bad_arg;
22812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
22822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            *value = st->voice_ratio;
22832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
22842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
22852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_SET_VBR_CONSTRAINT_REQUEST:
22862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
22872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_int32 value = va_arg(ap, opus_int32);
22882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if(value<0 || value>1)
22892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
22902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               goto bad_arg;
22912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
22922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            st->vbr_constraint = value;
22932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
22942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
22952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_GET_VBR_CONSTRAINT_REQUEST:
22962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
22972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_int32 *value = va_arg(ap, opus_int32*);
22982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (!value)
22992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
23002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               goto bad_arg;
23012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
23022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            *value = st->vbr_constraint;
23032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
23042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
23052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_SET_SIGNAL_REQUEST:
23062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
23072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_int32 value = va_arg(ap, opus_int32);
23082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if(value!=OPUS_AUTO && value!=OPUS_SIGNAL_VOICE && value!=OPUS_SIGNAL_MUSIC)
23092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
23102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               goto bad_arg;
23112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
23122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            st->signal_type = value;
23132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
23142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
23152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_GET_SIGNAL_REQUEST:
23162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
23172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_int32 *value = va_arg(ap, opus_int32*);
23182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (!value)
23192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
23202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               goto bad_arg;
23212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
23222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            *value = st->signal_type;
23232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
23242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
23252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_GET_LOOKAHEAD_REQUEST:
23262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
23272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_int32 *value = va_arg(ap, opus_int32*);
23282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (!value)
23292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
23302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               goto bad_arg;
23312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
23322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            *value = st->Fs/400;
23332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (st->application != OPUS_APPLICATION_RESTRICTED_LOWDELAY)
23342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                *value += st->delay_compensation;
23352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
23362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
23372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_GET_SAMPLE_RATE_REQUEST:
23382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
23392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_int32 *value = va_arg(ap, opus_int32*);
23402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (!value)
23412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
23422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               goto bad_arg;
23432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
23442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            *value = st->Fs;
23452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
23462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
23472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_GET_FINAL_RANGE_REQUEST:
23482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
23492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_uint32 *value = va_arg(ap, opus_uint32*);
23502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (!value)
23512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
23522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               goto bad_arg;
23532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
23542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            *value = st->rangeFinal;
23552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
23562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
23572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_SET_LSB_DEPTH_REQUEST:
23582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
23592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_int32 value = va_arg(ap, opus_int32);
23602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (value<8 || value>24)
23612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
23622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               goto bad_arg;
23632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
23642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            st->lsb_depth=value;
23652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
23662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
23672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_GET_LSB_DEPTH_REQUEST:
23682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
23692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_int32 *value = va_arg(ap, opus_int32*);
23702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (!value)
23712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
23722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               goto bad_arg;
23732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
23742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            *value = st->lsb_depth;
23752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
23762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
23772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST:
23782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
23792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_int32 value = va_arg(ap, opus_int32);
23802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (value != OPUS_FRAMESIZE_ARG   && value != OPUS_FRAMESIZE_2_5_MS &&
23812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                value != OPUS_FRAMESIZE_5_MS  && value != OPUS_FRAMESIZE_10_MS  &&
23822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                value != OPUS_FRAMESIZE_20_MS && value != OPUS_FRAMESIZE_40_MS  &&
23832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                value != OPUS_FRAMESIZE_60_MS && value != OPUS_FRAMESIZE_VARIABLE)
23842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
23852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               goto bad_arg;
23862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
23872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            st->variable_duration = value;
23882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            celt_encoder_ctl(celt_enc, OPUS_SET_EXPERT_FRAME_DURATION(value));
23892bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
23902bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
23912bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_GET_EXPERT_FRAME_DURATION_REQUEST:
23922bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
23932bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_int32 *value = va_arg(ap, opus_int32*);
23942bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if (!value)
23952bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
23962bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               goto bad_arg;
23972bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
23982bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            *value = st->variable_duration;
23992bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
24002bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
24012bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_SET_PREDICTION_DISABLED_REQUEST:
24022bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
24032bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           opus_int32 value = va_arg(ap, opus_int32);
24042bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           if (value > 1 || value < 0)
24052bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian              goto bad_arg;
24062bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           st->silk_mode.reducedDependency = value;
24072bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
24082bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
24092bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_GET_PREDICTION_DISABLED_REQUEST:
24102bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
24112bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           opus_int32 *value = va_arg(ap, opus_int32*);
24122bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           if (!value)
24132bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian              goto bad_arg;
24142bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           *value = st->silk_mode.reducedDependency;
24152bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
24162bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
24172bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_RESET_STATE:
24182bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
24192bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           void *silk_enc;
24202bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           silk_EncControlStruct dummy;
24212bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           silk_enc = (char*)st+st->silk_enc_offset;
24222bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
24232bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           OPUS_CLEAR((char*)&st->OPUS_ENCODER_RESET_START,
24242bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                 sizeof(OpusEncoder)-
24252bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian                 ((char*)&st->OPUS_ENCODER_RESET_START - (char*)st));
24262bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
24272bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           celt_encoder_ctl(celt_enc, OPUS_RESET_STATE);
24282bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           silk_InitEncoder( silk_enc, st->arch, &dummy );
24292bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           st->stream_channels = st->channels;
24302bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           st->hybrid_stereo_width_Q14 = 1 << 14;
24312bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           st->prev_HB_gain = Q15ONE;
24322bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           st->first = 1;
24332bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           st->mode = MODE_HYBRID;
24342bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           st->bandwidth = OPUS_BANDWIDTH_FULLBAND;
24352bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           st->variable_HP_smth2_Q15 = silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 );
24362bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
24372bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
24382bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_SET_FORCE_MODE_REQUEST:
24392bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
24402bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_int32 value = va_arg(ap, opus_int32);
24412bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            if ((value < MODE_SILK_ONLY || value > MODE_CELT_ONLY) && value != OPUS_AUTO)
24422bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            {
24432bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian               goto bad_arg;
24442bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            }
24452bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            st->user_forced_mode = value;
24462bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
24472bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
24482bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_SET_LFE_REQUEST:
24492bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
24502bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_int32 value = va_arg(ap, opus_int32);
24512bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            st->lfe = value;
24522bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            ret = celt_encoder_ctl(celt_enc, OPUS_SET_LFE(value));
24532bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
24542bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
24552bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case OPUS_SET_ENERGY_MASK_REQUEST:
24562bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
24572bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            opus_val16 *value = va_arg(ap, opus_val16*);
24582bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            st->energy_masking = value;
24592bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            ret = celt_encoder_ctl(celt_enc, OPUS_SET_ENERGY_MASK(value));
24602bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
24612bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
24622bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
24632bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        case CELT_GET_MODE_REQUEST:
24642bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        {
24652bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           const CELTMode ** value = va_arg(ap, const CELTMode**);
24662bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           if (!value)
24672bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           {
24682bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian              goto bad_arg;
24692bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           }
24702bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian           ret = celt_encoder_ctl(celt_enc, CELT_GET_MODE(value));
24712bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        }
24722bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        break;
24732bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian        default:
24742bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            /* fprintf(stderr, "unknown opus_encoder_ctl() request: %d", request);*/
24752bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            ret = OPUS_UNIMPLEMENTED;
24762bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian            break;
24772bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    }
24782bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    va_end(ap);
24792bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    return ret;
24802bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianbad_arg:
24812bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    va_end(ap);
24822bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    return OPUS_BAD_ARG;
24832bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
24842bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian
24852bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanianvoid opus_encoder_destroy(OpusEncoder *st)
24862bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian{
24872bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian    opus_free(st);
24882bd8b54017b5320bc0c1df9bf86f4cdc9f8db242Vignesh Venkatasubramanian}
2489