b70d7a4a |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/**
* @file
* Opus SILK decoder
*/
#include <stdint.h>
#include "opus.h"
typedef struct SilkFrame {
int coded;
int log_gain;
int16_t nlsf[16];
float lpc[16];
float output [2 * SILK_HISTORY];
float lpc_history[2 * SILK_HISTORY];
int primarylag;
int prev_voiced;
} SilkFrame;
struct SilkContext {
AVCodecContext *avctx;
int output_channels;
int midonly;
int subframes;
int sflength;
int flength;
int nlsf_interp_factor;
enum OpusBandwidth bandwidth;
int wb;
SilkFrame frame[2];
float prev_stereo_weights[2];
float stereo_weights[2];
int prev_coded_channels;
};
static const uint16_t silk_model_stereo_s1[] = {
256, 7, 9, 10, 11, 12, 22, 46, 54, 55, 56, 59, 82, 174, 197, 200,
201, 202, 210, 234, 244, 245, 246, 247, 249, 256
};
static const uint16_t silk_model_stereo_s2[] = {256, 85, 171, 256};
static const uint16_t silk_model_stereo_s3[] = {256, 51, 102, 154, 205, 256};
static const uint16_t silk_model_mid_only[] = {256, 192, 256};
static const uint16_t silk_model_frame_type_inactive[] = {256, 26, 256};
static const uint16_t silk_model_frame_type_active[] = {256, 24, 98, 246, 256};
static const uint16_t silk_model_gain_highbits[3][9] = {
{256, 32, 144, 212, 241, 253, 254, 255, 256},
{256, 2, 19, 64, 124, 186, 233, 252, 256},
{256, 1, 4, 30, 101, 195, 245, 254, 256}
};
static const uint16_t silk_model_gain_lowbits[] = {256, 32, 64, 96, 128, 160, 192, 224, 256};
static const uint16_t silk_model_gain_delta[] = {
256, 6, 11, 22, 53, 185, 206, 214, 218, 221, 223, 225, 227, 228, 229, 230,
231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246,
247, 248, 249, 250, 251, 252, 253, 254, 255, 256
};
static const uint16_t silk_model_lsf_s1[2][2][33] = {
{
{ // NB or MB, unvoiced
256, 44, 78, 108, 127, 148, 160, 171, 174, 177, 179, 195, 197, 199, 200, 205,
207, 208, 211, 214, 215, 216, 218, 220, 222, 225, 226, 235, 244, 246, 253, 255, 256
}, { // NB or MB, voiced
256, 1, 11, 12, 20, 23, 31, 39, 53, 66, 80, 81, 95, 107, 120, 131,
142, 154, 165, 175, 185, 196, 204, 213, 221, 228, 236, 237, 238, 244, 245, 251, 256
}
}, {
{ // WB, unvoiced
256, 31, 52, 55, 72, 73, 81, 98, 102, 103, 121, 137, 141, 143, 146, 147,
157, 158, 161, 177, 188, 204, 206, 208, 211, 213, 224, 225, 229, 238, 246, 253, 256
}, { // WB, voiced
256, 1, 5, 21, 26, 44, 55, 60, 74, 89, 90, 93, 105, 118, 132, 146,
152, 166, 178, 180, 186, 187, 199, 211, 222, 232, 235, 245, 250, 251, 252, 253, 256
}
}
};
static const uint16_t silk_model_lsf_s2[32][10] = {
// NB, MB
{ 256, 1, 2, 3, 18, 242, 253, 254, 255, 256 },
{ 256, 1, 2, 4, 38, 221, 253, 254, 255, 256 },
{ 256, 1, 2, 6, 48, 197, 252, 254, 255, 256 },
{ 256, 1, 2, 10, 62, 185, 246, 254, 255, 256 },
{ 256, 1, 4, 20, 73, 174, 248, 254, 255, 256 },
{ 256, 1, 4, 21, 76, 166, 239, 254, 255, 256 },
{ 256, 1, 8, 32, 85, 159, 226, 252, 255, 256 },
{ 256, 1, 2, 20, 83, 161, 219, 249, 255, 256 },
// WB
{ 256, 1, 2, 3, 12, 244, 253, 254, 255, 256 },
{ 256, 1, 2, 4, 32, 218, 253, 254, 255, 256 },
{ 256, 1, 2, 5, 47, 199, 252, 254, 255, 256 },
{ 256, 1, 2, 12, 61, 187, 252, 254, 255, 256 },
{ 256, 1, 5, 24, 72, 172, 249, 254, 255, 256 },
{ 256, 1, 2, 16, 70, 170, 242, 254, 255, 256 },
{ 256, 1, 2, 17, 78, 165, 226, 251, 255, 256 },
{ 256, 1, 8, 29, 79, 156, 237, 254, 255, 256 }
};
static const uint16_t silk_model_lsf_s2_ext[] = { 256, 156, 216, 240, 249, 253, 255, 256 };
static const uint16_t silk_model_lsf_interpolation_offset[] = { 256, 13, 35, 64, 75, 256 };
static const uint16_t silk_model_pitch_highbits[] = {
256, 3, 6, 12, 23, 44, 74, 106, 125, 136, 146, 158, 171, 184, 196, 207,
216, 224, 231, 237, 241, 243, 245, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256
};
static const uint16_t silk_model_pitch_lowbits_nb[]= { 256, 64, 128, 192, 256 };
static const uint16_t silk_model_pitch_lowbits_mb[]= { 256, 43, 85, 128, 171, 213, 256 };
static const uint16_t silk_model_pitch_lowbits_wb[]= { 256, 32, 64, 96, 128, 160, 192, 224, 256 };
static const uint16_t silk_model_pitch_delta[] = {
256, 46, 48, 50, 53, 57, 63, 73, 88, 114, 152, 182, 204, 219, 229, 236,
242, 246, 250, 252, 254, 256
};
static const uint16_t silk_model_pitch_contour_nb10ms[] = { 256, 143, 193, 256 };
static const uint16_t silk_model_pitch_contour_nb20ms[] = {
256, 68, 80, 101, 118, 137, 159, 189, 213, 230, 246, 256
};
static const uint16_t silk_model_pitch_contour_mbwb10ms[] = {
256, 91, 137, 176, 195, 209, 221, 229, 236, 242, 247, 252, 256
};
static const uint16_t silk_model_pitch_contour_mbwb20ms[] = {
256, 33, 55, 73, 89, 104, 118, 132, 145, 158, 168, 177, 186, 194, 200, 206,
212, 217, 221, 225, 229, 232, 235, 238, 240, 242, 244, 246, 248, 250, 252, 253,
254, 255, 256
};
static const uint16_t silk_model_ltp_filter[] = { 256, 77, 157, 256 };
static const uint16_t silk_model_ltp_filter0_sel[] = {
256, 185, 200, 213, 226, 235, 244, 250, 256
};
static const uint16_t silk_model_ltp_filter1_sel[] = {
256, 57, 91, 112, 132, 147, 160, 172, 185, 195, 205, 214, 224, 233, 241, 248, 256
};
static const uint16_t silk_model_ltp_filter2_sel[] = {
256, 15, 31, 45, 57, 69, 81, 92, 103, 114, 124, 133, 142, 151, 160, 168,
176, 184, 192, 199, 206, 212, 218, 223, 227, 232, 236, 240, 244, 247, 251, 254, 256
};
static const uint16_t silk_model_ltp_scale_index[] = { 256, 128, 192, 256 };
static const uint16_t silk_model_lcg_seed[] = { 256, 64, 128, 192, 256 };
static const uint16_t silk_model_exc_rate[2][10] = {
{ 256, 15, 66, 78, 124, 169, 182, 215, 242, 256 }, // unvoiced
{ 256, 33, 63, 99, 116, 150, 199, 217, 238, 256 } // voiced
};
static const uint16_t silk_model_pulse_count[11][19] = {
{ 256, 131, 205, 230, 238, 241, 244, 245, 246,
247, 248, 249, 250, 251, 252, 253, 254, 255, 256 },
{ 256, 58, 151, 211, 234, 241, 244, 245, 246,
247, 248, 249, 250, 251, 252, 253, 254, 255, 256 },
{ 256, 43, 94, 140, 173, 197, 213, 224, 232,
238, 241, 244, 247, 249, 250, 251, 253, 254, 256 },
{ 256, 17, 69, 140, 197, 228, 240, 245, 246,
247, 248, 249, 250, 251, 252, 253, 254, 255, 256 },
{ 256, 6, 27, 68, 121, 170, 205, 226, 237,
243, 246, 248, 250, 251, 252, 253, 254, 255, 256 },
{ 256, 7, 21, 43, 71, 100, 128, 153, 173,
190, 203, 214, 223, 230, 235, 239, 243, 246, 256 },
{ 256, 2, 7, 21, 50, 92, 138, 179, 210,
229, 240, 246, 249, 251, 252, 253, 254, 255, 256 },
{ 256, 1, 3, 7, 17, 36, 65, 100, 137,
171, 199, 219, 233, 241, 246, 250, 252, 254, 256 },
{ 256, 1, 3, 5, 10, 19, 33, 53, 77,
104, 132, 158, 181, 201, 216, 227, 235, 241, 256 },
{ 256, 1, 2, 3, 9, 36, 94, 150, 189,
214, 228, 238, 244, 247, 250, 252, 253, 254, 256 },
{ 256, 2, 3, 9, 36, 94, 150, 189, 214,
228, 238, 244, 247, 250, 252, 253, 254, 256, 256 }
};
static const uint16_t silk_model_pulse_location[4][168] = {
{
256, 126, 256,
256, 56, 198, 256,
256, 25, 126, 230, 256,
256, 12, 72, 180, 244, 256,
256, 7, 42, 126, 213, 250, 256,
256, 4, 24, 83, 169, 232, 253, 256,
256, 3, 15, 53, 125, 200, 242, 254, 256,
256, 2, 10, 35, 89, 162, 221, 248, 255, 256,
256, 2, 7, 24, 63, 126, 191, 233, 251, 255, 256,
256, 1, 5, 17, 45, 94, 157, 211, 241, 252, 255, 256,
256, 1, 5, 13, 33, 70, 125, 182, 223, 245, 253, 255, 256,
256, 1, 4, 11, 26, 54, 98, 151, 199, 232, 248, 254, 255, 256,
256, 1, 3, 9, 21, 42, 77, 124, 172, 212, 237, 249, 254, 255, 256,
256, 1, 2, 6, 16, 33, 60, 97, 144, 187, 220, 241, 250, 254, 255, 256,
256, 1, 2, 3, 11, 25, 47, 80, 120, 163, 201, 229, 245, 253, 254, 255, 256,
256, 1, 2, 3, 4, 17, 35, 62, 98, 139, 180, 214, 238, 252, 253, 254, 255, 256
},{
256, 127, 256,
256, 53, 202, 256,
256, 22, 127, 233, 256,
256, 11, 72, 183, 246, 256,
256, 6, 41, 127, 215, 251, 256,
256, 4, 24, 83, 170, 232, 253, 256,
256, 3, 16, 56, 127, 200, 241, 254, 256,
256, 3, 12, 39, 92, 162, 218, 246, 255, 256,
256, 3, 11, 30, 67, 124, 185, 229, 249, 255, 256,
256, 3, 10, 25, 53, 97, 151, 200, 233, 250, 255, 256,
256, 1, 8, 21, 43, 77, 123, 171, 209, 237, 251, 255, 256,
256, 1, 2, 13, 35, 62, 97, 139, 186, 219, 244, 254, 255, 256,
256, 1, 2, 8, 22, 48, 85, 128, 171, 208, 234, 248, 254, 255, 256,
256, 1, 2, 6, 16, 36, 67, 107, 149, 189, 220, 240, 250, 254, 255, 256,
256, 1, 2, 5, 13, 29, 55, 90, 128, 166, 201, 227, 243, 251, 254, 255, 256,
256, 1, 2, 4, 10, 22, 43, 73, 109, 147, 183, 213, 234, 246, 252, 254, 255, 256
},{
256, 127, 256,
256, 49, 206, 256,
256, 20, 127, 236, 256,
256, 11, 71, 184, 246, 256,
256, 7, 43, 127, 214, 250, 256,
256, 6, 30, 87, 169, 229, 252, 256,
256, 5, 23, 62, 126, 194, 236, 252, 256,
256, 6, 20, 49, 96, 157, 209, 239, 253, 256,
256, 1, 16, 39, 74, 125, 175, 215, 245, 255, 256,
256, 1, 2, 23, 55, 97, 149, 195, 236, 254, 255, 256,
256, 1, 7, 23, 50, 86, 128, 170, 206, 233, 249, 255, 256,
256, 1, 6, 18, 39, 70, 108, 148, 186, 217, 238, 250, 255, 256,
256, 1, 4, 13, 30, 56, 90, 128, 166, 200, 226, 243, 252, 255, 256,
256, 1, 4, 11, 25, 47, 76, 110, 146, 180, 209, 231, 245, 252, 255, 256,
256, 1, 3, 8, 19, 37, 62, 93, 128, 163, 194, 219, 237, 248, 253, 255, 256,
256, 1, 2, 6, 15, 30, 51, 79, 111, 145, 177, 205, 226, 241, 250, 254, 255, 256
},{
256, 128, 256,
256, 42, 214, 256,
256, 21, 128, 235, 256,
256, 12, 72, 184, 245, 256,
256, 8, 42, 128, 214, 249, 256,
256, 8, 31, 86, 176, 231, 251, 256,
256, 5, 20, 58, 130, 202, 238, 253, 256,
256, 6, 18, 45, 97, 174, 221, 241, 251, 256,
256, 6, 25, 53, 88, 128, 168, 203, 231, 250, 256,
256, 4, 18, 40, 71, 108, 148, 185, 216, 238, 252, 256,
256, 3, 13, 31, 57, 90, 128, 166, 199, 225, 243, 253, 256,
256, 2, 10, 23, 44, 73, 109, 147, 183, 212, 233, 246, 254, 256,
256, 1, 6, 16, 33, 58, 90, 128, 166, 198, 223, 240, 250, 255, 256,
256, 1, 5, 12, 25, 46, 75, 110, 146, 181, 210, 231, 244, 251, 255, 256,
256, 1, 3, 8, 18, 35, 60, 92, 128, 164, 196, 221, 238, 248, 253, 255, 256,
256, 1, 3, 7, 14, 27, 48, 76, 110, 146, 180, 208, 229, 242, 249, 253, 255, 256
}
};
static const uint16_t silk_model_excitation_lsb[] = {256, 136, 256};
static const uint16_t silk_model_excitation_sign[3][2][7][3] = {
{ // Inactive
{ // Low offset
{256, 2, 256},
{256, 207, 256},
{256, 189, 256},
{256, 179, 256},
{256, 174, 256},
{256, 163, 256},
{256, 157, 256}
}, { // High offset
{256, 58, 256},
{256, 245, 256},
{256, 238, 256},
{256, 232, 256},
{256, 225, 256},
{256, 220, 256},
{256, 211, 256}
}
}, { // Unvoiced
{ // Low offset
{256, 1, 256},
{256, 210, 256},
{256, 190, 256},
{256, 178, 256},
{256, 169, 256},
{256, 162, 256},
{256, 152, 256}
}, { // High offset
{256, 48, 256},
{256, 242, 256},
{256, 235, 256},
{256, 224, 256},
{256, 214, 256},
{256, 205, 256},
{256, 190, 256}
}
}, { // Voiced
{ // Low offset
{256, 1, 256},
{256, 162, 256},
{256, 152, 256},
{256, 147, 256},
{256, 144, 256},
{256, 141, 256},
{256, 138, 256}
}, { // High offset
{256, 8, 256},
{256, 203, 256},
{256, 187, 256},
{256, 176, 256},
{256, 168, 256},
{256, 161, 256},
{256, 154, 256}
}
}
};
static const int16_t silk_stereo_weights[] = {
-13732, -10050, -8266, -7526, -6500, -5000, -2950, -820,
820, 2950, 5000, 6500, 7526, 8266, 10050, 13732
};
static const uint8_t silk_lsf_s2_model_sel_nbmb[32][10] = {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 3, 1, 2, 2, 1, 2, 1, 1, 1 },
{ 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
{ 1, 2, 2, 2, 2, 1, 2, 1, 1, 1 },
{ 2, 3, 3, 3, 3, 2, 2, 2, 2, 2 },
{ 0, 5, 3, 3, 2, 2, 2, 2, 1, 1 },
{ 0, 2, 2, 2, 2, 2, 2, 2, 2, 1 },
{ 2, 3, 6, 4, 4, 4, 5, 4, 5, 5 },
{ 2, 4, 5, 5, 4, 5, 4, 6, 4, 4 },
{ 2, 4, 4, 7, 4, 5, 4, 5, 5, 4 },
{ 4, 3, 3, 3, 2, 3, 2, 2, 2, 2 },
{ 1, 5, 5, 6, 4, 5, 4, 5, 5, 5 },
{ 2, 7, 4, 6, 5, 5, 5, 5, 5, 5 },
{ 2, 7, 5, 5, 5, 5, 5, 6, 5, 4 },
{ 3, 3, 5, 4, 4, 5, 4, 5, 4, 4 },
{ 2, 3, 3, 5, 5, 4, 4, 4, 4, 4 },
{ 2, 4, 4, 6, 4, 5, 4, 5, 5, 5 },
{ 2, 5, 4, 6, 5, 5, 5, 4, 5, 4 },
{ 2, 7, 4, 5, 4, 5, 4, 5, 5, 5 },
{ 2, 5, 4, 6, 7, 6, 5, 6, 5, 4 },
{ 3, 6, 7, 4, 6, 5, 5, 6, 4, 5 },
{ 2, 7, 6, 4, 4, 4, 5, 4, 5, 5 },
{ 4, 5, 5, 4, 6, 6, 5, 6, 5, 4 },
{ 2, 5, 5, 6, 5, 6, 4, 6, 4, 4 },
{ 4, 5, 5, 5, 3, 7, 4, 5, 5, 4 },
{ 2, 3, 4, 5, 5, 6, 4, 5, 5, 4 },
{ 2, 3, 2, 3, 3, 4, 2, 3, 3, 3 },
{ 1, 1, 2, 2, 2, 2, 2, 3, 2, 2 },
{ 4, 5, 5, 6, 6, 6, 5, 6, 4, 5 },
{ 3, 5, 5, 4, 4, 4, 4, 3, 3, 2 },
{ 2, 5, 3, 7, 5, 5, 4, 4, 5, 4 },
{ 4, 4, 5, 4, 5, 6, 5, 6, 5, 4 }
};
static const uint8_t silk_lsf_s2_model_sel_wb[32][16] = {
{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 },
{ 10, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 9, 9, 9, 8, 11 },
{ 10, 13, 13, 11, 15, 12, 12, 13, 10, 13, 12, 13, 13, 12, 11, 11 },
{ 8, 10, 9, 10, 10, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 9 },
{ 8, 14, 13, 12, 14, 12, 15, 13, 12, 12, 12, 13, 13, 12, 12, 11 },
{ 8, 11, 13, 13, 12, 11, 11, 13, 11, 11, 11, 11, 11, 11, 10, 12 },
{ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 },
{ 8, 10, 14, 11, 15, 10, 13, 11, 12, 13, 13, 12, 11, 11, 10, 11 },
{ 8, 14, 10, 14, 14, 12, 13, 12, 14, 13, 12, 12, 13, 11, 11, 11 },
{ 10, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 },
{ 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9 },
{ 10, 10, 11, 12, 13, 11, 11, 11, 11, 11, 11, 11, 10, 10, 9, 11 },
{ 10, 10, 11, 11, 12, 11, 11, 11, 11, 11, 11, 11, 11, 10, 9, 11 },
{ 11, 12, 12, 12, 14, 12, 12, 13, 11, 13, 12, 12, 13, 12, 11, 12 },
{ 8, 14, 12, 13, 12, 15, 13, 10, 14, 13, 15, 12, 12, 11, 13, 11 },
{ 8, 9, 8, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 9, 8 },
{ 9, 14, 13, 15, 13, 12, 13, 11, 12, 13, 12, 12, 12, 11, 11, 12 },
{ 9, 11, 11, 12, 12, 11, 11, 13, 10, 11, 11, 13, 13, 13, 11, 12 },
{ 10, 11, 11, 10, 10, 10, 11, 10, 9, 10, 9, 10, 9, 9, 9, 12 },
{ 8, 10, 11, 13, 11, 11, 10, 10, 10, 9, 9, 8, 8, 8, 8, 8 },
{ 11, 12, 11, 13, 11, 11, 10, 10, 9, 9, 9, 9, 9, 10, 10, 12 },
{ 10, 14, 11, 15, 15, 12, 13, 12, 13, 11, 13, 11, 11, 10, 11, 11 },
{ 10, 11, 13, 14, 14, 11, 13, 11, 12, 12, 11, 11, 11, 11, 10, 12 },
{ 9, 11, 11, 12, 12, 12, 12, 11, 13, 13, 13, 11, 9, 9, 9, 9 },
{ 10, 13, 11, 14, 14, 12, 15, 12, 12, 13, 11, 12, 12, 11, 11, 11 },
{ 8, 14, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 },
{ 8, 14, 14, 11, 13, 10, 13, 13, 11, 12, 12, 15, 15, 12, 12, 12 },
{ 11, 11, 15, 11, 13, 12, 11, 11, 11, 10, 10, 11, 11, 11, 10, 11 },
{ 8, 8, 9, 8, 8, 8, 10, 9, 10, 9, 9, 10, 10, 10, 9, 9 },
{ 8, 11, 10, 13, 11, 11, 10, 11, 10, 9, 8, 8, 9, 8, 8, 9 },
{ 11, 13, 13, 12, 15, 13, 11, 11, 10, 11, 10, 10, 9, 8, 9, 8 },
{ 10, 11, 13, 11, 12, 11, 11, 11, 10, 9, 10, 14, 12, 8, 8, 8 }
};
static const uint8_t silk_lsf_pred_weights_nbmb[2][9] = {
{179, 138, 140, 148, 151, 149, 153, 151, 163},
{116, 67, 82, 59, 92, 72, 100, 89, 92}
};
static const uint8_t silk_lsf_pred_weights_wb[2][15] = {
{175, 148, 160, 176, 178, 173, 174, 164, 177, 174, 196, 182, 198, 192, 182},
{ 68, 62, 66, 60, 72, 117, 85, 90, 118, 136, 151, 142, 160, 142, 155}
};
static const uint8_t silk_lsf_weight_sel_nbmb[32][9] = {
{ 0, 1, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 1, 1, 0, 0, 0, 0, 1, 0 },
{ 0, 1, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 1, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 0, 1, 1, 0, 0, 0, 1, 0 },
{ 0, 1, 1, 0, 0, 1, 1, 0, 0 },
{ 0, 0, 1, 1, 0, 1, 0, 1, 1 },
{ 0, 0, 1, 1, 0, 0, 1, 1, 1 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 1, 0, 1, 1, 1, 1, 1, 0 },
{ 0, 1, 0, 1, 1, 1, 1, 1, 0 },
{ 0, 1, 1, 1, 1, 1, 1, 1, 0 },
{ 1, 0, 1, 1, 0, 1, 1, 1, 1 },
{ 0, 1, 1, 1, 1, 1, 0, 1, 0 },
{ 0, 0, 1, 1, 0, 1, 0, 1, 0 },
{ 0, 0, 1, 1, 1, 0, 1, 1, 1 },
{ 0, 1, 1, 0, 0, 1, 1, 1, 0 },
{ 0, 0, 0, 1, 1, 1, 0, 1, 0 },
{ 0, 1, 1, 0, 0, 1, 0, 1, 0 },
{ 0, 1, 1, 0, 0, 0, 1, 1, 0 },
{ 0, 0, 0, 0, 0, 1, 1, 1, 1 },
{ 0, 0, 1, 1, 0, 0, 0, 1, 1 },
{ 0, 0, 0, 1, 0, 1, 1, 1, 1 },
{ 0, 1, 1, 1, 1, 1, 1, 1, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 0, 1, 1, 0, 1, 0 },
{ 1, 0, 0, 1, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 1, 1, 0, 1, 0, 1 },
{ 1, 0, 1, 1, 0, 1, 1, 1, 1 }
};
static const uint8_t silk_lsf_weight_sel_wb[32][15] = {
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
{ 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0 },
{ 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0 },
{ 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1 },
{ 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0 },
{ 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0 },
{ 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0 },
{ 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1 },
{ 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0 },
{ 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0 },
{ 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
{ 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0 },
{ 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 0, 0 },
{ 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0 },
{ 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1 },
{ 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 },
{ 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0 }
};
static const uint8_t silk_lsf_codebook_nbmb[32][10] = {
{ 12, 35, 60, 83, 108, 132, 157, 180, 206, 228 },
{ 15, 32, 55, 77, 101, 125, 151, 175, 201, 225 },
{ 19, 42, 66, 89, 114, 137, 162, 184, 209, 230 },
{ 12, 25, 50, 72, 97, 120, 147, 172, 200, 223 },
{ 26, 44, 69, 90, 114, 135, 159, 180, 205, 225 },
{ 13, 22, 53, 80, 106, 130, 156, 180, 205, 228 },
{ 15, 25, 44, 64, 90, 115, 142, 168, 196, 222 },
{ 19, 24, 62, 82, 100, 120, 145, 168, 190, 214 },
{ 22, 31, 50, 79, 103, 120, 151, 170, 203, 227 },
{ 21, 29, 45, 65, 106, 124, 150, 171, 196, 224 },
{ 30, 49, 75, 97, 121, 142, 165, 186, 209, 229 },
{ 19, 25, 52, 70, 93, 116, 143, 166, 192, 219 },
{ 26, 34, 62, 75, 97, 118, 145, 167, 194, 217 },
{ 25, 33, 56, 70, 91, 113, 143, 165, 196, 223 },
{ 21, 34, 51, 72, 97, 117, 145, 171, 196, 222 },
{ 20, 29, 50, 67, 90, 117, 144, 168, 197, 221 },
{ 22, 31, 48, 66, 95, 117, 146, 168, 196, 222 },
{ 24, 33, 51, 77, 116, 134, 158, 180, 200, 224 },
{ 21, 28, 70, 87, 106, 124, 149, 170, 194, 217 },
{ 26, 33, 53, 64, 83, 117, 152, 173, 204, 225 },
{ 27, 34, 65, 95, 108, 129, 155, 174, 210, 225 },
{ 20, 26, 72, 99, 113, 131, 154, 176, 200, 219 },
{ 34, 43, 61, 78, 93, 114, 155, 177, 205, 229 },
{ 23, 29, 54, 97, 124, 138, 163, 179, 209, 229 },
{ 30, 38, 56, 89, 118, 129, 158, 178, 200, 231 },
{ 21, 29, 49, 63, 85, 111, 142, 163, 193, 222 },
{ 27, 48, 77, 103, 133, 158, 179, 196, 215, 232 },
{ 29, 47, 74, 99, 124, 151, 176, 198, 220, 237 },
{ 33, 42, 61, 76, 93, 121, 155, 174, 207, 225 },
{ 29, 53, 87, 112, 136, 154, 170, 188, 208, 227 },
{ 24, 30, 52, 84, 131, 150, 166, 186, 203, 229 },
{ 37, 48, 64, 84, 104, 118, 156, 177, 201, 230 }
};
static const uint8_t silk_lsf_codebook_wb[32][16] = {
{ 7, 23, 38, 54, 69, 85, 100, 116, 131, 147, 162, 178, 193, 208, 223, 239 },
{ 13, 25, 41, 55, 69, 83, 98, 112, 127, 142, 157, 171, 187, 203, 220, 236 },
{ 15, 21, 34, 51, 61, 78, 92, 106, 126, 136, 152, 167, 185, 205, 225, 240 },
{ 10, 21, 36, 50, 63, 79, 95, 110, 126, 141, 157, 173, 189, 205, 221, 237 },
{ 17, 20, 37, 51, 59, 78, 89, 107, 123, 134, 150, 164, 184, 205, 224, 240 },
{ 10, 15, 32, 51, 67, 81, 96, 112, 129, 142, 158, 173, 189, 204, 220, 236 },
{ 8, 21, 37, 51, 65, 79, 98, 113, 126, 138, 155, 168, 179, 192, 209, 218 },
{ 12, 15, 34, 55, 63, 78, 87, 108, 118, 131, 148, 167, 185, 203, 219, 236 },
{ 16, 19, 32, 36, 56, 79, 91, 108, 118, 136, 154, 171, 186, 204, 220, 237 },
{ 11, 28, 43, 58, 74, 89, 105, 120, 135, 150, 165, 180, 196, 211, 226, 241 },
{ 6, 16, 33, 46, 60, 75, 92, 107, 123, 137, 156, 169, 185, 199, 214, 225 },
{ 11, 19, 30, 44, 57, 74, 89, 105, 121, 135, 152, 169, 186, 202, 218, 234 },
{ 12, 19, 29, 46, 57, 71, 88, 100, 120, 132, 148, 165, 182, 199, 216, 233 },
{ 17, 23, 35, 46, 56, 77, 92, 106, 123, 134, 152, 167, 185, 204, 222, 237 },
{ 14, 17, 45, 53, 63, 75, 89, 107, 115, 132, 151, 171, 188, 206, 221, 240 },
{ 9, 16, 29, 40, 56, 71, 88, 103, 119, 137, 154, 171, 189, 205, 222, 237 },
{ 16, 19, 36, 48, 57, 76, 87, 105, 118, 132, 150, 167, 185, 202, 218, 236 },
{ 12, 17, 29, 54, 71, 81, 94, 104, 126, 136, 149, 164, 182, 201, 221, 237 },
{ 15, 28, 47, 62, 79, 97, 115, 129, 142, 155, 168, 180, 194, 208, 223, 238 },
{ 8, 14, 30, 45, 62, 78, 94, 111, 127, 143, 159, 175, 192, 207, 223, 239 },
{ 17, 30, 49, 62, 79, 92, 107, 119, 132, 145, 160, 174, 190, 204, 220, 235 },
{ 14, 19, 36, 45, 61, 76, 91, 108, 121, 138, 154, 172, 189, 205, 222, 238 },
{ 12, 18, 31, 45, 60, 76, 91, 107, 123, 138, 154, 171, 187, 204, 221, 236 },
{ 13, 17, 31, 43, 53, 70, 83, 103, 114, 131, 149, 167, 185, 203, 220, 237 },
{ 17, 22, 35, 42, 58, 78, 93, 110, 125, 139, 155, 170, 188, 206, 224, 240 },
{ 8, 15, 34, 50, 67, 83, 99, 115, 131, 146, 162, 178, 193, 209, 224, 239 },
{ 13, 16, 41, 66, 73, 86, 95, 111, 128, 137, 150, 163, 183, 206, 225, 241 },
{ 17, 25, 37, 52, 63, 75, 92, 102, 119, 132, 144, 160, 175, 191, 212, 231 },
{ 19, 31, 49, 65, 83, 100, 117, 133, 147, 161, 174, 187, 200, 213, 227, 242 },
{ 18, 31, 52, 68, 88, 103, 117, 126, 138, 149, 163, 177, 192, 207, 223, 239 },
{ 16, 29, 47, 61, 76, 90, 106, 119, 133, 147, 161, 176, 193, 209, 224, 240 },
{ 15, 21, 35, 50, 61, 73, 86, 97, 110, 119, 129, 141, 175, 198, 218, 237 }
};
static const uint16_t silk_lsf_min_spacing_nbmb[] = {
250, 3, 6, 3, 3, 3, 4, 3, 3, 3, 461
};
static const uint16_t silk_lsf_min_spacing_wb[] = {
100, 3, 40, 3, 3, 3, 5, 14, 14, 10, 11, 3, 8, 9, 7, 3, 347
};
static const uint8_t silk_lsf_ordering_nbmb[] = {
0, 9, 6, 3, 4, 5, 8, 1, 2, 7
};
static const uint8_t silk_lsf_ordering_wb[] = {
0, 15, 8, 7, 4, 11, 12, 3, 2, 13, 10, 5, 6, 9, 14, 1
};
static const int16_t silk_cosine[] = { /* (0.12) */
4096, 4095, 4091, 4085,
4076, 4065, 4052, 4036,
4017, 3997, 3973, 3948,
3920, 3889, 3857, 3822,
3784, 3745, 3703, 3659,
3613, 3564, 3513, 3461,
3406, 3349, 3290, 3229,
3166, 3102, 3035, 2967,
2896, 2824, 2751, 2676,
2599, 2520, 2440, 2359,
2276, 2191, 2106, 2019,
1931, 1842, 1751, 1660,
1568, 1474, 1380, 1285,
1189, 1093, 995, 897,
799, 700, 601, 501,
401, 301, 201, 101,
0, -101, -201, -301,
-401, -501, -601, -700,
-799, -897, -995, -1093,
-1189, -1285, -1380, -1474,
-1568, -1660, -1751, -1842,
-1931, -2019, -2106, -2191,
-2276, -2359, -2440, -2520,
-2599, -2676, -2751, -2824,
-2896, -2967, -3035, -3102,
-3166, -3229, -3290, -3349,
-3406, -3461, -3513, -3564,
-3613, -3659, -3703, -3745,
-3784, -3822, -3857, -3889,
-3920, -3948, -3973, -3997,
-4017, -4036, -4052, -4065,
-4076, -4085, -4091, -4095,
-4096
};
static const uint16_t silk_pitch_scale[] = { 4, 6, 8};
static const uint16_t silk_pitch_min_lag[] = { 16, 24, 32};
static const uint16_t silk_pitch_max_lag[] = {144, 216, 288};
static const int8_t silk_pitch_offset_nb10ms[3][2] = {
{ 0, 0},
{ 1, 0},
{ 0, 1}
};
static const int8_t silk_pitch_offset_nb20ms[11][4] = {
{ 0, 0, 0, 0},
{ 2, 1, 0, -1},
{-1, 0, 1, 2},
{-1, 0, 0, 1},
{-1, 0, 0, 0},
{ 0, 0, 0, 1},
{ 0, 0, 1, 1},
{ 1, 1, 0, 0},
{ 1, 0, 0, 0},
{ 0, 0, 0, -1},
{ 1, 0, 0, -1}
};
static const int8_t silk_pitch_offset_mbwb10ms[12][2] = {
{ 0, 0},
{ 0, 1},
{ 1, 0},
{-1, 1},
{ 1, -1},
{-1, 2},
{ 2, -1},
{-2, 2},
{ 2, -2},
{-2, 3},
{ 3, -2},
{-3, 3}
};
static const int8_t silk_pitch_offset_mbwb20ms[34][4] = {
{ 0, 0, 0, 0},
{ 0, 0, 1, 1},
{ 1, 1, 0, 0},
{-1, 0, 0, 0},
{ 0, 0, 0, 1},
{ 1, 0, 0, 0},
{-1, 0, 0, 1},
{ 0, 0, 0, -1},
{-1, 0, 1, 2},
{ 1, 0, 0, -1},
{-2, -1, 1, 2},
{ 2, 1, 0, -1},
{-2, 0, 0, 2},
{-2, 0, 1, 3},
{ 2, 1, -1, -2},
{-3, -1, 1, 3},
{ 2, 0, 0, -2},
{ 3, 1, 0, -2},
{-3, -1, 2, 4},
{-4, -1, 1, 4},
{ 3, 1, -1, -3},
{-4, -1, 2, 5},
{ 4, 2, -1, -3},
{ 4, 1, -1, -4},
{-5, -1, 2, 6},
{ 5, 2, -1, -4},
{-6, -2, 2, 6},
{-5, -2, 2, 5},
{ 6, 2, -1, -5},
{-7, -2, 3, 8},
{ 6, 2, -2, -6},
{ 5, 2, -2, -5},
{ 8, 3, -2, -7},
{-9, -3, 3, 9}
};
static const int8_t silk_ltp_filter0_taps[8][5] = {
{ 4, 6, 24, 7, 5},
{ 0, 0, 2, 0, 0},
{ 12, 28, 41, 13, -4},
{ -9, 15, 42, 25, 14},
{ 1, -2, 62, 41, -9},
{-10, 37, 65, -4, 3},
{ -6, 4, 66, 7, -8},
{ 16, 14, 38, -3, 33}
};
static const int8_t silk_ltp_filter1_taps[16][5] = {
{ 13, 22, 39, 23, 12},
{ -1, 36, 64, 27, -6},
{ -7, 10, 55, 43, 17},
{ 1, 1, 8, 1, 1},
{ 6, -11, 74, 53, -9},
{-12, 55, 76, -12, 8},
{ -3, 3, 93, 27, -4},
{ 26, 39, 59, 3, -8},
{ 2, 0, 77, 11, 9},
{ -8, 22, 44, -6, 7},
{ 40, 9, 26, 3, 9},
{ -7, 20, 101, -7, 4},
{ 3, -8, 42, 26, 0},
{-15, 33, 68, 2, 23},
{ -2, 55, 46, -2, 15},
{ 3, -1, 21, 16, 41}
};
static const int8_t silk_ltp_filter2_taps[32][5] = {
{ -6, 27, 61, 39, 5},
{-11, 42, 88, 4, 1},
{ -2, 60, 65, 6, -4},
{ -1, -5, 73, 56, 1},
{ -9, 19, 94, 29, -9},
{ 0, 12, 99, 6, 4},
{ 8, -19, 102, 46, -13},
{ 3, 2, 13, 3, 2},
{ 9, -21, 84, 72, -18},
{-11, 46, 104, -22, 8},
{ 18, 38, 48, 23, 0},
{-16, 70, 83, -21, 11},
{ 5, -11, 117, 22, -8},
{ -6, 23, 117, -12, 3},
{ 3, -8, 95, 28, 4},
{-10, 15, 77, 60, -15},
{ -1, 4, 124, 2, -4},
{ 3, 38, 84, 24, -25},
{ 2, 13, 42, 13, 31},
{ 21, -4, 56, 46, -1},
{ -1, 35, 79, -13, 19},
{ -7, 65, 88, -9, -14},
{ 20, 4, 81, 49, -29},
{ 20, 0, 75, 3, -17},
{ 5, -9, 44, 92, -8},
{ 1, -3, 22, 69, 31},
{ -6, 95, 41, -12, 5},
{ 39, 67, 16, -4, 1},
{ 0, -6, 120, 55, -36},
{-13, 44, 122, 4, -24},
{ 81, 5, 11, 3, 7},
{ 2, 0, 9, 10, 88}
};
static const uint16_t silk_ltp_scale_factor[] = {15565, 12288, 8192};
static const uint8_t silk_shell_blocks[3][2] = {
{ 5, 10}, // NB
{ 8, 15}, // MB
{10, 20} // WB
};
static const uint8_t silk_quant_offset[2][2] = { /* (0.23) */
{25, 60}, // Inactive or Unvoiced
{ 8, 25} // Voiced
};
static const int silk_stereo_interp_len[3] = {
64, 96, 128
};
static inline void silk_stabilize_lsf(int16_t nlsf[16], int order, const uint16_t min_delta[17])
{
int pass, i;
for (pass = 0; pass < 20; pass++) {
int k, min_diff = 0;
for (i = 0; i < order+1; i++) {
int low = i != 0 ? nlsf[i-1] : 0;
int high = i != order ? nlsf[i] : 32768;
int diff = (high - low) - (min_delta[i]);
if (diff < min_diff) {
min_diff = diff;
k = i;
if (pass == 20)
break;
}
}
if (min_diff == 0) /* no issues; stabilized */
return;
/* wiggle one or two LSFs */
if (k == 0) {
/* repel away from lower bound */
nlsf[0] = min_delta[0];
} else if (k == order) {
/* repel away from higher bound */
nlsf[order-1] = 32768 - min_delta[order];
} else {
/* repel away from current position */
int min_center = 0, max_center = 32768, center_val;
/* lower extent */
for (i = 0; i < k; i++)
min_center += min_delta[i];
min_center += min_delta[k] >> 1;
/* upper extent */
for (i = order; i > k; i--)
max_center -= min_delta[k];
max_center -= min_delta[k] >> 1;
/* move apart */
center_val = nlsf[k - 1] + nlsf[k];
center_val = (center_val >> 1) + (center_val & 1); // rounded divide by 2
center_val = FFMIN(max_center, FFMAX(min_center, center_val));
nlsf[k - 1] = center_val - (min_delta[k] >> 1);
nlsf[k] = nlsf[k - 1] + min_delta[k];
}
}
/* resort to the fall-back method, the standard method for LSF stabilization */
/* sort; as the LSFs should be nearly sorted, use insertion sort */
for (i = 1; i < order; i++) {
int j, value = nlsf[i];
for (j = i - 1; j >= 0 && nlsf[j] > value; j--)
nlsf[j + 1] = nlsf[j];
nlsf[j + 1] = value;
}
/* push forwards to increase distance */
if (nlsf[0] < min_delta[0])
nlsf[0] = min_delta[0];
for (i = 1; i < order; i++)
if (nlsf[i] < nlsf[i - 1] + min_delta[i])
nlsf[i] = nlsf[i - 1] + min_delta[i];
/* push backwards to increase distance */
if (nlsf[order-1] > 32768 - min_delta[order])
nlsf[order-1] = 32768 - min_delta[order];
for (i = order-2; i >= 0; i--)
if (nlsf[i] > nlsf[i + 1] - min_delta[i+1])
nlsf[i] = nlsf[i + 1] - min_delta[i+1];
return;
}
static inline int silk_is_lpc_stable(const int16_t lpc[16], int order)
{
int k, j, DC_resp = 0;
int32_t lpc32[2][16]; // Q24
int totalinvgain = 1 << 30; // 1.0 in Q30
int32_t *row = lpc32[0], *prevrow;
/* initialize the first row for the Levinson recursion */
for (k = 0; k < order; k++) {
DC_resp += lpc[k];
row[k] = lpc[k] * 4096;
}
if (DC_resp >= 4096)
return 0;
/* check if prediction gain pushes any coefficients too far */
for (k = order - 1; 1; k--) {
int rc; // Q31; reflection coefficient
int gaindiv; // Q30; inverse of the gain (the divisor)
int gain; // gain for this reflection coefficient
int fbits; // fractional bits used for the gain
int error; // Q29; estimate of the error of our partial estimate of 1/gaindiv
if (FFABS(row[k]) > 16773022)
return 0;
rc = -(row[k] * 128);
gaindiv = (1 << 30) - MULH(rc, rc);
totalinvgain = MULH(totalinvgain, gaindiv) << 2;
if (k == 0)
return (totalinvgain >= 107374);
/* approximate 1.0/gaindiv */
fbits = opus_ilog(gaindiv);
gain = ((1 << 29) - 1) / (gaindiv >> (fbits + 1 - 16)); // Q<fbits-16>
error = (1 << 29) - MULL(gaindiv << (15 + 16 - fbits), gain, 16);
gain = ((gain << 16) + (error * gain >> 13));
/* switch to the next row of the LPC coefficients */
prevrow = row;
row = lpc32[k & 1];
for (j = 0; j < k; j++) {
int x = prevrow[j] - ROUND_MULL(prevrow[k - j - 1], rc, 31);
row[j] = ROUND_MULL(x, gain, fbits);
}
}
}
static void silk_lsp2poly(const int32_t lsp[16], int32_t pol[16], int half_order)
{
int i, j;
pol[0] = 65536; // 1.0 in Q16
pol[1] = -lsp[0];
for (i = 1; i < half_order; i++) {
pol[i + 1] = pol[i - 1] * 2 - ROUND_MULL(lsp[2 * i], pol[i], 16);
for (j = i; j > 1; j--)
pol[j] += pol[j - 2] - ROUND_MULL(lsp[2 * i], pol[j - 1], 16);
pol[1] -= lsp[2 * i];
}
}
static void silk_lsf2lpc(const int16_t nlsf[16], float lpcf[16], int order)
{
int i, k;
int32_t lsp[16]; // Q17; 2*cos(LSF)
int32_t p[9], q[9]; // Q16
int32_t lpc32[16]; // Q17
int16_t lpc[16]; // Q12
/* convert the LSFs to LSPs, i.e. 2*cos(LSF) */
for (k = 0; k < order; k++) {
int index = nlsf[k] >> 8;
int offset = nlsf[k] & 255;
int k2 = (order == 10) ? silk_lsf_ordering_nbmb[k] : silk_lsf_ordering_wb[k];
/* interpolate and round */
lsp[k2] = silk_cosine[index] * 256;
lsp[k2] += (silk_cosine[index + 1] - silk_cosine[index]) * offset;
lsp[k2] = (lsp[k2] + 4) >> 3;
}
silk_lsp2poly(lsp , p, order >> 1);
silk_lsp2poly(lsp + 1, q, order >> 1);
/* reconstruct A(z) */
for (k = 0; k < order>>1; k++) {
lpc32[k] = -p[k + 1] - p[k] - q[k + 1] + q[k];
lpc32[order-k-1] = -p[k + 1] - p[k] + q[k + 1] - q[k];
}
/* limit the range of the LPC coefficients to each fit within an int16_t */
for (i = 0; i < 10; i++) {
int j;
unsigned int maxabs = 0;
for (j = 0, k = 0; j < order; j++) {
unsigned int x = FFABS(lpc32[k]);
if (x > maxabs) {
maxabs = x; // Q17
k = j;
}
}
maxabs = (maxabs + 16) >> 5; // convert to Q12
if (maxabs > 32767) {
/* perform bandwidth expansion */
unsigned int chirp, chirp_base; // Q16
maxabs = FFMIN(maxabs, 163838); // anything above this overflows chirp's numerator
chirp_base = chirp = 65470 - ((maxabs - 32767) << 14) / ((maxabs * (k+1)) >> 2);
for (k = 0; k < order; k++) {
lpc32[k] = ROUND_MULL(lpc32[k], chirp, 16);
chirp = (chirp_base * chirp + 32768) >> 16;
}
} else break;
}
if (i == 10) {
/* time's up: just clamp */
for (k = 0; k < order; k++) {
int x = (lpc32[k] + 16) >> 5;
lpc[k] = av_clip_int16(x);
lpc32[k] = lpc[k] << 5; // shortcut mandated by the spec; drops lower 5 bits
}
} else {
for (k = 0; k < order; k++)
lpc[k] = (lpc32[k] + 16) >> 5;
}
/* if the prediction gain causes the LPC filter to become unstable,
apply further bandwidth expansion on the Q17 coefficients */
for (i = 1; i <= 16 && !silk_is_lpc_stable(lpc, order); i++) {
unsigned int chirp, chirp_base;
chirp_base = chirp = 65536 - (1 << i);
for (k = 0; k < order; k++) {
lpc32[k] = ROUND_MULL(lpc32[k], chirp, 16);
lpc[k] = (lpc32[k] + 16) >> 5;
chirp = (chirp_base * chirp + 32768) >> 16;
}
}
for (i = 0; i < order; i++)
lpcf[i] = lpc[i] / 4096.0f;
}
static inline void silk_decode_lpc(SilkContext *s, SilkFrame *frame,
OpusRangeCoder *rc,
float lpc_leadin[16], float lpc[16],
int *lpc_order, int *has_lpc_leadin, int voiced)
{
int i;
int order; // order of the LP polynomial; 10 for NB/MB and 16 for WB
int8_t lsf_i1, lsf_i2[16]; // stage-1 and stage-2 codebook indices
int16_t lsf_res[16]; // residual as a Q10 value
int16_t nlsf[16]; // Q15
*lpc_order = order = s->wb ? 16 : 10;
/* obtain LSF stage-1 and stage-2 indices */
lsf_i1 = opus_rc_getsymbol(rc, silk_model_lsf_s1[s->wb][voiced]);
for (i = 0; i < order; i++) {
int index = s->wb ? silk_lsf_s2_model_sel_wb [lsf_i1][i] :
silk_lsf_s2_model_sel_nbmb[lsf_i1][i];
lsf_i2[i] = opus_rc_getsymbol(rc, silk_model_lsf_s2[index]) - 4;
if (lsf_i2[i] == -4)
lsf_i2[i] -= opus_rc_getsymbol(rc, silk_model_lsf_s2_ext);
else if (lsf_i2[i] == 4)
lsf_i2[i] += opus_rc_getsymbol(rc, silk_model_lsf_s2_ext);
}
/* reverse the backwards-prediction step */
for (i = order - 1; i >= 0; i--) {
int qstep = s->wb ? 9830 : 11796;
lsf_res[i] = lsf_i2[i] * 1024;
if (lsf_i2[i] < 0) lsf_res[i] += 102;
else if (lsf_i2[i] > 0) lsf_res[i] -= 102;
lsf_res[i] = (lsf_res[i] * qstep) >> 16;
if (i + 1 < order) {
int weight = s->wb ? silk_lsf_pred_weights_wb [silk_lsf_weight_sel_wb [lsf_i1][i]][i] :
silk_lsf_pred_weights_nbmb[silk_lsf_weight_sel_nbmb[lsf_i1][i]][i];
lsf_res[i] += (lsf_res[i+1] * weight) >> 8;
}
}
/* reconstruct the NLSF coefficients from the supplied indices */
for (i = 0; i < order; i++) {
const uint8_t * codebook = s->wb ? silk_lsf_codebook_wb [lsf_i1] :
silk_lsf_codebook_nbmb[lsf_i1];
int cur, prev, next, weight_sq, weight, ipart, fpart, y, value;
/* find the weight of the residual */
/* TODO: precompute */
cur = codebook[i];
prev = i ? codebook[i - 1] : 0;
next = i + 1 < order ? codebook[i + 1] : 256;
weight_sq = (1024 / (cur - prev) + 1024 / (next - cur)) << 16;
/* approximate square-root with mandated fixed-point arithmetic */
ipart = opus_ilog(weight_sq);
fpart = (weight_sq >> (ipart-8)) & 127;
y = ((ipart & 1) ? 32768 : 46214) >> ((32 - ipart)>>1);
weight = y + ((213 * fpart * y) >> 16);
value = cur * 128 + (lsf_res[i] * 16384) / weight; |