mirror of
				https://github.com/nyanmisaka/ffmpeg-rockchip.git
				synced 2025-10-30 04:02:04 +08:00 
			
		
		
		
	 f61d44b74a
			
		
	
	f61d44b74a
	
	
	
		
			
			Due to this typo max_center can be too large, causing nlsf to be set to too large values, which in turn can cause nlsf[i - 1] + min_delta[i] to overflow to a negative value, which is not allowed for nlsf and can cause an out of bounds read in silk_lsf2lpc. Reviewed-by: Michael Niedermayer <michael@niedermayer.cc> Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
		
			
				
	
	
		
			1598 lines
		
	
	
		
			59 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1598 lines
		
	
	
		
			59 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * Copyright (c) 2012 Andrew D'Addesio
 | |
|  * Copyright (c) 2013-2014 Mozilla Corporation
 | |
|  *
 | |
|  * This file is part of FFmpeg.
 | |
|  *
 | |
|  * FFmpeg is free software; you can redistribute it and/or
 | |
|  * modify it under the terms of the GNU Lesser General Public
 | |
|  * License as published by the Free Software Foundation; either
 | |
|  * version 2.1 of the License, or (at your option) any later version.
 | |
|  *
 | |
|  * FFmpeg is distributed in the hope that it will be useful,
 | |
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | |
|  * Lesser General Public License for more details.
 | |
|  *
 | |
|  * You should have received a copy of the GNU Lesser General Public
 | |
|  * License along with FFmpeg; if not, write to the Free Software
 | |
|  * 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[i];
 | |
|             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;
 | |
|         nlsf[i] = av_clip_uintp2(value, 15);
 | |
|     }
 | |
| 
 | |
|     /* stabilize the NLSF coefficients */
 | |
|     silk_stabilize_lsf(nlsf, order, s->wb ? silk_lsf_min_spacing_wb :
 | |
|                                             silk_lsf_min_spacing_nbmb);
 | |
| 
 | |
|     /* produce an interpolation for the first 2 subframes, */
 | |
|     /* and then convert both sets of NLSFs to LPC coefficients */
 | |
|     *has_lpc_leadin = 0;
 | |
|     if (s->subframes == 4) {
 | |
|         int offset = opus_rc_getsymbol(rc, silk_model_lsf_interpolation_offset);
 | |
|         if (offset != 4 && frame->coded) {
 | |
|             *has_lpc_leadin = 1;
 | |
|             if (offset != 0) {
 | |
|                 int16_t nlsf_leadin[16];
 | |
|                 for (i = 0; i < order; i++)
 | |
|                     nlsf_leadin[i] = frame->nlsf[i] +
 | |
|                         ((nlsf[i] - frame->nlsf[i]) * offset >> 2);
 | |
|                 silk_lsf2lpc(nlsf_leadin, lpc_leadin, order);
 | |
|             } else  /* avoid re-computation for a (roughly) 1-in-4 occurrence */
 | |
|                 memcpy(lpc_leadin, frame->lpc, 16 * sizeof(float));
 | |
|         } else
 | |
|             offset = 4;
 | |
|         s->nlsf_interp_factor = offset;
 | |
| 
 | |
|         silk_lsf2lpc(nlsf, lpc, order);
 | |
|     } else {
 | |
|         s->nlsf_interp_factor = 4;
 | |
|         silk_lsf2lpc(nlsf, lpc, order);
 | |
|     }
 | |
| 
 | |
|     memcpy(frame->nlsf, nlsf, order * sizeof(nlsf[0]));
 | |
|     memcpy(frame->lpc,  lpc,  order * sizeof(lpc[0]));
 | |
| }
 | |
| 
 | |
| static inline void silk_count_children(OpusRangeCoder *rc, int model, int32_t total,
 | |
|                                        int32_t child[2])
 | |
| {
 | |
|     if (total != 0) {
 | |
|         child[0] = opus_rc_getsymbol(rc,
 | |
|                        silk_model_pulse_location[model] + (((total - 1 + 5) * (total - 1)) >> 1));
 | |
|         child[1] = total - child[0];
 | |
|     } else {
 | |
|         child[0] = 0;
 | |
|         child[1] = 0;
 | |
|     }
 | |
| }
 | |
| 
 | |
| static inline void silk_decode_excitation(SilkContext *s, OpusRangeCoder *rc,
 | |
|                                           float* excitationf,
 | |
|                                           int qoffset_high, int active, int voiced)
 | |
| {
 | |
|     int i;
 | |
|     uint32_t seed;
 | |
|     int shellblocks;
 | |
|     int ratelevel;
 | |
|     uint8_t pulsecount[20];     // total pulses in each shell block
 | |
|     uint8_t lsbcount[20] = {0}; // raw lsbits defined for each pulse in each shell block
 | |
|     int32_t excitation[320];    // Q23
 | |
| 
 | |
|     /* excitation parameters */
 | |
|     seed = opus_rc_getsymbol(rc, silk_model_lcg_seed);
 | |
|     shellblocks = silk_shell_blocks[s->bandwidth][s->subframes >> 2];
 | |
|     ratelevel = opus_rc_getsymbol(rc, silk_model_exc_rate[voiced]);
 | |
| 
 | |
|     for (i = 0; i < shellblocks; i++) {
 | |
|         pulsecount[i] = opus_rc_getsymbol(rc, silk_model_pulse_count[ratelevel]);
 | |
|         if (pulsecount[i] == 17) {
 | |
|             while (pulsecount[i] == 17 && ++lsbcount[i] != 10)
 | |
|                 pulsecount[i] = opus_rc_getsymbol(rc, silk_model_pulse_count[9]);
 | |
|             if (lsbcount[i] == 10)
 | |
|                 pulsecount[i] = opus_rc_getsymbol(rc, silk_model_pulse_count[10]);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /* decode pulse locations using PVQ */
 | |
|     for (i = 0; i < shellblocks; i++) {
 | |
|         if (pulsecount[i] != 0) {
 | |
|             int a, b, c, d;
 | |
|             int32_t * location = excitation + 16*i;
 | |
|             int32_t branch[4][2];
 | |
|             branch[0][0] = pulsecount[i];
 | |
| 
 | |
|             /* unrolled tail recursion */
 | |
|             for (a = 0; a < 1; a++) {
 | |
|                 silk_count_children(rc, 0, branch[0][a], branch[1]);
 | |
|                 for (b = 0; b < 2; b++) {
 | |
|                     silk_count_children(rc, 1, branch[1][b], branch[2]);
 | |
|                     for (c = 0; c < 2; c++) {
 | |
|                         silk_count_children(rc, 2, branch[2][c], branch[3]);
 | |
|                         for (d = 0; d < 2; d++) {
 | |
|                             silk_count_children(rc, 3, branch[3][d], location);
 | |
|                             location += 2;
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         } else
 | |
|             memset(excitation + 16*i, 0, 16*sizeof(int32_t));
 | |
|     }
 | |
| 
 | |
|     /* decode least significant bits */
 | |
|     for (i = 0; i < shellblocks << 4; i++) {
 | |
|         int bit;
 | |
|         for (bit = 0; bit < lsbcount[i >> 4]; bit++)
 | |
|             excitation[i] = (excitation[i] << 1) |
 | |
|                             opus_rc_getsymbol(rc, silk_model_excitation_lsb);
 | |
|     }
 | |
| 
 | |
|     /* decode signs */
 | |
|     for (i = 0; i < shellblocks << 4; i++) {
 | |
|         if (excitation[i] != 0) {
 | |
|             int sign = opus_rc_getsymbol(rc, silk_model_excitation_sign[active +
 | |
|                                          voiced][qoffset_high][FFMIN(pulsecount[i >> 4], 6)]);
 | |
|             if (sign == 0)
 | |
|                 excitation[i] *= -1;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /* assemble the excitation */
 | |
|     for (i = 0; i < shellblocks << 4; i++) {
 | |
|         int value = excitation[i];
 | |
|         excitation[i] = value * 256 | silk_quant_offset[voiced][qoffset_high];
 | |
|         if (value < 0)      excitation[i] += 20;
 | |
|         else if (value > 0) excitation[i] -= 20;
 | |
| 
 | |
|         /* invert samples pseudorandomly */
 | |
|         seed = 196314165 * seed + 907633515;
 | |
|         if (seed & 0x80000000)
 | |
|             excitation[i] *= -1;
 | |
|         seed += value;
 | |
| 
 | |
|         excitationf[i] = excitation[i] / 8388608.0f;
 | |
|     }
 | |
| }
 | |
| 
 | |
| /** Maximum residual history according to 4.2.7.6.1 */
 | |
| #define SILK_MAX_LAG  (288 + LTP_ORDER / 2)
 | |
| 
 | |
| /** Order of the LTP filter */
 | |
| #define LTP_ORDER 5
 | |
| 
 | |
| static void silk_decode_frame(SilkContext *s, OpusRangeCoder *rc,
 | |
|                               int frame_num, int channel, int coded_channels, int active, int active1)
 | |
| {
 | |
|     /* per frame */
 | |
|     int voiced;       // combines with active to indicate inactive, active, or active+voiced
 | |
|     int qoffset_high;
 | |
|     int order;                             // order of the LPC coefficients
 | |
|     float lpc_leadin[16], lpc_body[16], residual[SILK_MAX_LAG + SILK_HISTORY];
 | |
|     int has_lpc_leadin;
 | |
|     float ltpscale;
 | |
| 
 | |
|     /* per subframe */
 | |
|     struct {
 | |
|         float gain;
 | |
|         int pitchlag;
 | |
|         float ltptaps[5];
 | |
|     } sf[4];
 | |
| 
 | |
|     SilkFrame * const frame = s->frame + channel;
 | |
| 
 | |
|     int i;
 | |
| 
 | |
|     /* obtain stereo weights */
 | |
|     if (coded_channels == 2 && channel == 0) {
 | |
|         int n, wi[2], ws[2], w[2];
 | |
|         n     = opus_rc_getsymbol(rc, silk_model_stereo_s1);
 | |
|         wi[0] = opus_rc_getsymbol(rc, silk_model_stereo_s2) + 3 * (n / 5);
 | |
|         ws[0] = opus_rc_getsymbol(rc, silk_model_stereo_s3);
 | |
|         wi[1] = opus_rc_getsymbol(rc, silk_model_stereo_s2) + 3 * (n % 5);
 | |
|         ws[1] = opus_rc_getsymbol(rc, silk_model_stereo_s3);
 | |
| 
 | |
|         for (i = 0; i < 2; i++)
 | |
|             w[i] = silk_stereo_weights[wi[i]] +
 | |
|                    (((silk_stereo_weights[wi[i] + 1] - silk_stereo_weights[wi[i]]) * 6554) >> 16)
 | |
|                     * (ws[i]*2 + 1);
 | |
| 
 | |
|         s->stereo_weights[0] = (w[0] - w[1]) / 8192.0;
 | |
|         s->stereo_weights[1] = w[1]          / 8192.0;
 | |
| 
 | |
|         /* and read the mid-only flag */
 | |
|         s->midonly = active1 ? 0 : opus_rc_getsymbol(rc, silk_model_mid_only);
 | |
|     }
 | |
| 
 | |
|     /* obtain frame type */
 | |
|     if (!active) {
 | |
|         qoffset_high = opus_rc_getsymbol(rc, silk_model_frame_type_inactive);
 | |
|         voiced = 0;
 | |
|     } else {
 | |
|         int type = opus_rc_getsymbol(rc, silk_model_frame_type_active);
 | |
|         qoffset_high = type & 1;
 | |
|         voiced = type >> 1;
 | |
|     }
 | |
| 
 | |
|     /* obtain subframe quantization gains */
 | |
|     for (i = 0; i < s->subframes; i++) {
 | |
|         int log_gain;     //Q7
 | |
|         int ipart, fpart, lingain;
 | |
| 
 | |
|         if (i == 0 && (frame_num == 0 || !frame->coded)) {
 | |
|             /* gain is coded absolute */
 | |
|             int x = opus_rc_getsymbol(rc, silk_model_gain_highbits[active + voiced]);
 | |
|             log_gain = (x<<3) | opus_rc_getsymbol(rc, silk_model_gain_lowbits);
 | |
| 
 | |
|             if (frame->coded)
 | |
|                 log_gain = FFMAX(log_gain, frame->log_gain - 16);
 | |
|         } else {
 | |
|             /* gain is coded relative */
 | |
|             int delta_gain = opus_rc_getsymbol(rc, silk_model_gain_delta);
 | |
|             log_gain = av_clip_uintp2(FFMAX((delta_gain<<1) - 16,
 | |
|                                      frame->log_gain + delta_gain - 4), 6);
 | |
|         }
 | |
| 
 | |
|         frame->log_gain = log_gain;
 | |
| 
 | |
|         /* approximate 2**(x/128) with a Q7 (i.e. non-integer) input */
 | |
|         log_gain = (log_gain * 0x1D1C71 >> 16) + 2090;
 | |
|         ipart = log_gain >> 7;
 | |
|         fpart = log_gain & 127;
 | |
|         lingain = (1 << ipart) + ((-174 * fpart * (128-fpart) >>16) + fpart) * ((1<<ipart) >> 7);
 | |
|         sf[i].gain = lingain / 65536.0f;
 | |
|     }
 | |
| 
 | |
|     /* obtain LPC filter coefficients */
 | |
|     silk_decode_lpc(s, frame, rc, lpc_leadin, lpc_body, &order, &has_lpc_leadin, voiced);
 | |
| 
 | |
|     /* obtain pitch lags, if this is a voiced frame */
 | |
|     if (voiced) {
 | |
|         int lag_absolute = (!frame_num || !frame->prev_voiced);
 | |
|         int primarylag;         // primary pitch lag for the entire SILK frame
 | |
|         int ltpfilter;
 | |
|         const int8_t * offsets;
 | |
| 
 | |
|         if (!lag_absolute) {
 | |
|             int delta = opus_rc_getsymbol(rc, silk_model_pitch_delta);
 | |
|             if (delta)
 | |
|                 primarylag = frame->primarylag + delta - 9;
 | |
|             else
 | |
|                 lag_absolute = 1;
 | |
|         }
 | |
| 
 | |
|         if (lag_absolute) {
 | |
|             /* primary lag is coded absolute */
 | |
|             int highbits, lowbits;
 | |
|             const uint16_t *model[] = {
 | |
|                 silk_model_pitch_lowbits_nb, silk_model_pitch_lowbits_mb,
 | |
|                 silk_model_pitch_lowbits_wb
 | |
|             };
 | |
|             highbits = opus_rc_getsymbol(rc, silk_model_pitch_highbits);
 | |
|             lowbits  = opus_rc_getsymbol(rc, model[s->bandwidth]);
 | |
| 
 | |
|             primarylag = silk_pitch_min_lag[s->bandwidth] +
 | |
|                          highbits*silk_pitch_scale[s->bandwidth] + lowbits;
 | |
|         }
 | |
|         frame->primarylag = primarylag;
 | |
| 
 | |
|         if (s->subframes == 2)
 | |
|             offsets = (s->bandwidth == OPUS_BANDWIDTH_NARROWBAND)
 | |
|                      ? silk_pitch_offset_nb10ms[opus_rc_getsymbol(rc,
 | |
|                                                 silk_model_pitch_contour_nb10ms)]
 | |
|                      : silk_pitch_offset_mbwb10ms[opus_rc_getsymbol(rc,
 | |
|                                                 silk_model_pitch_contour_mbwb10ms)];
 | |
|         else
 | |
|             offsets = (s->bandwidth == OPUS_BANDWIDTH_NARROWBAND)
 | |
|                      ? silk_pitch_offset_nb20ms[opus_rc_getsymbol(rc,
 | |
|                                                 silk_model_pitch_contour_nb20ms)]
 | |
|                      : silk_pitch_offset_mbwb20ms[opus_rc_getsymbol(rc,
 | |
|                                                 silk_model_pitch_contour_mbwb20ms)];
 | |
| 
 | |
|         for (i = 0; i < s->subframes; i++)
 | |
|             sf[i].pitchlag = av_clip(primarylag + offsets[i],
 | |
|                                      silk_pitch_min_lag[s->bandwidth],
 | |
|                                      silk_pitch_max_lag[s->bandwidth]);
 | |
| 
 | |
|         /* obtain LTP filter coefficients */
 | |
|         ltpfilter = opus_rc_getsymbol(rc, silk_model_ltp_filter);
 | |
|         for (i = 0; i < s->subframes; i++) {
 | |
|             int index, j;
 | |
|             const uint16_t *filter_sel[] = {
 | |
|                 silk_model_ltp_filter0_sel, silk_model_ltp_filter1_sel,
 | |
|                 silk_model_ltp_filter2_sel
 | |
|             };
 | |
|             const int8_t (*filter_taps[])[5] = {
 | |
|                 silk_ltp_filter0_taps, silk_ltp_filter1_taps, silk_ltp_filter2_taps
 | |
|             };
 | |
|             index = opus_rc_getsymbol(rc, filter_sel[ltpfilter]);
 | |
|             for (j = 0; j < 5; j++)
 | |
|                 sf[i].ltptaps[j] = filter_taps[ltpfilter][index][j] / 128.0f;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /* obtain LTP scale factor */
 | |
|     if (voiced && frame_num == 0)
 | |
|         ltpscale = silk_ltp_scale_factor[opus_rc_getsymbol(rc,
 | |
|                                          silk_model_ltp_scale_index)] / 16384.0f;
 | |
|     else ltpscale = 15565.0f/16384.0f;
 | |
| 
 | |
|     /* generate the excitation signal for the entire frame */
 | |
|     silk_decode_excitation(s, rc, residual + SILK_MAX_LAG, qoffset_high,
 | |
|                            active, voiced);
 | |
| 
 | |
|     /* skip synthesising the side channel if we want mono-only */
 | |
|     if (s->output_channels == channel)
 | |
|         return;
 | |
| 
 | |
|     /* generate the output signal */
 | |
|     for (i = 0; i < s->subframes; i++) {
 | |
|         const float * lpc_coeff = (i < 2 && has_lpc_leadin) ? lpc_leadin : lpc_body;
 | |
|         float *dst    = frame->output      + SILK_HISTORY + i * s->sflength;
 | |
|         float *resptr = residual           + SILK_MAX_LAG + i * s->sflength;
 | |
|         float *lpc    = frame->lpc_history + SILK_HISTORY + i * s->sflength;
 | |
|         float sum;
 | |
|         int j, k;
 | |
| 
 | |
|         if (voiced) {
 | |
|             int out_end;
 | |
|             float scale;
 | |
| 
 | |
|             if (i < 2 || s->nlsf_interp_factor == 4) {
 | |
|                 out_end = -i * s->sflength;
 | |
|                 scale   = ltpscale;
 | |
|             } else {
 | |
|                 out_end = -(i - 2) * s->sflength;
 | |
|                 scale   = 1.0f;
 | |
|             }
 | |
| 
 | |
|             /* when the LPC coefficients change, a re-whitening filter is used */
 | |
|             /* to produce a residual that accounts for the change */
 | |
|             for (j = - sf[i].pitchlag - LTP_ORDER/2; j < out_end; j++) {
 | |
|                 sum = dst[j];
 | |
|                 for (k = 0; k < order; k++)
 | |
|                     sum -= lpc_coeff[k] * dst[j - k - 1];
 | |
|                 resptr[j] = av_clipf(sum, -1.0f, 1.0f) * scale / sf[i].gain;
 | |
|             }
 | |
| 
 | |
|             if (out_end) {
 | |
|                 float rescale = sf[i-1].gain / sf[i].gain;
 | |
|                 for (j = out_end; j < 0; j++)
 | |
|                     resptr[j] *= rescale;
 | |
|             }
 | |
| 
 | |
|             /* LTP synthesis */
 | |
|             for (j = 0; j < s->sflength; j++) {
 | |
|                 sum = resptr[j];
 | |
|                 for (k = 0; k < LTP_ORDER; k++)
 | |
|                     sum += sf[i].ltptaps[k] * resptr[j - sf[i].pitchlag + LTP_ORDER/2 - k];
 | |
|                 resptr[j] = sum;
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         /* LPC synthesis */
 | |
|         for (j = 0; j < s->sflength; j++) {
 | |
|             sum = resptr[j] * sf[i].gain;
 | |
|             for (k = 1; k <= order; k++)
 | |
|                 sum += lpc_coeff[k - 1] * lpc[j - k];
 | |
| 
 | |
|             lpc[j] = sum;
 | |
|             dst[j] = av_clipf(sum, -1.0f, 1.0f);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     frame->prev_voiced = voiced;
 | |
|     memmove(frame->lpc_history, frame->lpc_history + s->flength, SILK_HISTORY * sizeof(float));
 | |
|     memmove(frame->output,      frame->output      + s->flength, SILK_HISTORY * sizeof(float));
 | |
| 
 | |
|     frame->coded = 1;
 | |
| }
 | |
| 
 | |
| static void silk_unmix_ms(SilkContext *s, float *l, float *r)
 | |
| {
 | |
|     float *mid    = s->frame[0].output + SILK_HISTORY - s->flength;
 | |
|     float *side   = s->frame[1].output + SILK_HISTORY - s->flength;
 | |
|     float w0_prev = s->prev_stereo_weights[0];
 | |
|     float w1_prev = s->prev_stereo_weights[1];
 | |
|     float w0      = s->stereo_weights[0];
 | |
|     float w1      = s->stereo_weights[1];
 | |
|     int n1        = silk_stereo_interp_len[s->bandwidth];
 | |
|     int i;
 | |
| 
 | |
|     for (i = 0; i < n1; i++) {
 | |
|         float interp0 = w0_prev + i * (w0 - w0_prev) / n1;
 | |
|         float interp1 = w1_prev + i * (w1 - w1_prev) / n1;
 | |
|         float p0      = 0.25 * (mid[i - 2] + 2 * mid[i - 1] + mid[i]);
 | |
| 
 | |
|         l[i] = av_clipf((1 + interp1) * mid[i - 1] + side[i - 1] + interp0 * p0, -1.0, 1.0);
 | |
|         r[i] = av_clipf((1 - interp1) * mid[i - 1] - side[i - 1] - interp0 * p0, -1.0, 1.0);
 | |
|     }
 | |
| 
 | |
|     for (; i < s->flength; i++) {
 | |
|         float p0 = 0.25 * (mid[i - 2] + 2 * mid[i - 1] + mid[i]);
 | |
| 
 | |
|         l[i] = av_clipf((1 + w1) * mid[i - 1] + side[i - 1] + w0 * p0, -1.0, 1.0);
 | |
|         r[i] = av_clipf((1 - w1) * mid[i - 1] - side[i - 1] - w0 * p0, -1.0, 1.0);
 | |
|     }
 | |
| 
 | |
|     memcpy(s->prev_stereo_weights, s->stereo_weights, sizeof(s->stereo_weights));
 | |
| }
 | |
| 
 | |
| static void silk_flush_frame(SilkFrame *frame)
 | |
| {
 | |
|     if (!frame->coded)
 | |
|         return;
 | |
| 
 | |
|     memset(frame->output,      0, sizeof(frame->output));
 | |
|     memset(frame->lpc_history, 0, sizeof(frame->lpc_history));
 | |
| 
 | |
|     memset(frame->lpc,  0, sizeof(frame->lpc));
 | |
|     memset(frame->nlsf, 0, sizeof(frame->nlsf));
 | |
| 
 | |
|     frame->log_gain = 0;
 | |
| 
 | |
|     frame->primarylag  = 0;
 | |
|     frame->prev_voiced = 0;
 | |
|     frame->coded       = 0;
 | |
| }
 | |
| 
 | |
| int ff_silk_decode_superframe(SilkContext *s, OpusRangeCoder *rc,
 | |
|                               float *output[2],
 | |
|                               enum OpusBandwidth bandwidth,
 | |
|                               int coded_channels,
 | |
|                               int duration_ms)
 | |
| {
 | |
|     int active[2][6], redundancy[2];
 | |
|     int nb_frames, i, j;
 | |
| 
 | |
|     if (bandwidth > OPUS_BANDWIDTH_WIDEBAND ||
 | |
|         coded_channels > 2 || duration_ms > 60) {
 | |
|         av_log(s->avctx, AV_LOG_ERROR, "Invalid parameters passed "
 | |
|                "to the SILK decoder.\n");
 | |
|         return AVERROR(EINVAL);
 | |
|     }
 | |
| 
 | |
|     nb_frames = 1 + (duration_ms > 20) + (duration_ms > 40);
 | |
|     s->subframes = duration_ms / nb_frames / 5;         // 5ms subframes
 | |
|     s->sflength  = 20 * (bandwidth + 2);
 | |
|     s->flength   = s->sflength * s->subframes;
 | |
|     s->bandwidth = bandwidth;
 | |
|     s->wb        = bandwidth == OPUS_BANDWIDTH_WIDEBAND;
 | |
| 
 | |
|     /* make sure to flush the side channel when switching from mono to stereo */
 | |
|     if (coded_channels > s->prev_coded_channels)
 | |
|         silk_flush_frame(&s->frame[1]);
 | |
|     s->prev_coded_channels = coded_channels;
 | |
| 
 | |
|     /* read the LP-layer header bits */
 | |
|     for (i = 0; i < coded_channels; i++) {
 | |
|         for (j = 0; j < nb_frames; j++)
 | |
|             active[i][j] = opus_rc_p2model(rc, 1);
 | |
| 
 | |
|         redundancy[i] = opus_rc_p2model(rc, 1);
 | |
|         if (redundancy[i]) {
 | |
|             av_log(s->avctx, AV_LOG_ERROR, "LBRR frames present; this is unsupported\n");
 | |
|             return AVERROR_PATCHWELCOME;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     for (i = 0; i < nb_frames; i++) {
 | |
|         for (j = 0; j < coded_channels && !s->midonly; j++)
 | |
|             silk_decode_frame(s, rc, i, j, coded_channels, active[j][i], active[1][i]);
 | |
| 
 | |
|         /* reset the side channel if it is not coded */
 | |
|         if (s->midonly && s->frame[1].coded)
 | |
|             silk_flush_frame(&s->frame[1]);
 | |
| 
 | |
|         if (coded_channels == 1 || s->output_channels == 1) {
 | |
|             for (j = 0; j < s->output_channels; j++) {
 | |
|                 memcpy(output[j] + i * s->flength,
 | |
|                        s->frame[0].output + SILK_HISTORY - s->flength - 2,
 | |
|                        s->flength * sizeof(float));
 | |
|             }
 | |
|         } else {
 | |
|             silk_unmix_ms(s, output[0] + i * s->flength, output[1] + i * s->flength);
 | |
|         }
 | |
| 
 | |
|         s->midonly        = 0;
 | |
|     }
 | |
| 
 | |
|     return nb_frames * s->flength;
 | |
| }
 | |
| 
 | |
| void ff_silk_free(SilkContext **ps)
 | |
| {
 | |
|     av_freep(ps);
 | |
| }
 | |
| 
 | |
| void ff_silk_flush(SilkContext *s)
 | |
| {
 | |
|     silk_flush_frame(&s->frame[0]);
 | |
|     silk_flush_frame(&s->frame[1]);
 | |
| 
 | |
|     memset(s->prev_stereo_weights, 0, sizeof(s->prev_stereo_weights));
 | |
| }
 | |
| 
 | |
| int ff_silk_init(AVCodecContext *avctx, SilkContext **ps, int output_channels)
 | |
| {
 | |
|     SilkContext *s;
 | |
| 
 | |
|     if (output_channels != 1 && output_channels != 2) {
 | |
|         av_log(avctx, AV_LOG_ERROR, "Invalid number of output channels: %d\n",
 | |
|                output_channels);
 | |
|         return AVERROR(EINVAL);
 | |
|     }
 | |
| 
 | |
|     s = av_mallocz(sizeof(*s));
 | |
|     if (!s)
 | |
|         return AVERROR(ENOMEM);
 | |
| 
 | |
|     s->avctx           = avctx;
 | |
|     s->output_channels = output_channels;
 | |
| 
 | |
|     ff_silk_flush(s);
 | |
| 
 | |
|     *ps = s;
 | |
| 
 | |
|     return 0;
 | |
| }
 |