From 35064811c0ac104acddd7777e00bfd9e054c2db6 Mon Sep 17 00:00:00 2001 From: hairball Date: Sat, 8 Feb 2014 03:21:02 +0000 Subject: Upgrade opus 1.0.2 -> 1.1 --- src/opus-1.0.2/celt/_kiss_fft_guts.h | 175 -- src/opus-1.0.2/celt/arch.h | 209 -- src/opus-1.0.2/celt/bands.c | 1302 --------- src/opus-1.0.2/celt/bands.h | 95 - src/opus-1.0.2/celt/celt.c | 2906 -------------------- src/opus-1.0.2/celt/celt.h | 117 - src/opus-1.0.2/celt/celt_lpc.c | 188 -- src/opus-1.0.2/celt/celt_lpc.h | 53 - src/opus-1.0.2/celt/cwrs.c | 645 ----- src/opus-1.0.2/celt/cwrs.h | 48 - src/opus-1.0.2/celt/ecintrin.h | 87 - src/opus-1.0.2/celt/entcode.c | 93 - src/opus-1.0.2/celt/entcode.h | 116 - src/opus-1.0.2/celt/entdec.c | 245 -- src/opus-1.0.2/celt/entdec.h | 100 - src/opus-1.0.2/celt/entenc.c | 294 -- src/opus-1.0.2/celt/entenc.h | 110 - src/opus-1.0.2/celt/fixed_debug.h | 763 ----- src/opus-1.0.2/celt/fixed_generic.h | 129 - src/opus-1.0.2/celt/float_cast.h | 140 - src/opus-1.0.2/celt/kiss_fft.c | 722 ----- src/opus-1.0.2/celt/kiss_fft.h | 139 - src/opus-1.0.2/celt/laplace.c | 134 - src/opus-1.0.2/celt/laplace.h | 48 - src/opus-1.0.2/celt/mathops.c | 206 -- src/opus-1.0.2/celt/mathops.h | 237 -- src/opus-1.0.2/celt/mdct.c | 332 --- src/opus-1.0.2/celt/mdct.h | 70 - src/opus-1.0.2/celt/mfrngcod.h | 48 - src/opus-1.0.2/celt/modes.c | 430 --- src/opus-1.0.2/celt/modes.h | 83 - src/opus-1.0.2/celt/opus_custom_demo.c | 210 -- src/opus-1.0.2/celt/os_support.h | 89 - src/opus-1.0.2/celt/pitch.c | 410 --- src/opus-1.0.2/celt/pitch.h | 48 - src/opus-1.0.2/celt/quant_bands.c | 570 ---- src/opus-1.0.2/celt/quant_bands.h | 60 - src/opus-1.0.2/celt/rate.c | 638 ----- src/opus-1.0.2/celt/rate.h | 101 - src/opus-1.0.2/celt/stack_alloc.h | 149 - src/opus-1.0.2/celt/static_modes_fixed.h | 595 ---- src/opus-1.0.2/celt/static_modes_float.h | 599 ---- src/opus-1.0.2/celt/vq.c | 415 --- src/opus-1.0.2/celt/vq.h | 73 - src/opus-1.0.2/include/opus.h | 903 ------ src/opus-1.0.2/include/opus_custom.h | 329 --- src/opus-1.0.2/include/opus_defines.h | 655 ----- src/opus-1.0.2/include/opus_multistream.h | 632 ----- src/opus-1.0.2/include/opus_types.h | 159 -- src/opus-1.0.2/silk/A2NLSF.c | 252 -- src/opus-1.0.2/silk/API.h | 132 - src/opus-1.0.2/silk/CNG.c | 167 -- src/opus-1.0.2/silk/HP_variable_cutoff.c | 77 - src/opus-1.0.2/silk/Inlines.h | 188 -- src/opus-1.0.2/silk/LPC_analysis_filter.c | 85 - src/opus-1.0.2/silk/LPC_inv_pred_gain.c | 154 -- src/opus-1.0.2/silk/LP_variable_cutoff.c | 135 - src/opus-1.0.2/silk/MacroCount.h | 718 ----- src/opus-1.0.2/silk/MacroDebug.h | 952 ------- src/opus-1.0.2/silk/NLSF2A.c | 178 -- src/opus-1.0.2/silk/NLSF_VQ.c | 68 - src/opus-1.0.2/silk/NLSF_VQ_weights_laroia.c | 80 - src/opus-1.0.2/silk/NLSF_decode.c | 101 - src/opus-1.0.2/silk/NLSF_del_dec_quant.c | 207 -- src/opus-1.0.2/silk/NLSF_encode.c | 128 - src/opus-1.0.2/silk/NLSF_stabilize.c | 142 - src/opus-1.0.2/silk/NLSF_unpack.c | 55 - src/opus-1.0.2/silk/NSQ.c | 439 --- src/opus-1.0.2/silk/NSQ_del_dec.c | 705 ----- src/opus-1.0.2/silk/PLC.c | 423 --- src/opus-1.0.2/silk/PLC.h | 61 - src/opus-1.0.2/silk/SigProc_FIX.h | 589 ---- src/opus-1.0.2/silk/VAD.c | 330 --- src/opus-1.0.2/silk/VQ_WMat_EC.c | 111 - src/opus-1.0.2/silk/ana_filt_bank_1.c | 74 - src/opus-1.0.2/silk/biquad_alt.c | 78 - src/opus-1.0.2/silk/bwexpander.c | 51 - src/opus-1.0.2/silk/bwexpander_32.c | 50 - src/opus-1.0.2/silk/check_control_input.c | 106 - src/opus-1.0.2/silk/code_signs.c | 115 - src/opus-1.0.2/silk/control.h | 139 - src/opus-1.0.2/silk/control_SNR.c | 81 - src/opus-1.0.2/silk/control_audio_bandwidth.c | 123 - src/opus-1.0.2/silk/control_codec.c | 411 --- src/opus-1.0.2/silk/debug.c | 170 -- src/opus-1.0.2/silk/debug.h | 284 -- src/opus-1.0.2/silk/dec_API.c | 392 --- src/opus-1.0.2/silk/decode_core.c | 238 -- src/opus-1.0.2/silk/decode_frame.c | 128 - src/opus-1.0.2/silk/decode_indices.c | 151 - src/opus-1.0.2/silk/decode_parameters.c | 115 - src/opus-1.0.2/silk/decode_pitch.c | 77 - src/opus-1.0.2/silk/decode_pulses.c | 115 - src/opus-1.0.2/silk/decoder_set_fs.c | 108 - src/opus-1.0.2/silk/define.h | 235 -- src/opus-1.0.2/silk/enc_API.c | 538 ---- src/opus-1.0.2/silk/encode_indices.c | 181 -- src/opus-1.0.2/silk/encode_pulses.c | 199 -- src/opus-1.0.2/silk/errors.h | 98 - .../silk/fixed/LTP_analysis_filter_FIX.c | 85 - src/opus-1.0.2/silk/fixed/LTP_scale_ctrl_FIX.c | 53 - src/opus-1.0.2/silk/fixed/apply_sine_window_FIX.c | 101 - src/opus-1.0.2/silk/fixed/autocorr_FIX.c | 76 - src/opus-1.0.2/silk/fixed/burg_modified_FIX.c | 269 -- src/opus-1.0.2/silk/fixed/corrMatrix_FIX.c | 156 -- src/opus-1.0.2/silk/fixed/encode_frame_FIX.c | 372 --- src/opus-1.0.2/silk/fixed/find_LPC_FIX.c | 145 - src/opus-1.0.2/silk/fixed/find_LTP_FIX.c | 244 -- src/opus-1.0.2/silk/fixed/find_pitch_lags_FIX.c | 137 - src/opus-1.0.2/silk/fixed/find_pred_coefs_FIX.c | 136 - src/opus-1.0.2/silk/fixed/k2a_FIX.c | 53 - src/opus-1.0.2/silk/fixed/k2a_Q16_FIX.c | 53 - src/opus-1.0.2/silk/fixed/main_FIX.h | 254 -- .../silk/fixed/noise_shape_analysis_FIX.c | 440 --- .../silk/fixed/pitch_analysis_core_FIX.c | 745 ----- src/opus-1.0.2/silk/fixed/prefilter_FIX.c | 204 -- src/opus-1.0.2/silk/fixed/process_gains_FIX.c | 117 - .../silk/fixed/regularize_correlations_FIX.c | 47 - src/opus-1.0.2/silk/fixed/residual_energy16_FIX.c | 103 - src/opus-1.0.2/silk/fixed/residual_energy_FIX.c | 91 - src/opus-1.0.2/silk/fixed/schur64_FIX.c | 77 - src/opus-1.0.2/silk/fixed/schur_FIX.c | 92 - src/opus-1.0.2/silk/fixed/solve_LS_FIX.c | 245 -- src/opus-1.0.2/silk/fixed/structs_FIX.h | 133 - src/opus-1.0.2/silk/fixed/vector_ops_FIX.c | 127 - .../silk/fixed/warped_autocorrelation_FIX.c | 88 - .../silk/float/LPC_analysis_filter_FLP.c | 249 -- src/opus-1.0.2/silk/float/LPC_inv_pred_gain_FLP.c | 76 - .../silk/float/LTP_analysis_filter_FLP.c | 75 - src/opus-1.0.2/silk/float/LTP_scale_ctrl_FLP.c | 52 - src/opus-1.0.2/silk/float/SigProc_FLP.h | 203 -- src/opus-1.0.2/silk/float/apply_sine_window_FLP.c | 81 - src/opus-1.0.2/silk/float/autocorrelation_FLP.c | 52 - src/opus-1.0.2/silk/float/burg_modified_FLP.c | 186 -- src/opus-1.0.2/silk/float/bwexpander_FLP.c | 49 - src/opus-1.0.2/silk/float/corrMatrix_FLP.c | 93 - src/opus-1.0.2/silk/float/encode_frame_FLP.c | 372 --- src/opus-1.0.2/silk/float/energy_FLP.c | 60 - src/opus-1.0.2/silk/float/find_LPC_FLP.c | 104 - src/opus-1.0.2/silk/float/find_LTP_FLP.c | 132 - src/opus-1.0.2/silk/float/find_pitch_lags_FLP.c | 131 - src/opus-1.0.2/silk/float/find_pred_coefs_FLP.c | 116 - src/opus-1.0.2/silk/float/inner_product_FLP.c | 60 - src/opus-1.0.2/silk/float/k2a_FLP.c | 53 - src/opus-1.0.2/silk/float/levinsondurbin_FLP.c | 81 - src/opus-1.0.2/silk/float/main_FLP.h | 309 --- .../silk/float/noise_shape_analysis_FLP.c | 365 --- .../silk/float/pitch_analysis_core_FLP.c | 630 ----- src/opus-1.0.2/silk/float/prefilter_FLP.c | 206 -- src/opus-1.0.2/silk/float/process_gains_FLP.c | 103 - .../silk/float/regularize_correlations_FLP.c | 48 - src/opus-1.0.2/silk/float/residual_energy_FLP.c | 117 - src/opus-1.0.2/silk/float/scale_copy_vector_FLP.c | 57 - src/opus-1.0.2/silk/float/scale_vector_FLP.c | 56 - src/opus-1.0.2/silk/float/schur_FLP.c | 70 - src/opus-1.0.2/silk/float/solve_LS_FLP.c | 207 -- src/opus-1.0.2/silk/float/sort_FLP.c | 83 - src/opus-1.0.2/silk/float/structs_FLP.h | 131 - .../silk/float/warped_autocorrelation_FLP.c | 73 - src/opus-1.0.2/silk/float/wrappers_FLP.c | 200 -- src/opus-1.0.2/silk/gain_quant.c | 141 - src/opus-1.0.2/silk/init_decoder.c | 56 - src/opus-1.0.2/silk/init_encoder.c | 60 - src/opus-1.0.2/silk/inner_prod_aligned.c | 47 - src/opus-1.0.2/silk/interpolate.c | 51 - src/opus-1.0.2/silk/lin2log.c | 46 - src/opus-1.0.2/silk/log2lin.c | 56 - src/opus-1.0.2/silk/macros.h | 135 - src/opus-1.0.2/silk/main.h | 434 --- src/opus-1.0.2/silk/pitch_est_defines.h | 88 - src/opus-1.0.2/silk/pitch_est_tables.c | 99 - src/opus-1.0.2/silk/process_NLSFs.c | 105 - src/opus-1.0.2/silk/quant_LTP_gains.c | 107 - src/opus-1.0.2/silk/resampler.c | 215 -- src/opus-1.0.2/silk/resampler_down2.c | 74 - src/opus-1.0.2/silk/resampler_down2_3.c | 98 - src/opus-1.0.2/silk/resampler_private.h | 88 - src/opus-1.0.2/silk/resampler_private_AR2.c | 55 - src/opus-1.0.2/silk/resampler_private_IIR_FIR.c | 103 - src/opus-1.0.2/silk/resampler_private_down_FIR.c | 189 -- src/opus-1.0.2/silk/resampler_private_up2_HQ.c | 113 - src/opus-1.0.2/silk/resampler_rom.c | 96 - src/opus-1.0.2/silk/resampler_rom.h | 68 - src/opus-1.0.2/silk/resampler_structs.h | 57 - src/opus-1.0.2/silk/shell_coder.c | 151 - src/opus-1.0.2/silk/sigm_Q15.c | 76 - src/opus-1.0.2/silk/sort.c | 154 -- src/opus-1.0.2/silk/stereo_LR_to_MS.c | 219 -- src/opus-1.0.2/silk/stereo_MS_to_LR.c | 85 - src/opus-1.0.2/silk/stereo_decode_pred.c | 73 - src/opus-1.0.2/silk/stereo_encode_pred.c | 62 - src/opus-1.0.2/silk/stereo_find_predictor.c | 79 - src/opus-1.0.2/silk/stereo_quant_pred.c | 73 - src/opus-1.0.2/silk/structs.h | 324 --- src/opus-1.0.2/silk/sum_sqr_shift.c | 85 - src/opus-1.0.2/silk/table_LSF_cos.c | 70 - src/opus-1.0.2/silk/tables.h | 120 - src/opus-1.0.2/silk/tables_LTP.c | 272 -- src/opus-1.0.2/silk/tables_NLSF_CB_NB_MB.c | 159 -- src/opus-1.0.2/silk/tables_NLSF_CB_WB.c | 198 -- src/opus-1.0.2/silk/tables_gain.c | 63 - src/opus-1.0.2/silk/tables_other.c | 138 - src/opus-1.0.2/silk/tables_pitch_lag.c | 69 - src/opus-1.0.2/silk/tables_pulses_per_block.c | 264 -- src/opus-1.0.2/silk/tuning_parameters.h | 168 -- src/opus-1.0.2/silk/typedef.h | 77 - src/opus-1.0.2/src/opus.c | 47 - src/opus-1.0.2/src/opus_decoder.c | 1051 ------- src/opus-1.0.2/src/opus_encoder.c | 1617 ----------- src/opus-1.0.2/src/opus_multistream.c | 1027 ------- src/opus-1.0.2/src/opus_private.h | 85 - src/opus-1.0.2/src/repacketizer.c | 208 -- src/opus-1.1/celt/_kiss_fft_guts.h | 183 ++ src/opus-1.1/celt/arch.h | 214 ++ src/opus-1.1/celt/arm/arm2gnu.pl | 316 +++ src/opus-1.1/celt/arm/arm_celt_map.c | 49 + src/opus-1.1/celt/arm/armcpu.c | 174 ++ src/opus-1.1/celt/arm/armcpu.h | 71 + src/opus-1.1/celt/arm/armopts.s.in | 37 + src/opus-1.1/celt/arm/celt_pitch_xcorr_arm.s | 545 ++++ src/opus-1.1/celt/arm/fixed_armv4.h | 76 + src/opus-1.1/celt/arm/fixed_armv5e.h | 116 + src/opus-1.1/celt/arm/kiss_fft_armv4.h | 121 + src/opus-1.1/celt/arm/kiss_fft_armv5e.h | 118 + src/opus-1.1/celt/arm/pitch_arm.h | 57 + src/opus-1.1/celt/bands.c | 1518 ++++++++++ src/opus-1.1/celt/bands.h | 114 + src/opus-1.1/celt/celt.c | 223 ++ src/opus-1.1/celt/celt.h | 218 ++ src/opus-1.1/celt/celt_decoder.c | 1195 ++++++++ src/opus-1.1/celt/celt_encoder.c | 2353 ++++++++++++++++ src/opus-1.1/celt/celt_lpc.c | 309 +++ src/opus-1.1/celt/celt_lpc.h | 54 + src/opus-1.1/celt/cpu_support.h | 54 + src/opus-1.1/celt/cwrs.c | 697 +++++ src/opus-1.1/celt/cwrs.h | 48 + src/opus-1.1/celt/ecintrin.h | 87 + src/opus-1.1/celt/entcode.c | 93 + src/opus-1.1/celt/entcode.h | 117 + src/opus-1.1/celt/entdec.c | 245 ++ src/opus-1.1/celt/entdec.h | 100 + src/opus-1.1/celt/entenc.c | 294 ++ src/opus-1.1/celt/entenc.h | 110 + src/opus-1.1/celt/fixed_debug.h | 773 ++++++ src/opus-1.1/celt/fixed_generic.h | 134 + src/opus-1.1/celt/float_cast.h | 140 + src/opus-1.1/celt/kiss_fft.c | 719 +++++ src/opus-1.1/celt/kiss_fft.h | 139 + src/opus-1.1/celt/laplace.c | 134 + src/opus-1.1/celt/laplace.h | 48 + src/opus-1.1/celt/mathops.c | 208 ++ src/opus-1.1/celt/mathops.h | 258 ++ src/opus-1.1/celt/mdct.c | 311 +++ src/opus-1.1/celt/mdct.h | 70 + src/opus-1.1/celt/mfrngcod.h | 48 + src/opus-1.1/celt/modes.c | 438 +++ src/opus-1.1/celt/modes.h | 83 + src/opus-1.1/celt/opus_custom_demo.c | 210 ++ src/opus-1.1/celt/os_support.h | 92 + src/opus-1.1/celt/pitch.c | 537 ++++ src/opus-1.1/celt/pitch.h | 173 ++ src/opus-1.1/celt/quant_bands.c | 556 ++++ src/opus-1.1/celt/quant_bands.h | 66 + src/opus-1.1/celt/rate.c | 638 +++++ src/opus-1.1/celt/rate.h | 101 + src/opus-1.1/celt/stack_alloc.h | 178 ++ src/opus-1.1/celt/static_modes_fixed.h | 595 ++++ src/opus-1.1/celt/static_modes_float.h | 599 ++++ src/opus-1.1/celt/vq.c | 415 +++ src/opus-1.1/celt/vq.h | 70 + src/opus-1.1/celt/x86/pitch_sse.h | 156 ++ src/opus-1.1/include/opus.h | 978 +++++++ src/opus-1.1/include/opus_custom.h | 342 +++ src/opus-1.1/include/opus_defines.h | 726 +++++ src/opus-1.1/include/opus_multistream.h | 660 +++++ src/opus-1.1/include/opus_types.h | 159 ++ src/opus-1.1/silk/A2NLSF.c | 252 ++ src/opus-1.1/silk/API.h | 133 + src/opus-1.1/silk/CNG.c | 172 ++ src/opus-1.1/silk/HP_variable_cutoff.c | 77 + src/opus-1.1/silk/Inlines.h | 188 ++ src/opus-1.1/silk/LPC_analysis_filter.c | 106 + src/opus-1.1/silk/LPC_inv_pred_gain.c | 154 ++ src/opus-1.1/silk/LP_variable_cutoff.c | 135 + src/opus-1.1/silk/MacroCount.h | 718 +++++ src/opus-1.1/silk/MacroDebug.h | 952 +++++++ src/opus-1.1/silk/NLSF2A.c | 178 ++ src/opus-1.1/silk/NLSF_VQ.c | 68 + src/opus-1.1/silk/NLSF_VQ_weights_laroia.c | 80 + src/opus-1.1/silk/NLSF_decode.c | 101 + src/opus-1.1/silk/NLSF_del_dec_quant.c | 207 ++ src/opus-1.1/silk/NLSF_encode.c | 136 + src/opus-1.1/silk/NLSF_stabilize.c | 142 + src/opus-1.1/silk/NLSF_unpack.c | 55 + src/opus-1.1/silk/NSQ.c | 446 +++ src/opus-1.1/silk/NSQ_del_dec.c | 719 +++++ src/opus-1.1/silk/PLC.c | 423 +++ src/opus-1.1/silk/PLC.h | 61 + src/opus-1.1/silk/SigProc_FIX.h | 594 ++++ src/opus-1.1/silk/VAD.c | 357 +++ src/opus-1.1/silk/VQ_WMat_EC.c | 120 + src/opus-1.1/silk/ana_filt_bank_1.c | 74 + src/opus-1.1/silk/arm/SigProc_FIX_armv4.h | 47 + src/opus-1.1/silk/arm/SigProc_FIX_armv5e.h | 61 + src/opus-1.1/silk/arm/macros_armv4.h | 103 + src/opus-1.1/silk/arm/macros_armv5e.h | 213 ++ src/opus-1.1/silk/biquad_alt.c | 78 + src/opus-1.1/silk/bwexpander.c | 51 + src/opus-1.1/silk/bwexpander_32.c | 50 + src/opus-1.1/silk/check_control_input.c | 106 + src/opus-1.1/silk/code_signs.c | 115 + src/opus-1.1/silk/control.h | 142 + src/opus-1.1/silk/control_SNR.c | 81 + src/opus-1.1/silk/control_audio_bandwidth.c | 126 + src/opus-1.1/silk/control_codec.c | 422 +++ src/opus-1.1/silk/debug.c | 170 ++ src/opus-1.1/silk/debug.h | 279 ++ src/opus-1.1/silk/dec_API.c | 397 +++ src/opus-1.1/silk/decode_core.c | 238 ++ src/opus-1.1/silk/decode_frame.c | 128 + src/opus-1.1/silk/decode_indices.c | 151 + src/opus-1.1/silk/decode_parameters.c | 115 + src/opus-1.1/silk/decode_pitch.c | 77 + src/opus-1.1/silk/decode_pulses.c | 115 + src/opus-1.1/silk/decoder_set_fs.c | 108 + src/opus-1.1/silk/define.h | 235 ++ src/opus-1.1/silk/enc_API.c | 556 ++++ src/opus-1.1/silk/encode_indices.c | 181 ++ src/opus-1.1/silk/encode_pulses.c | 206 ++ src/opus-1.1/silk/errors.h | 98 + src/opus-1.1/silk/fixed/LTP_analysis_filter_FIX.c | 85 + src/opus-1.1/silk/fixed/LTP_scale_ctrl_FIX.c | 53 + src/opus-1.1/silk/fixed/apply_sine_window_FIX.c | 101 + src/opus-1.1/silk/fixed/autocorr_FIX.c | 48 + src/opus-1.1/silk/fixed/burg_modified_FIX.c | 279 ++ src/opus-1.1/silk/fixed/corrMatrix_FIX.c | 156 ++ src/opus-1.1/silk/fixed/encode_frame_FIX.c | 385 +++ src/opus-1.1/silk/fixed/find_LPC_FIX.c | 151 + src/opus-1.1/silk/fixed/find_LTP_FIX.c | 244 ++ src/opus-1.1/silk/fixed/find_pitch_lags_FIX.c | 145 + src/opus-1.1/silk/fixed/find_pred_coefs_FIX.c | 147 + src/opus-1.1/silk/fixed/k2a_FIX.c | 53 + src/opus-1.1/silk/fixed/k2a_Q16_FIX.c | 53 + src/opus-1.1/silk/fixed/main_FIX.h | 257 ++ src/opus-1.1/silk/fixed/noise_shape_analysis_FIX.c | 445 +++ src/opus-1.1/silk/fixed/pitch_analysis_core_FIX.c | 744 +++++ src/opus-1.1/silk/fixed/prefilter_FIX.c | 209 ++ src/opus-1.1/silk/fixed/process_gains_FIX.c | 117 + .../silk/fixed/regularize_correlations_FIX.c | 47 + src/opus-1.1/silk/fixed/residual_energy16_FIX.c | 103 + src/opus-1.1/silk/fixed/residual_energy_FIX.c | 97 + src/opus-1.1/silk/fixed/schur64_FIX.c | 92 + src/opus-1.1/silk/fixed/schur_FIX.c | 106 + src/opus-1.1/silk/fixed/solve_LS_FIX.c | 249 ++ src/opus-1.1/silk/fixed/structs_FIX.h | 133 + src/opus-1.1/silk/fixed/vector_ops_FIX.c | 96 + .../silk/fixed/warped_autocorrelation_FIX.c | 88 + src/opus-1.1/silk/float/LPC_analysis_filter_FLP.c | 249 ++ src/opus-1.1/silk/float/LPC_inv_pred_gain_FLP.c | 76 + src/opus-1.1/silk/float/LTP_analysis_filter_FLP.c | 75 + src/opus-1.1/silk/float/LTP_scale_ctrl_FLP.c | 52 + src/opus-1.1/silk/float/SigProc_FLP.h | 204 ++ src/opus-1.1/silk/float/apply_sine_window_FLP.c | 81 + src/opus-1.1/silk/float/autocorrelation_FLP.c | 52 + src/opus-1.1/silk/float/burg_modified_FLP.c | 186 ++ src/opus-1.1/silk/float/bwexpander_FLP.c | 49 + src/opus-1.1/silk/float/corrMatrix_FLP.c | 93 + src/opus-1.1/silk/float/encode_frame_FLP.c | 372 +++ src/opus-1.1/silk/float/energy_FLP.c | 60 + src/opus-1.1/silk/float/find_LPC_FLP.c | 104 + src/opus-1.1/silk/float/find_LTP_FLP.c | 132 + src/opus-1.1/silk/float/find_pitch_lags_FLP.c | 132 + src/opus-1.1/silk/float/find_pred_coefs_FLP.c | 117 + src/opus-1.1/silk/float/inner_product_FLP.c | 60 + src/opus-1.1/silk/float/k2a_FLP.c | 53 + src/opus-1.1/silk/float/levinsondurbin_FLP.c | 81 + src/opus-1.1/silk/float/main_FLP.h | 312 +++ src/opus-1.1/silk/float/noise_shape_analysis_FLP.c | 365 +++ src/opus-1.1/silk/float/pitch_analysis_core_FLP.c | 630 +++++ src/opus-1.1/silk/float/prefilter_FLP.c | 206 ++ src/opus-1.1/silk/float/process_gains_FLP.c | 103 + .../silk/float/regularize_correlations_FLP.c | 48 + src/opus-1.1/silk/float/residual_energy_FLP.c | 117 + src/opus-1.1/silk/float/scale_copy_vector_FLP.c | 57 + src/opus-1.1/silk/float/scale_vector_FLP.c | 56 + src/opus-1.1/silk/float/schur_FLP.c | 70 + src/opus-1.1/silk/float/solve_LS_FLP.c | 207 ++ src/opus-1.1/silk/float/sort_FLP.c | 83 + src/opus-1.1/silk/float/structs_FLP.h | 131 + .../silk/float/warped_autocorrelation_FLP.c | 73 + src/opus-1.1/silk/float/wrappers_FLP.c | 201 ++ src/opus-1.1/silk/gain_quant.c | 141 + src/opus-1.1/silk/init_decoder.c | 56 + src/opus-1.1/silk/init_encoder.c | 64 + src/opus-1.1/silk/inner_prod_aligned.c | 47 + src/opus-1.1/silk/interpolate.c | 51 + src/opus-1.1/silk/lin2log.c | 46 + src/opus-1.1/silk/log2lin.c | 58 + src/opus-1.1/silk/macros.h | 115 + src/opus-1.1/silk/main.h | 438 +++ src/opus-1.1/silk/pitch_est_defines.h | 88 + src/opus-1.1/silk/pitch_est_tables.c | 99 + src/opus-1.1/silk/process_NLSFs.c | 105 + src/opus-1.1/silk/quant_LTP_gains.c | 128 + src/opus-1.1/silk/resampler.c | 215 ++ src/opus-1.1/silk/resampler_down2.c | 74 + src/opus-1.1/silk/resampler_down2_3.c | 103 + src/opus-1.1/silk/resampler_private.h | 88 + src/opus-1.1/silk/resampler_private_AR2.c | 55 + src/opus-1.1/silk/resampler_private_IIR_FIR.c | 107 + src/opus-1.1/silk/resampler_private_down_FIR.c | 194 ++ src/opus-1.1/silk/resampler_private_up2_HQ.c | 113 + src/opus-1.1/silk/resampler_rom.c | 96 + src/opus-1.1/silk/resampler_rom.h | 68 + src/opus-1.1/silk/resampler_structs.h | 60 + src/opus-1.1/silk/shell_coder.c | 151 + src/opus-1.1/silk/sigm_Q15.c | 76 + src/opus-1.1/silk/sort.c | 154 ++ src/opus-1.1/silk/stereo_LR_to_MS.c | 229 ++ src/opus-1.1/silk/stereo_MS_to_LR.c | 85 + src/opus-1.1/silk/stereo_decode_pred.c | 73 + src/opus-1.1/silk/stereo_encode_pred.c | 62 + src/opus-1.1/silk/stereo_find_predictor.c | 79 + src/opus-1.1/silk/stereo_quant_pred.c | 73 + src/opus-1.1/silk/structs.h | 327 +++ src/opus-1.1/silk/sum_sqr_shift.c | 85 + src/opus-1.1/silk/table_LSF_cos.c | 70 + src/opus-1.1/silk/tables.h | 122 + src/opus-1.1/silk/tables_LTP.c | 296 ++ src/opus-1.1/silk/tables_NLSF_CB_NB_MB.c | 159 ++ src/opus-1.1/silk/tables_NLSF_CB_WB.c | 198 ++ src/opus-1.1/silk/tables_gain.c | 63 + src/opus-1.1/silk/tables_other.c | 138 + src/opus-1.1/silk/tables_pitch_lag.c | 69 + src/opus-1.1/silk/tables_pulses_per_block.c | 264 ++ src/opus-1.1/silk/tuning_parameters.h | 171 ++ src/opus-1.1/silk/typedef.h | 78 + src/opus-1.1/src/analysis.c | 645 +++++ src/opus-1.1/src/analysis.h | 90 + src/opus-1.1/src/mlp.c | 140 + src/opus-1.1/src/mlp.h | 41 + src/opus-1.1/src/mlp_data.c | 105 + src/opus-1.1/src/opus.c | 329 +++ src/opus-1.1/src/opus_decoder.c | 970 +++++++ src/opus-1.1/src/opus_encoder.c | 2488 +++++++++++++++++ src/opus-1.1/src/opus_multistream.c | 92 + src/opus-1.1/src/opus_multistream_decoder.c | 537 ++++ src/opus-1.1/src/opus_multistream_encoder.c | 1174 ++++++++ src/opus-1.1/src/opus_private.h | 129 + src/opus-1.1/src/repacketizer.c | 345 +++ src/opus-1.1/src/tansig_table.h | 45 + 451 files changed, 54288 insertions(+), 46751 deletions(-) delete mode 100644 src/opus-1.0.2/celt/_kiss_fft_guts.h delete mode 100644 src/opus-1.0.2/celt/arch.h delete mode 100644 src/opus-1.0.2/celt/bands.c delete mode 100644 src/opus-1.0.2/celt/bands.h delete mode 100644 src/opus-1.0.2/celt/celt.c delete mode 100644 src/opus-1.0.2/celt/celt.h delete mode 100644 src/opus-1.0.2/celt/celt_lpc.c delete mode 100644 src/opus-1.0.2/celt/celt_lpc.h delete mode 100644 src/opus-1.0.2/celt/cwrs.c delete mode 100644 src/opus-1.0.2/celt/cwrs.h delete mode 100644 src/opus-1.0.2/celt/ecintrin.h delete mode 100644 src/opus-1.0.2/celt/entcode.c delete mode 100644 src/opus-1.0.2/celt/entcode.h delete mode 100644 src/opus-1.0.2/celt/entdec.c delete mode 100644 src/opus-1.0.2/celt/entdec.h delete mode 100644 src/opus-1.0.2/celt/entenc.c delete mode 100644 src/opus-1.0.2/celt/entenc.h delete mode 100644 src/opus-1.0.2/celt/fixed_debug.h delete mode 100644 src/opus-1.0.2/celt/fixed_generic.h delete mode 100644 src/opus-1.0.2/celt/float_cast.h delete mode 100644 src/opus-1.0.2/celt/kiss_fft.c delete mode 100644 src/opus-1.0.2/celt/kiss_fft.h delete mode 100644 src/opus-1.0.2/celt/laplace.c delete mode 100644 src/opus-1.0.2/celt/laplace.h delete mode 100644 src/opus-1.0.2/celt/mathops.c delete mode 100644 src/opus-1.0.2/celt/mathops.h delete mode 100644 src/opus-1.0.2/celt/mdct.c delete mode 100644 src/opus-1.0.2/celt/mdct.h delete mode 100644 src/opus-1.0.2/celt/mfrngcod.h delete mode 100644 src/opus-1.0.2/celt/modes.c delete mode 100644 src/opus-1.0.2/celt/modes.h delete mode 100644 src/opus-1.0.2/celt/opus_custom_demo.c delete mode 100644 src/opus-1.0.2/celt/os_support.h delete mode 100644 src/opus-1.0.2/celt/pitch.c delete mode 100644 src/opus-1.0.2/celt/pitch.h delete mode 100644 src/opus-1.0.2/celt/quant_bands.c delete mode 100644 src/opus-1.0.2/celt/quant_bands.h delete mode 100644 src/opus-1.0.2/celt/rate.c delete mode 100644 src/opus-1.0.2/celt/rate.h delete mode 100644 src/opus-1.0.2/celt/stack_alloc.h delete mode 100644 src/opus-1.0.2/celt/static_modes_fixed.h delete mode 100644 src/opus-1.0.2/celt/static_modes_float.h delete mode 100644 src/opus-1.0.2/celt/vq.c delete mode 100644 src/opus-1.0.2/celt/vq.h delete mode 100644 src/opus-1.0.2/include/opus.h delete mode 100644 src/opus-1.0.2/include/opus_custom.h delete mode 100644 src/opus-1.0.2/include/opus_defines.h delete mode 100644 src/opus-1.0.2/include/opus_multistream.h delete mode 100644 src/opus-1.0.2/include/opus_types.h delete mode 100644 src/opus-1.0.2/silk/A2NLSF.c delete mode 100644 src/opus-1.0.2/silk/API.h delete mode 100644 src/opus-1.0.2/silk/CNG.c delete mode 100644 src/opus-1.0.2/silk/HP_variable_cutoff.c delete mode 100644 src/opus-1.0.2/silk/Inlines.h delete mode 100644 src/opus-1.0.2/silk/LPC_analysis_filter.c delete mode 100644 src/opus-1.0.2/silk/LPC_inv_pred_gain.c delete mode 100644 src/opus-1.0.2/silk/LP_variable_cutoff.c delete mode 100644 src/opus-1.0.2/silk/MacroCount.h delete mode 100644 src/opus-1.0.2/silk/MacroDebug.h delete mode 100644 src/opus-1.0.2/silk/NLSF2A.c delete mode 100644 src/opus-1.0.2/silk/NLSF_VQ.c delete mode 100644 src/opus-1.0.2/silk/NLSF_VQ_weights_laroia.c delete mode 100644 src/opus-1.0.2/silk/NLSF_decode.c delete mode 100644 src/opus-1.0.2/silk/NLSF_del_dec_quant.c delete mode 100644 src/opus-1.0.2/silk/NLSF_encode.c delete mode 100644 src/opus-1.0.2/silk/NLSF_stabilize.c delete mode 100644 src/opus-1.0.2/silk/NLSF_unpack.c delete mode 100644 src/opus-1.0.2/silk/NSQ.c delete mode 100644 src/opus-1.0.2/silk/NSQ_del_dec.c delete mode 100644 src/opus-1.0.2/silk/PLC.c delete mode 100644 src/opus-1.0.2/silk/PLC.h delete mode 100644 src/opus-1.0.2/silk/SigProc_FIX.h delete mode 100644 src/opus-1.0.2/silk/VAD.c delete mode 100644 src/opus-1.0.2/silk/VQ_WMat_EC.c delete mode 100644 src/opus-1.0.2/silk/ana_filt_bank_1.c delete mode 100644 src/opus-1.0.2/silk/biquad_alt.c delete mode 100644 src/opus-1.0.2/silk/bwexpander.c delete mode 100644 src/opus-1.0.2/silk/bwexpander_32.c delete mode 100644 src/opus-1.0.2/silk/check_control_input.c delete mode 100644 src/opus-1.0.2/silk/code_signs.c delete mode 100644 src/opus-1.0.2/silk/control.h delete mode 100644 src/opus-1.0.2/silk/control_SNR.c delete mode 100644 src/opus-1.0.2/silk/control_audio_bandwidth.c delete mode 100644 src/opus-1.0.2/silk/control_codec.c delete mode 100644 src/opus-1.0.2/silk/debug.c delete mode 100644 src/opus-1.0.2/silk/debug.h delete mode 100644 src/opus-1.0.2/silk/dec_API.c delete mode 100644 src/opus-1.0.2/silk/decode_core.c delete mode 100644 src/opus-1.0.2/silk/decode_frame.c delete mode 100644 src/opus-1.0.2/silk/decode_indices.c delete mode 100644 src/opus-1.0.2/silk/decode_parameters.c delete mode 100644 src/opus-1.0.2/silk/decode_pitch.c delete mode 100644 src/opus-1.0.2/silk/decode_pulses.c delete mode 100644 src/opus-1.0.2/silk/decoder_set_fs.c delete mode 100644 src/opus-1.0.2/silk/define.h delete mode 100644 src/opus-1.0.2/silk/enc_API.c delete mode 100644 src/opus-1.0.2/silk/encode_indices.c delete mode 100644 src/opus-1.0.2/silk/encode_pulses.c delete mode 100644 src/opus-1.0.2/silk/errors.h delete mode 100644 src/opus-1.0.2/silk/fixed/LTP_analysis_filter_FIX.c delete mode 100644 src/opus-1.0.2/silk/fixed/LTP_scale_ctrl_FIX.c delete mode 100644 src/opus-1.0.2/silk/fixed/apply_sine_window_FIX.c delete mode 100644 src/opus-1.0.2/silk/fixed/autocorr_FIX.c delete mode 100644 src/opus-1.0.2/silk/fixed/burg_modified_FIX.c delete mode 100644 src/opus-1.0.2/silk/fixed/corrMatrix_FIX.c delete mode 100644 src/opus-1.0.2/silk/fixed/encode_frame_FIX.c delete mode 100644 src/opus-1.0.2/silk/fixed/find_LPC_FIX.c delete mode 100644 src/opus-1.0.2/silk/fixed/find_LTP_FIX.c delete mode 100644 src/opus-1.0.2/silk/fixed/find_pitch_lags_FIX.c delete mode 100644 src/opus-1.0.2/silk/fixed/find_pred_coefs_FIX.c delete mode 100644 src/opus-1.0.2/silk/fixed/k2a_FIX.c delete mode 100644 src/opus-1.0.2/silk/fixed/k2a_Q16_FIX.c delete mode 100644 src/opus-1.0.2/silk/fixed/main_FIX.h delete mode 100644 src/opus-1.0.2/silk/fixed/noise_shape_analysis_FIX.c delete mode 100644 src/opus-1.0.2/silk/fixed/pitch_analysis_core_FIX.c delete mode 100644 src/opus-1.0.2/silk/fixed/prefilter_FIX.c delete mode 100644 src/opus-1.0.2/silk/fixed/process_gains_FIX.c delete mode 100644 src/opus-1.0.2/silk/fixed/regularize_correlations_FIX.c delete mode 100644 src/opus-1.0.2/silk/fixed/residual_energy16_FIX.c delete mode 100644 src/opus-1.0.2/silk/fixed/residual_energy_FIX.c delete mode 100644 src/opus-1.0.2/silk/fixed/schur64_FIX.c delete mode 100644 src/opus-1.0.2/silk/fixed/schur_FIX.c delete mode 100644 src/opus-1.0.2/silk/fixed/solve_LS_FIX.c delete mode 100644 src/opus-1.0.2/silk/fixed/structs_FIX.h delete mode 100644 src/opus-1.0.2/silk/fixed/vector_ops_FIX.c delete mode 100644 src/opus-1.0.2/silk/fixed/warped_autocorrelation_FIX.c delete mode 100644 src/opus-1.0.2/silk/float/LPC_analysis_filter_FLP.c delete mode 100644 src/opus-1.0.2/silk/float/LPC_inv_pred_gain_FLP.c delete mode 100644 src/opus-1.0.2/silk/float/LTP_analysis_filter_FLP.c delete mode 100644 src/opus-1.0.2/silk/float/LTP_scale_ctrl_FLP.c delete mode 100644 src/opus-1.0.2/silk/float/SigProc_FLP.h delete mode 100644 src/opus-1.0.2/silk/float/apply_sine_window_FLP.c delete mode 100644 src/opus-1.0.2/silk/float/autocorrelation_FLP.c delete mode 100644 src/opus-1.0.2/silk/float/burg_modified_FLP.c delete mode 100644 src/opus-1.0.2/silk/float/bwexpander_FLP.c delete mode 100644 src/opus-1.0.2/silk/float/corrMatrix_FLP.c delete mode 100644 src/opus-1.0.2/silk/float/encode_frame_FLP.c delete mode 100644 src/opus-1.0.2/silk/float/energy_FLP.c delete mode 100644 src/opus-1.0.2/silk/float/find_LPC_FLP.c delete mode 100644 src/opus-1.0.2/silk/float/find_LTP_FLP.c delete mode 100644 src/opus-1.0.2/silk/float/find_pitch_lags_FLP.c delete mode 100644 src/opus-1.0.2/silk/float/find_pred_coefs_FLP.c delete mode 100644 src/opus-1.0.2/silk/float/inner_product_FLP.c delete mode 100644 src/opus-1.0.2/silk/float/k2a_FLP.c delete mode 100644 src/opus-1.0.2/silk/float/levinsondurbin_FLP.c delete mode 100644 src/opus-1.0.2/silk/float/main_FLP.h delete mode 100644 src/opus-1.0.2/silk/float/noise_shape_analysis_FLP.c delete mode 100644 src/opus-1.0.2/silk/float/pitch_analysis_core_FLP.c delete mode 100644 src/opus-1.0.2/silk/float/prefilter_FLP.c delete mode 100644 src/opus-1.0.2/silk/float/process_gains_FLP.c delete mode 100644 src/opus-1.0.2/silk/float/regularize_correlations_FLP.c delete mode 100644 src/opus-1.0.2/silk/float/residual_energy_FLP.c delete mode 100644 src/opus-1.0.2/silk/float/scale_copy_vector_FLP.c delete mode 100644 src/opus-1.0.2/silk/float/scale_vector_FLP.c delete mode 100644 src/opus-1.0.2/silk/float/schur_FLP.c delete mode 100644 src/opus-1.0.2/silk/float/solve_LS_FLP.c delete mode 100644 src/opus-1.0.2/silk/float/sort_FLP.c delete mode 100644 src/opus-1.0.2/silk/float/structs_FLP.h delete mode 100644 src/opus-1.0.2/silk/float/warped_autocorrelation_FLP.c delete mode 100644 src/opus-1.0.2/silk/float/wrappers_FLP.c delete mode 100644 src/opus-1.0.2/silk/gain_quant.c delete mode 100644 src/opus-1.0.2/silk/init_decoder.c delete mode 100644 src/opus-1.0.2/silk/init_encoder.c delete mode 100644 src/opus-1.0.2/silk/inner_prod_aligned.c delete mode 100644 src/opus-1.0.2/silk/interpolate.c delete mode 100644 src/opus-1.0.2/silk/lin2log.c delete mode 100644 src/opus-1.0.2/silk/log2lin.c delete mode 100644 src/opus-1.0.2/silk/macros.h delete mode 100644 src/opus-1.0.2/silk/main.h delete mode 100644 src/opus-1.0.2/silk/pitch_est_defines.h delete mode 100644 src/opus-1.0.2/silk/pitch_est_tables.c delete mode 100644 src/opus-1.0.2/silk/process_NLSFs.c delete mode 100644 src/opus-1.0.2/silk/quant_LTP_gains.c delete mode 100644 src/opus-1.0.2/silk/resampler.c delete mode 100644 src/opus-1.0.2/silk/resampler_down2.c delete mode 100644 src/opus-1.0.2/silk/resampler_down2_3.c delete mode 100644 src/opus-1.0.2/silk/resampler_private.h delete mode 100644 src/opus-1.0.2/silk/resampler_private_AR2.c delete mode 100644 src/opus-1.0.2/silk/resampler_private_IIR_FIR.c delete mode 100644 src/opus-1.0.2/silk/resampler_private_down_FIR.c delete mode 100644 src/opus-1.0.2/silk/resampler_private_up2_HQ.c delete mode 100644 src/opus-1.0.2/silk/resampler_rom.c delete mode 100644 src/opus-1.0.2/silk/resampler_rom.h delete mode 100644 src/opus-1.0.2/silk/resampler_structs.h delete mode 100644 src/opus-1.0.2/silk/shell_coder.c delete mode 100644 src/opus-1.0.2/silk/sigm_Q15.c delete mode 100644 src/opus-1.0.2/silk/sort.c delete mode 100644 src/opus-1.0.2/silk/stereo_LR_to_MS.c delete mode 100644 src/opus-1.0.2/silk/stereo_MS_to_LR.c delete mode 100644 src/opus-1.0.2/silk/stereo_decode_pred.c delete mode 100644 src/opus-1.0.2/silk/stereo_encode_pred.c delete mode 100644 src/opus-1.0.2/silk/stereo_find_predictor.c delete mode 100644 src/opus-1.0.2/silk/stereo_quant_pred.c delete mode 100644 src/opus-1.0.2/silk/structs.h delete mode 100644 src/opus-1.0.2/silk/sum_sqr_shift.c delete mode 100644 src/opus-1.0.2/silk/table_LSF_cos.c delete mode 100644 src/opus-1.0.2/silk/tables.h delete mode 100644 src/opus-1.0.2/silk/tables_LTP.c delete mode 100644 src/opus-1.0.2/silk/tables_NLSF_CB_NB_MB.c delete mode 100644 src/opus-1.0.2/silk/tables_NLSF_CB_WB.c delete mode 100644 src/opus-1.0.2/silk/tables_gain.c delete mode 100644 src/opus-1.0.2/silk/tables_other.c delete mode 100644 src/opus-1.0.2/silk/tables_pitch_lag.c delete mode 100644 src/opus-1.0.2/silk/tables_pulses_per_block.c delete mode 100644 src/opus-1.0.2/silk/tuning_parameters.h delete mode 100644 src/opus-1.0.2/silk/typedef.h delete mode 100644 src/opus-1.0.2/src/opus.c delete mode 100644 src/opus-1.0.2/src/opus_decoder.c delete mode 100644 src/opus-1.0.2/src/opus_encoder.c delete mode 100644 src/opus-1.0.2/src/opus_multistream.c delete mode 100644 src/opus-1.0.2/src/opus_private.h delete mode 100644 src/opus-1.0.2/src/repacketizer.c create mode 100644 src/opus-1.1/celt/_kiss_fft_guts.h create mode 100644 src/opus-1.1/celt/arch.h create mode 100755 src/opus-1.1/celt/arm/arm2gnu.pl create mode 100644 src/opus-1.1/celt/arm/arm_celt_map.c create mode 100644 src/opus-1.1/celt/arm/armcpu.c create mode 100644 src/opus-1.1/celt/arm/armcpu.h create mode 100644 src/opus-1.1/celt/arm/armopts.s.in create mode 100644 src/opus-1.1/celt/arm/celt_pitch_xcorr_arm.s create mode 100644 src/opus-1.1/celt/arm/fixed_armv4.h create mode 100644 src/opus-1.1/celt/arm/fixed_armv5e.h create mode 100644 src/opus-1.1/celt/arm/kiss_fft_armv4.h create mode 100644 src/opus-1.1/celt/arm/kiss_fft_armv5e.h create mode 100644 src/opus-1.1/celt/arm/pitch_arm.h create mode 100644 src/opus-1.1/celt/bands.c create mode 100644 src/opus-1.1/celt/bands.h create mode 100644 src/opus-1.1/celt/celt.c create mode 100644 src/opus-1.1/celt/celt.h create mode 100644 src/opus-1.1/celt/celt_decoder.c create mode 100644 src/opus-1.1/celt/celt_encoder.c create mode 100644 src/opus-1.1/celt/celt_lpc.c create mode 100644 src/opus-1.1/celt/celt_lpc.h create mode 100644 src/opus-1.1/celt/cpu_support.h create mode 100644 src/opus-1.1/celt/cwrs.c create mode 100644 src/opus-1.1/celt/cwrs.h create mode 100644 src/opus-1.1/celt/ecintrin.h create mode 100644 src/opus-1.1/celt/entcode.c create mode 100644 src/opus-1.1/celt/entcode.h create mode 100644 src/opus-1.1/celt/entdec.c create mode 100644 src/opus-1.1/celt/entdec.h create mode 100644 src/opus-1.1/celt/entenc.c create mode 100644 src/opus-1.1/celt/entenc.h create mode 100644 src/opus-1.1/celt/fixed_debug.h create mode 100644 src/opus-1.1/celt/fixed_generic.h create mode 100644 src/opus-1.1/celt/float_cast.h create mode 100644 src/opus-1.1/celt/kiss_fft.c create mode 100644 src/opus-1.1/celt/kiss_fft.h create mode 100644 src/opus-1.1/celt/laplace.c create mode 100644 src/opus-1.1/celt/laplace.h create mode 100644 src/opus-1.1/celt/mathops.c create mode 100644 src/opus-1.1/celt/mathops.h create mode 100644 src/opus-1.1/celt/mdct.c create mode 100644 src/opus-1.1/celt/mdct.h create mode 100644 src/opus-1.1/celt/mfrngcod.h create mode 100644 src/opus-1.1/celt/modes.c create mode 100644 src/opus-1.1/celt/modes.h create mode 100644 src/opus-1.1/celt/opus_custom_demo.c create mode 100644 src/opus-1.1/celt/os_support.h create mode 100644 src/opus-1.1/celt/pitch.c create mode 100644 src/opus-1.1/celt/pitch.h create mode 100644 src/opus-1.1/celt/quant_bands.c create mode 100644 src/opus-1.1/celt/quant_bands.h create mode 100644 src/opus-1.1/celt/rate.c create mode 100644 src/opus-1.1/celt/rate.h create mode 100644 src/opus-1.1/celt/stack_alloc.h create mode 100644 src/opus-1.1/celt/static_modes_fixed.h create mode 100644 src/opus-1.1/celt/static_modes_float.h create mode 100644 src/opus-1.1/celt/vq.c create mode 100644 src/opus-1.1/celt/vq.h create mode 100644 src/opus-1.1/celt/x86/pitch_sse.h create mode 100644 src/opus-1.1/include/opus.h create mode 100644 src/opus-1.1/include/opus_custom.h create mode 100644 src/opus-1.1/include/opus_defines.h create mode 100644 src/opus-1.1/include/opus_multistream.h create mode 100644 src/opus-1.1/include/opus_types.h create mode 100644 src/opus-1.1/silk/A2NLSF.c create mode 100644 src/opus-1.1/silk/API.h create mode 100644 src/opus-1.1/silk/CNG.c create mode 100644 src/opus-1.1/silk/HP_variable_cutoff.c create mode 100644 src/opus-1.1/silk/Inlines.h create mode 100644 src/opus-1.1/silk/LPC_analysis_filter.c create mode 100644 src/opus-1.1/silk/LPC_inv_pred_gain.c create mode 100644 src/opus-1.1/silk/LP_variable_cutoff.c create mode 100644 src/opus-1.1/silk/MacroCount.h create mode 100644 src/opus-1.1/silk/MacroDebug.h create mode 100644 src/opus-1.1/silk/NLSF2A.c create mode 100644 src/opus-1.1/silk/NLSF_VQ.c create mode 100644 src/opus-1.1/silk/NLSF_VQ_weights_laroia.c create mode 100644 src/opus-1.1/silk/NLSF_decode.c create mode 100644 src/opus-1.1/silk/NLSF_del_dec_quant.c create mode 100644 src/opus-1.1/silk/NLSF_encode.c create mode 100644 src/opus-1.1/silk/NLSF_stabilize.c create mode 100644 src/opus-1.1/silk/NLSF_unpack.c create mode 100644 src/opus-1.1/silk/NSQ.c create mode 100644 src/opus-1.1/silk/NSQ_del_dec.c create mode 100644 src/opus-1.1/silk/PLC.c create mode 100644 src/opus-1.1/silk/PLC.h create mode 100644 src/opus-1.1/silk/SigProc_FIX.h create mode 100644 src/opus-1.1/silk/VAD.c create mode 100644 src/opus-1.1/silk/VQ_WMat_EC.c create mode 100644 src/opus-1.1/silk/ana_filt_bank_1.c create mode 100644 src/opus-1.1/silk/arm/SigProc_FIX_armv4.h create mode 100644 src/opus-1.1/silk/arm/SigProc_FIX_armv5e.h create mode 100644 src/opus-1.1/silk/arm/macros_armv4.h create mode 100644 src/opus-1.1/silk/arm/macros_armv5e.h create mode 100644 src/opus-1.1/silk/biquad_alt.c create mode 100644 src/opus-1.1/silk/bwexpander.c create mode 100644 src/opus-1.1/silk/bwexpander_32.c create mode 100644 src/opus-1.1/silk/check_control_input.c create mode 100644 src/opus-1.1/silk/code_signs.c create mode 100644 src/opus-1.1/silk/control.h create mode 100644 src/opus-1.1/silk/control_SNR.c create mode 100644 src/opus-1.1/silk/control_audio_bandwidth.c create mode 100644 src/opus-1.1/silk/control_codec.c create mode 100644 src/opus-1.1/silk/debug.c create mode 100644 src/opus-1.1/silk/debug.h create mode 100644 src/opus-1.1/silk/dec_API.c create mode 100644 src/opus-1.1/silk/decode_core.c create mode 100644 src/opus-1.1/silk/decode_frame.c create mode 100644 src/opus-1.1/silk/decode_indices.c create mode 100644 src/opus-1.1/silk/decode_parameters.c create mode 100644 src/opus-1.1/silk/decode_pitch.c create mode 100644 src/opus-1.1/silk/decode_pulses.c create mode 100644 src/opus-1.1/silk/decoder_set_fs.c create mode 100644 src/opus-1.1/silk/define.h create mode 100644 src/opus-1.1/silk/enc_API.c create mode 100644 src/opus-1.1/silk/encode_indices.c create mode 100644 src/opus-1.1/silk/encode_pulses.c create mode 100644 src/opus-1.1/silk/errors.h create mode 100644 src/opus-1.1/silk/fixed/LTP_analysis_filter_FIX.c create mode 100644 src/opus-1.1/silk/fixed/LTP_scale_ctrl_FIX.c create mode 100644 src/opus-1.1/silk/fixed/apply_sine_window_FIX.c create mode 100644 src/opus-1.1/silk/fixed/autocorr_FIX.c create mode 100644 src/opus-1.1/silk/fixed/burg_modified_FIX.c create mode 100644 src/opus-1.1/silk/fixed/corrMatrix_FIX.c create mode 100644 src/opus-1.1/silk/fixed/encode_frame_FIX.c create mode 100644 src/opus-1.1/silk/fixed/find_LPC_FIX.c create mode 100644 src/opus-1.1/silk/fixed/find_LTP_FIX.c create mode 100644 src/opus-1.1/silk/fixed/find_pitch_lags_FIX.c create mode 100644 src/opus-1.1/silk/fixed/find_pred_coefs_FIX.c create mode 100644 src/opus-1.1/silk/fixed/k2a_FIX.c create mode 100644 src/opus-1.1/silk/fixed/k2a_Q16_FIX.c create mode 100644 src/opus-1.1/silk/fixed/main_FIX.h create mode 100644 src/opus-1.1/silk/fixed/noise_shape_analysis_FIX.c create mode 100644 src/opus-1.1/silk/fixed/pitch_analysis_core_FIX.c create mode 100644 src/opus-1.1/silk/fixed/prefilter_FIX.c create mode 100644 src/opus-1.1/silk/fixed/process_gains_FIX.c create mode 100644 src/opus-1.1/silk/fixed/regularize_correlations_FIX.c create mode 100644 src/opus-1.1/silk/fixed/residual_energy16_FIX.c create mode 100644 src/opus-1.1/silk/fixed/residual_energy_FIX.c create mode 100644 src/opus-1.1/silk/fixed/schur64_FIX.c create mode 100644 src/opus-1.1/silk/fixed/schur_FIX.c create mode 100644 src/opus-1.1/silk/fixed/solve_LS_FIX.c create mode 100644 src/opus-1.1/silk/fixed/structs_FIX.h create mode 100644 src/opus-1.1/silk/fixed/vector_ops_FIX.c create mode 100644 src/opus-1.1/silk/fixed/warped_autocorrelation_FIX.c create mode 100644 src/opus-1.1/silk/float/LPC_analysis_filter_FLP.c create mode 100644 src/opus-1.1/silk/float/LPC_inv_pred_gain_FLP.c create mode 100644 src/opus-1.1/silk/float/LTP_analysis_filter_FLP.c create mode 100644 src/opus-1.1/silk/float/LTP_scale_ctrl_FLP.c create mode 100644 src/opus-1.1/silk/float/SigProc_FLP.h create mode 100644 src/opus-1.1/silk/float/apply_sine_window_FLP.c create mode 100644 src/opus-1.1/silk/float/autocorrelation_FLP.c create mode 100644 src/opus-1.1/silk/float/burg_modified_FLP.c create mode 100644 src/opus-1.1/silk/float/bwexpander_FLP.c create mode 100644 src/opus-1.1/silk/float/corrMatrix_FLP.c create mode 100644 src/opus-1.1/silk/float/encode_frame_FLP.c create mode 100644 src/opus-1.1/silk/float/energy_FLP.c create mode 100644 src/opus-1.1/silk/float/find_LPC_FLP.c create mode 100644 src/opus-1.1/silk/float/find_LTP_FLP.c create mode 100644 src/opus-1.1/silk/float/find_pitch_lags_FLP.c create mode 100644 src/opus-1.1/silk/float/find_pred_coefs_FLP.c create mode 100644 src/opus-1.1/silk/float/inner_product_FLP.c create mode 100644 src/opus-1.1/silk/float/k2a_FLP.c create mode 100644 src/opus-1.1/silk/float/levinsondurbin_FLP.c create mode 100644 src/opus-1.1/silk/float/main_FLP.h create mode 100644 src/opus-1.1/silk/float/noise_shape_analysis_FLP.c create mode 100644 src/opus-1.1/silk/float/pitch_analysis_core_FLP.c create mode 100644 src/opus-1.1/silk/float/prefilter_FLP.c create mode 100644 src/opus-1.1/silk/float/process_gains_FLP.c create mode 100644 src/opus-1.1/silk/float/regularize_correlations_FLP.c create mode 100644 src/opus-1.1/silk/float/residual_energy_FLP.c create mode 100644 src/opus-1.1/silk/float/scale_copy_vector_FLP.c create mode 100644 src/opus-1.1/silk/float/scale_vector_FLP.c create mode 100644 src/opus-1.1/silk/float/schur_FLP.c create mode 100644 src/opus-1.1/silk/float/solve_LS_FLP.c create mode 100644 src/opus-1.1/silk/float/sort_FLP.c create mode 100644 src/opus-1.1/silk/float/structs_FLP.h create mode 100644 src/opus-1.1/silk/float/warped_autocorrelation_FLP.c create mode 100644 src/opus-1.1/silk/float/wrappers_FLP.c create mode 100644 src/opus-1.1/silk/gain_quant.c create mode 100644 src/opus-1.1/silk/init_decoder.c create mode 100644 src/opus-1.1/silk/init_encoder.c create mode 100644 src/opus-1.1/silk/inner_prod_aligned.c create mode 100644 src/opus-1.1/silk/interpolate.c create mode 100644 src/opus-1.1/silk/lin2log.c create mode 100644 src/opus-1.1/silk/log2lin.c create mode 100644 src/opus-1.1/silk/macros.h create mode 100644 src/opus-1.1/silk/main.h create mode 100644 src/opus-1.1/silk/pitch_est_defines.h create mode 100644 src/opus-1.1/silk/pitch_est_tables.c create mode 100644 src/opus-1.1/silk/process_NLSFs.c create mode 100644 src/opus-1.1/silk/quant_LTP_gains.c create mode 100644 src/opus-1.1/silk/resampler.c create mode 100644 src/opus-1.1/silk/resampler_down2.c create mode 100644 src/opus-1.1/silk/resampler_down2_3.c create mode 100644 src/opus-1.1/silk/resampler_private.h create mode 100644 src/opus-1.1/silk/resampler_private_AR2.c create mode 100644 src/opus-1.1/silk/resampler_private_IIR_FIR.c create mode 100644 src/opus-1.1/silk/resampler_private_down_FIR.c create mode 100644 src/opus-1.1/silk/resampler_private_up2_HQ.c create mode 100644 src/opus-1.1/silk/resampler_rom.c create mode 100644 src/opus-1.1/silk/resampler_rom.h create mode 100644 src/opus-1.1/silk/resampler_structs.h create mode 100644 src/opus-1.1/silk/shell_coder.c create mode 100644 src/opus-1.1/silk/sigm_Q15.c create mode 100644 src/opus-1.1/silk/sort.c create mode 100644 src/opus-1.1/silk/stereo_LR_to_MS.c create mode 100644 src/opus-1.1/silk/stereo_MS_to_LR.c create mode 100644 src/opus-1.1/silk/stereo_decode_pred.c create mode 100644 src/opus-1.1/silk/stereo_encode_pred.c create mode 100644 src/opus-1.1/silk/stereo_find_predictor.c create mode 100644 src/opus-1.1/silk/stereo_quant_pred.c create mode 100644 src/opus-1.1/silk/structs.h create mode 100644 src/opus-1.1/silk/sum_sqr_shift.c create mode 100644 src/opus-1.1/silk/table_LSF_cos.c create mode 100644 src/opus-1.1/silk/tables.h create mode 100644 src/opus-1.1/silk/tables_LTP.c create mode 100644 src/opus-1.1/silk/tables_NLSF_CB_NB_MB.c create mode 100644 src/opus-1.1/silk/tables_NLSF_CB_WB.c create mode 100644 src/opus-1.1/silk/tables_gain.c create mode 100644 src/opus-1.1/silk/tables_other.c create mode 100644 src/opus-1.1/silk/tables_pitch_lag.c create mode 100644 src/opus-1.1/silk/tables_pulses_per_block.c create mode 100644 src/opus-1.1/silk/tuning_parameters.h create mode 100644 src/opus-1.1/silk/typedef.h create mode 100644 src/opus-1.1/src/analysis.c create mode 100644 src/opus-1.1/src/analysis.h create mode 100644 src/opus-1.1/src/mlp.c create mode 100644 src/opus-1.1/src/mlp.h create mode 100644 src/opus-1.1/src/mlp_data.c create mode 100644 src/opus-1.1/src/opus.c create mode 100644 src/opus-1.1/src/opus_decoder.c create mode 100644 src/opus-1.1/src/opus_encoder.c create mode 100644 src/opus-1.1/src/opus_multistream.c create mode 100644 src/opus-1.1/src/opus_multistream_decoder.c create mode 100644 src/opus-1.1/src/opus_multistream_encoder.c create mode 100644 src/opus-1.1/src/opus_private.h create mode 100644 src/opus-1.1/src/repacketizer.c create mode 100644 src/opus-1.1/src/tansig_table.h (limited to 'src') diff --git a/src/opus-1.0.2/celt/_kiss_fft_guts.h b/src/opus-1.0.2/celt/_kiss_fft_guts.h deleted file mode 100644 index 33e62c6b..00000000 --- a/src/opus-1.0.2/celt/_kiss_fft_guts.h +++ /dev/null @@ -1,175 +0,0 @@ -/*Copyright (c) 2003-2004, Mark Borgerding - - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE.*/ - -#ifndef KISS_FFT_GUTS_H -#define KISS_FFT_GUTS_H - -#define MIN(a,b) ((a)<(b) ? (a):(b)) -#define MAX(a,b) ((a)>(b) ? (a):(b)) - -/* kiss_fft.h - defines kiss_fft_scalar as either short or a float type - and defines - typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */ -#include "kiss_fft.h" - -/* - Explanation of macros dealing with complex math: - - C_MUL(m,a,b) : m = a*b - C_FIXDIV( c , div ) : if a fixed point impl., c /= div. noop otherwise - C_SUB( res, a,b) : res = a - b - C_SUBFROM( res , a) : res -= a - C_ADDTO( res , a) : res += a - * */ -#ifdef FIXED_POINT -#include "arch.h" - - -#define SAMP_MAX 2147483647 -#define TWID_MAX 32767 -#define TRIG_UPSCALE 1 - -#define SAMP_MIN -SAMP_MAX - - -# define S_MUL(a,b) MULT16_32_Q15(b, a) - -# define C_MUL(m,a,b) \ - do{ (m).r = SUB32(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)); \ - (m).i = ADD32(S_MUL((a).r,(b).i) , S_MUL((a).i,(b).r)); }while(0) - -# define C_MULC(m,a,b) \ - do{ (m).r = ADD32(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)); \ - (m).i = SUB32(S_MUL((a).i,(b).r) , S_MUL((a).r,(b).i)); }while(0) - -# define C_MUL4(m,a,b) \ - do{ (m).r = SHR32(SUB32(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)),2); \ - (m).i = SHR32(ADD32(S_MUL((a).r,(b).i) , S_MUL((a).i,(b).r)),2); }while(0) - -# define C_MULBYSCALAR( c, s ) \ - do{ (c).r = S_MUL( (c).r , s ) ;\ - (c).i = S_MUL( (c).i , s ) ; }while(0) - -# define DIVSCALAR(x,k) \ - (x) = S_MUL( x, (TWID_MAX-((k)>>1))/(k)+1 ) - -# define C_FIXDIV(c,div) \ - do { DIVSCALAR( (c).r , div); \ - DIVSCALAR( (c).i , div); }while (0) - -#define C_ADD( res, a,b)\ - do {(res).r=ADD32((a).r,(b).r); (res).i=ADD32((a).i,(b).i); \ - }while(0) -#define C_SUB( res, a,b)\ - do {(res).r=SUB32((a).r,(b).r); (res).i=SUB32((a).i,(b).i); \ - }while(0) -#define C_ADDTO( res , a)\ - do {(res).r = ADD32((res).r, (a).r); (res).i = ADD32((res).i,(a).i);\ - }while(0) - -#define C_SUBFROM( res , a)\ - do {(res).r = ADD32((res).r,(a).r); (res).i = SUB32((res).i,(a).i); \ - }while(0) - -#else /* not FIXED_POINT*/ - -# define S_MUL(a,b) ( (a)*(b) ) -#define C_MUL(m,a,b) \ - do{ (m).r = (a).r*(b).r - (a).i*(b).i;\ - (m).i = (a).r*(b).i + (a).i*(b).r; }while(0) -#define C_MULC(m,a,b) \ - do{ (m).r = (a).r*(b).r + (a).i*(b).i;\ - (m).i = (a).i*(b).r - (a).r*(b).i; }while(0) - -#define C_MUL4(m,a,b) C_MUL(m,a,b) - -# define C_FIXDIV(c,div) /* NOOP */ -# define C_MULBYSCALAR( c, s ) \ - do{ (c).r *= (s);\ - (c).i *= (s); }while(0) -#endif - -#ifndef CHECK_OVERFLOW_OP -# define CHECK_OVERFLOW_OP(a,op,b) /* noop */ -#endif - -#ifndef C_ADD -#define C_ADD( res, a,b)\ - do { \ - CHECK_OVERFLOW_OP((a).r,+,(b).r)\ - CHECK_OVERFLOW_OP((a).i,+,(b).i)\ - (res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \ - }while(0) -#define C_SUB( res, a,b)\ - do { \ - CHECK_OVERFLOW_OP((a).r,-,(b).r)\ - CHECK_OVERFLOW_OP((a).i,-,(b).i)\ - (res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \ - }while(0) -#define C_ADDTO( res , a)\ - do { \ - CHECK_OVERFLOW_OP((res).r,+,(a).r)\ - CHECK_OVERFLOW_OP((res).i,+,(a).i)\ - (res).r += (a).r; (res).i += (a).i;\ - }while(0) - -#define C_SUBFROM( res , a)\ - do {\ - CHECK_OVERFLOW_OP((res).r,-,(a).r)\ - CHECK_OVERFLOW_OP((res).i,-,(a).i)\ - (res).r -= (a).r; (res).i -= (a).i; \ - }while(0) -#endif /* C_ADD defined */ - -#ifdef FIXED_POINT -/*# define KISS_FFT_COS(phase) TRIG_UPSCALE*floor(MIN(32767,MAX(-32767,.5+32768 * cos (phase)))) -# define KISS_FFT_SIN(phase) TRIG_UPSCALE*floor(MIN(32767,MAX(-32767,.5+32768 * sin (phase))))*/ -# define KISS_FFT_COS(phase) floor(.5+TWID_MAX*cos (phase)) -# define KISS_FFT_SIN(phase) floor(.5+TWID_MAX*sin (phase)) -# define HALF_OF(x) ((x)>>1) -#elif defined(USE_SIMD) -# define KISS_FFT_COS(phase) _mm_set1_ps( cos(phase) ) -# define KISS_FFT_SIN(phase) _mm_set1_ps( sin(phase) ) -# define HALF_OF(x) ((x)*_mm_set1_ps(.5f)) -#else -# define KISS_FFT_COS(phase) (kiss_fft_scalar) cos(phase) -# define KISS_FFT_SIN(phase) (kiss_fft_scalar) sin(phase) -# define HALF_OF(x) ((x)*.5f) -#endif - -#define kf_cexp(x,phase) \ - do{ \ - (x)->r = KISS_FFT_COS(phase);\ - (x)->i = KISS_FFT_SIN(phase);\ - }while(0) - -#define kf_cexp2(x,phase) \ - do{ \ - (x)->r = TRIG_UPSCALE*celt_cos_norm((phase));\ - (x)->i = TRIG_UPSCALE*celt_cos_norm((phase)-32768);\ -}while(0) - -#endif /* KISS_FFT_GUTS_H */ diff --git a/src/opus-1.0.2/celt/arch.h b/src/opus-1.0.2/celt/arch.h deleted file mode 100644 index 03cda40f..00000000 --- a/src/opus-1.0.2/celt/arch.h +++ /dev/null @@ -1,209 +0,0 @@ -/* Copyright (c) 2003-2008 Jean-Marc Valin - Copyright (c) 2007-2008 CSIRO - Copyright (c) 2007-2009 Xiph.Org Foundation - Written by Jean-Marc Valin */ -/** - @file arch.h - @brief Various architecture definitions for CELT -*/ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef ARCH_H -#define ARCH_H - -#include "opus_types.h" - -# if !defined(__GNUC_PREREQ) -# if defined(__GNUC__)&&defined(__GNUC_MINOR__) -# define __GNUC_PREREQ(_maj,_min) \ - ((__GNUC__<<16)+__GNUC_MINOR__>=((_maj)<<16)+(_min)) -# else -# define __GNUC_PREREQ(_maj,_min) 0 -# endif -# endif - -#define CELT_SIG_SCALE 32768.f - -#define celt_fatal(str) _celt_fatal(str, __FILE__, __LINE__); -#ifdef ENABLE_ASSERTIONS -#include -#include -#ifdef __GNUC__ -__attribute__((noreturn)) -#endif -static inline void _celt_fatal(const char *str, const char *file, int line) -{ - fprintf (stderr, "Fatal (internal) error in %s, line %d: %s\n", file, line, str); - abort(); -} -#define celt_assert(cond) {if (!(cond)) {celt_fatal("assertion failed: " #cond);}} -#define celt_assert2(cond, message) {if (!(cond)) {celt_fatal("assertion failed: " #cond "\n" message);}} -#else -#define celt_assert(cond) -#define celt_assert2(cond, message) -#endif - -#define IMUL32(a,b) ((a)*(b)) - -#define ABS(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute integer value. */ -#define ABS16(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 16-bit value. */ -#define MIN16(a,b) ((a) < (b) ? (a) : (b)) /**< Minimum 16-bit value. */ -#define MAX16(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 16-bit value. */ -#define ABS32(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 32-bit value. */ -#define MIN32(a,b) ((a) < (b) ? (a) : (b)) /**< Minimum 32-bit value. */ -#define MAX32(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 32-bit value. */ -#define IMIN(a,b) ((a) < (b) ? (a) : (b)) /**< Minimum int value. */ -#define IMAX(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum int value. */ -#define UADD32(a,b) ((a)+(b)) -#define USUB32(a,b) ((a)-(b)) - -#define PRINT_MIPS(file) - -#ifdef FIXED_POINT - -typedef opus_int16 opus_val16; -typedef opus_int32 opus_val32; - -typedef opus_val32 celt_sig; -typedef opus_val16 celt_norm; -typedef opus_val32 celt_ener; - -#define Q15ONE 32767 - -#define SIG_SHIFT 12 - -#define NORM_SCALING 16384 - -#define DB_SHIFT 10 - -#define EPSILON 1 -#define VERY_LARGE16 ((opus_val16)32767) -#define Q15_ONE ((opus_val16)32767) - -#define SCALEIN(a) (a) -#define SCALEOUT(a) (a) - -#ifdef FIXED_DEBUG -#include "fixed_debug.h" -#else - -#include "fixed_generic.h" - -#ifdef ARM5E_ASM -#include "fixed_arm5e.h" -#elif defined (ARM4_ASM) -#include "fixed_arm4.h" -#elif defined (BFIN_ASM) -#include "fixed_bfin.h" -#elif defined (TI_C5X_ASM) -#include "fixed_c5x.h" -#elif defined (TI_C6X_ASM) -#include "fixed_c6x.h" -#endif - -#endif - -#else /* FIXED_POINT */ - -typedef float opus_val16; -typedef float opus_val32; - -typedef float celt_sig; -typedef float celt_norm; -typedef float celt_ener; - -#define Q15ONE 1.0f - -#define NORM_SCALING 1.f - -#define EPSILON 1e-15f -#define VERY_LARGE16 1e15f -#define Q15_ONE ((opus_val16)1.f) - -#define QCONST16(x,bits) (x) -#define QCONST32(x,bits) (x) - -#define NEG16(x) (-(x)) -#define NEG32(x) (-(x)) -#define EXTRACT16(x) (x) -#define EXTEND32(x) (x) -#define SHR16(a,shift) (a) -#define SHL16(a,shift) (a) -#define SHR32(a,shift) (a) -#define SHL32(a,shift) (a) -#define PSHR32(a,shift) (a) -#define VSHR32(a,shift) (a) - -#define PSHR(a,shift) (a) -#define SHR(a,shift) (a) -#define SHL(a,shift) (a) -#define SATURATE(x,a) (x) - -#define ROUND16(a,shift) (a) -#define HALF16(x) (.5f*(x)) -#define HALF32(x) (.5f*(x)) - -#define ADD16(a,b) ((a)+(b)) -#define SUB16(a,b) ((a)-(b)) -#define ADD32(a,b) ((a)+(b)) -#define SUB32(a,b) ((a)-(b)) -#define MULT16_16_16(a,b) ((a)*(b)) -#define MULT16_16(a,b) ((opus_val32)(a)*(opus_val32)(b)) -#define MAC16_16(c,a,b) ((c)+(opus_val32)(a)*(opus_val32)(b)) - -#define MULT16_32_Q15(a,b) ((a)*(b)) -#define MULT16_32_Q16(a,b) ((a)*(b)) - -#define MULT32_32_Q31(a,b) ((a)*(b)) - -#define MAC16_32_Q15(c,a,b) ((c)+(a)*(b)) - -#define MULT16_16_Q11_32(a,b) ((a)*(b)) -#define MULT16_16_Q13(a,b) ((a)*(b)) -#define MULT16_16_Q14(a,b) ((a)*(b)) -#define MULT16_16_Q15(a,b) ((a)*(b)) -#define MULT16_16_P15(a,b) ((a)*(b)) -#define MULT16_16_P13(a,b) ((a)*(b)) -#define MULT16_16_P14(a,b) ((a)*(b)) -#define MULT16_32_P16(a,b) ((a)*(b)) - -#define DIV32_16(a,b) (((opus_val32)(a))/(opus_val16)(b)) -#define DIV32(a,b) (((opus_val32)(a))/(opus_val32)(b)) - -#define SCALEIN(a) ((a)*CELT_SIG_SCALE) -#define SCALEOUT(a) ((a)*(1/CELT_SIG_SCALE)) - -#endif /* !FIXED_POINT */ - -#ifndef GLOBAL_STACK_SIZE -#ifdef FIXED_POINT -#define GLOBAL_STACK_SIZE 100000 -#else -#define GLOBAL_STACK_SIZE 100000 -#endif -#endif - -#endif /* ARCH_H */ diff --git a/src/opus-1.0.2/celt/bands.c b/src/opus-1.0.2/celt/bands.c deleted file mode 100644 index 3be543c3..00000000 --- a/src/opus-1.0.2/celt/bands.c +++ /dev/null @@ -1,1302 +0,0 @@ -/* Copyright (c) 2007-2008 CSIRO - Copyright (c) 2007-2009 Xiph.Org Foundation - Copyright (c) 2008-2009 Gregory Maxwell - Written by Jean-Marc Valin and Gregory Maxwell */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "bands.h" -#include "modes.h" -#include "vq.h" -#include "cwrs.h" -#include "stack_alloc.h" -#include "os_support.h" -#include "mathops.h" -#include "rate.h" - -opus_uint32 celt_lcg_rand(opus_uint32 seed) -{ - return 1664525 * seed + 1013904223; -} - -/* This is a cos() approximation designed to be bit-exact on any platform. Bit exactness - with this approximation is important because it has an impact on the bit allocation */ -static opus_int16 bitexact_cos(opus_int16 x) -{ - opus_int32 tmp; - opus_int16 x2; - tmp = (4096+((opus_int32)(x)*(x)))>>13; - celt_assert(tmp<=32767); - x2 = tmp; - x2 = (32767-x2) + FRAC_MUL16(x2, (-7651 + FRAC_MUL16(x2, (8277 + FRAC_MUL16(-626, x2))))); - celt_assert(x2<=32766); - return 1+x2; -} - -static int bitexact_log2tan(int isin,int icos) -{ - int lc; - int ls; - lc=EC_ILOG(icos); - ls=EC_ILOG(isin); - icos<<=15-lc; - isin<<=15-ls; - return (ls-lc)*(1<<11) - +FRAC_MUL16(isin, FRAC_MUL16(isin, -2597) + 7932) - -FRAC_MUL16(icos, FRAC_MUL16(icos, -2597) + 7932); -} - -#ifdef FIXED_POINT -/* Compute the amplitude (sqrt energy) in each of the bands */ -void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int M) -{ - int i, c, N; - const opus_int16 *eBands = m->eBands; - N = M*m->shortMdctSize; - c=0; do { - for (i=0;i 0) - { - int shift = celt_ilog2(maxval)-10; - j=M*eBands[i]; do { - sum = MAC16_16(sum, EXTRACT16(VSHR32(X[j+c*N],shift)), - EXTRACT16(VSHR32(X[j+c*N],shift))); - } while (++jnbEBands] = EPSILON+VSHR32(EXTEND32(celt_sqrt(sum)),-shift); - } else { - bandE[i+c*m->nbEBands] = EPSILON; - } - /*printf ("%f ", bandE[i+c*m->nbEBands]);*/ - } - } while (++ceBands; - N = M*m->shortMdctSize; - c=0; do { - i=0; do { - opus_val16 g; - int j,shift; - opus_val16 E; - shift = celt_zlog2(bandE[i+c*m->nbEBands])-13; - E = VSHR32(bandE[i+c*m->nbEBands], shift); - g = EXTRACT16(celt_rcp(SHL32(E,3))); - j=M*eBands[i]; do { - X[j+c*N] = MULT16_16_Q15(VSHR32(freq[j+c*N],shift-1),g); - } while (++jeBands; - N = M*m->shortMdctSize; - c=0; do { - for (i=0;inbEBands] = celt_sqrt(sum); - /*printf ("%f ", bandE[i+c*m->nbEBands]);*/ - } - } while (++ceBands; - N = M*m->shortMdctSize; - c=0; do { - for (i=0;inbEBands]); - for (j=M*eBands[i];jeBands; - N = M*m->shortMdctSize; - celt_assert2(C<=2, "denormalise_bands() not implemented for >2 channels"); - c=0; do { - celt_sig * OPUS_RESTRICT f; - const celt_norm * OPUS_RESTRICT x; - f = freq+c*N; - x = X+c*N; - for (i=0;inbEBands],1); - j=M*eBands[i]; - band_end = M*eBands[i+1]; - do { - *f++ = SHL32(MULT16_32_Q15(*x, g),2); - x++; - } while (++jeBands[i+1]-m->eBands[i]; - /* depth in 1/8 bits */ - depth = (1+pulses[i])/((m->eBands[i+1]-m->eBands[i])<>1; - t = SHL32(t, (7-shift)<<1); - sqrt_1 = celt_rsqrt_norm(t); - } -#else - thresh = .5f*celt_exp2(-.125f*depth); - sqrt_1 = celt_rsqrt(N0<nbEBands+i]; - prev2 = prev2logE[c*m->nbEBands+i]; - if (C==1) - { - prev1 = MAX16(prev1,prev1logE[m->nbEBands+i]); - prev2 = MAX16(prev2,prev2logE[m->nbEBands+i]); - } - Ediff = EXTEND32(logE[c*m->nbEBands+i])-EXTEND32(MIN16(prev1,prev2)); - Ediff = MAX32(0, Ediff); - -#ifdef FIXED_POINT - if (Ediff < 16384) - { - opus_val32 r32 = SHR32(celt_exp2(-EXTRACT16(Ediff)),1); - r = 2*MIN16(16383,r32); - } else { - r = 0; - } - if (LM==3) - r = MULT16_16_Q14(23170, MIN32(23169, r)); - r = SHR16(MIN16(thresh, r),1); - r = SHR32(MULT16_16_Q15(sqrt_1, r),shift); -#else - /* r needs to be multiplied by 2 or 2*sqrt(2) depending on LM because - short blocks don't have the same energy as long */ - r = 2.f*celt_exp2(-Ediff); - if (LM==3) - r *= 1.41421356f; - r = MIN16(thresh, r); - r = r*sqrt_1; -#endif - X = X_+c*size+(m->eBands[i]<nbEBands]))-13; -#endif - left = VSHR32(bandE[i],shift); - right = VSHR32(bandE[i+m->nbEBands],shift); - norm = EPSILON + celt_sqrt(EPSILON+MULT16_16(left,left)+MULT16_16(right,right)); - a1 = DIV32_16(SHL32(EXTEND32(left),14),norm); - a2 = DIV32_16(SHL32(EXTEND32(right),14),norm); - for (j=0;j>1; - kr = celt_ilog2(Er)>>1; -#endif - t = VSHR32(El, (kl-7)<<1); - lgain = celt_rsqrt_norm(t); - t = VSHR32(Er, (kr-7)<<1); - rgain = celt_rsqrt_norm(t); - -#ifdef FIXED_POINT - if (kl < 7) - kl = 7; - if (kr < 7) - kr = 7; -#endif - - for (j=0;jeBands; - int decision; - int hf_sum=0; - - celt_assert(end>0); - - N0 = M*m->shortMdctSize; - - if (M*(eBands[end]-eBands[end-1]) <= 8) - return SPREAD_NONE; - c=0; do { - for (i=0;im->nbEBands-4) - hf_sum += 32*(tcount[1]+tcount[0])/N; - tmp = (2*tcount[2] >= N) + (2*tcount[1] >= N) + (2*tcount[0] >= N); - sum += tmp*256; - nbBands++; - } - } while (++cnbEBands+end); - *hf_average = (*hf_average+hf_sum)>>1; - hf_sum = *hf_average; - if (*tapset_decision==2) - hf_sum += 4; - else if (*tapset_decision==0) - hf_sum -= 4; - if (hf_sum > 22) - *tapset_decision=2; - else if (hf_sum > 18) - *tapset_decision=1; - else - *tapset_decision=0; - } - /*printf("%d %d %d\n", hf_sum, *hf_average, *tapset_decision);*/ - celt_assert(nbBands>0); /*M*(eBands[end]-eBands[end-1]) <= 8 assures this*/ - sum /= nbBands; - /* Recursive averaging */ - sum = (sum+*average)>>1; - *average = sum; - /* Hysteresis */ - sum = (3*sum + (((3-last_decision)<<7) + 64) + 2)>>2; - if (sum < 80) - { - decision = SPREAD_AGGRESSIVE; - } else if (sum < 256) - { - decision = SPREAD_NORMAL; - } else if (sum < 384) - { - decision = SPREAD_LIGHT; - } else { - decision = SPREAD_NONE; - } -#ifdef FUZZING - decision = rand()&0x3; - *tapset_decision=rand()%3; -#endif - return decision; -} - -#ifdef MEASURE_NORM_MSE - -float MSE[30] = {0}; -int nbMSEBands = 0; -int MSECount[30] = {0}; - -void dump_norm_mse(void) -{ - int i; - for (i=0;inbEBands;i++) - { - int j; - int c; - float g; - if (bandE0[i]<10 || (C==2 && bandE0[i+m->nbEBands]<1)) - continue; - c=0; do { - g = bandE[i+c*m->nbEBands]/(1e-15+bandE0[i+c*m->nbEBands]); - for (j=M*m->eBands[i];jeBands[i+1];j++) - MSE[i] += (g*X[j+c*N]-X0[j+c*N])*(g*X[j+c*N]-X0[j+c*N]); - } while (++cnbEBands; -} - -#endif - -/* Indexing table for converting from natural Hadamard to ordery Hadamard - This is essentially a bit-reversed Gray, on top of which we've added - an inversion of the order because we want the DC at the end rather than - the beginning. The lines are for N=2, 4, 8, 16 */ -static const int ordery_table[] = { - 1, 0, - 3, 0, 2, 1, - 7, 0, 4, 3, 6, 1, 5, 2, - 15, 0, 8, 7, 12, 3, 11, 4, 14, 1, 9, 6, 13, 2, 10, 5, -}; - -static void deinterleave_hadamard(celt_norm *X, int N0, int stride, int hadamard) -{ - int i,j; - VARDECL(celt_norm, tmp); - int N; - SAVE_STACK; - N = N0*stride; - ALLOC(tmp, N, celt_norm); - celt_assert(stride>0); - if (hadamard) - { - const int *ordery = ordery_table+stride-2; - for (i=0;i>= 1; - for (i=0;i>1)) { - qn = 1; - } else { - qn = exp2_table8[qb&0x7]>>(14-(qb>>BITRES)); - qn = (qn+1)>>1<<1; - } - celt_assert(qn <= 256); - return qn; -} - -/* This function is responsible for encoding and decoding a band for both - the mono and stereo case. Even in the mono case, it can split the band - in two and transmit the energy difference with the two half-bands. It - can be called recursively so bands can end up being split in 8 parts. */ -static unsigned quant_band(int encode, const CELTMode *m, int i, celt_norm *X, celt_norm *Y, - int N, int b, int spread, int B, int intensity, int tf_change, celt_norm *lowband, ec_ctx *ec, - opus_int32 *remaining_bits, int LM, celt_norm *lowband_out, const celt_ener *bandE, int level, - opus_uint32 *seed, opus_val16 gain, celt_norm *lowband_scratch, int fill) -{ - const unsigned char *cache; - int q; - int curr_bits; - int stereo, split; - int imid=0, iside=0; - int N0=N; - int N_B=N; - int N_B0; - int B0=B; - int time_divide=0; - int recombine=0; - int inv = 0; - opus_val16 mid=0, side=0; - int longBlocks; - unsigned cm=0; -#ifdef RESYNTH - int resynth = 1; -#else - int resynth = !encode; -#endif - - longBlocks = B0==1; - - N_B /= B; - N_B0 = N_B; - - split = stereo = Y != NULL; - - /* Special case for one sample */ - if (N==1) - { - int c; - celt_norm *x = X; - c=0; do { - int sign=0; - if (*remaining_bits>=1<0) - recombine = tf_change; - /* Band recombining to increase frequency resolution */ - - if (lowband && (recombine || ((N_B&1) == 0 && tf_change<0) || B0>1)) - { - int j; - for (j=0;j>k, 1<>k, 1<>4]<<2; - } - B>>=recombine; - N_B<<=recombine; - - /* Increasing the time resolution */ - while ((N_B&1) == 0 && tf_change<0) - { - if (encode) - haar1(X, N_B, B); - if (lowband) - haar1(lowband, N_B, B); - fill |= fill<>= 1; - time_divide++; - tf_change++; - } - B0=B; - N_B0 = N_B; - - /* Reorganize the samples in time order instead of frequency order */ - if (B0>1) - { - if (encode) - deinterleave_hadamard(X, N_B>>recombine, B0<>recombine, B0<cache.bits + m->cache.index[(LM+1)*m->nbEBands+i]; - if (!stereo && LM != -1 && b > cache[cache[0]]+12 && N>2) - { - N >>= 1; - Y = X+N; - split = 1; - LM -= 1; - if (B==1) - fill = (fill&1)|(fill<<1); - B = (B+1)>>1; - } - - if (split) - { - int qn; - int itheta=0; - int mbits, sbits, delta; - int qalloc; - int pulse_cap; - int offset; - int orig_fill; - opus_int32 tell; - - /* Decide on the resolution to give to the split parameter theta */ - pulse_cap = m->logN[i]+LM*(1<>1) - (stereo&&N==2 ? QTHETA_OFFSET_TWOPHASE : QTHETA_OFFSET); - qn = compute_qn(N, b, offset, pulse_cap, stereo); - if (stereo && i>=intensity) - qn = 1; - if (encode) - { - /* theta is the atan() of the ratio between the (normalized) - side and mid. With just that parameter, we can re-scale both - mid and side because we know that 1) they have unit norm and - 2) they are orthogonal. */ - itheta = stereo_itheta(X, Y, stereo, N); - } - tell = ec_tell_frac(ec); - if (qn!=1) - { - if (encode) - itheta = (itheta*qn+8192)>>14; - - /* Entropy coding of the angle. We use a uniform pdf for the - time split, a step for stereo, and a triangular one for the rest. */ - if (stereo && N>2) - { - int p0 = 3; - int x = itheta; - int x0 = qn/2; - int ft = p0*(x0+1) + x0; - /* Use a probability of p0 up to itheta=8192 and then use 1 after */ - if (encode) - { - ec_encode(ec,x<=x0?p0*x:(x-1-x0)+(x0+1)*p0,x<=x0?p0*(x+1):(x-x0)+(x0+1)*p0,ft); - } else { - int fs; - fs=ec_decode(ec,ft); - if (fs<(x0+1)*p0) - x=fs/p0; - else - x=x0+1+(fs-(x0+1)*p0); - ec_dec_update(ec,x<=x0?p0*x:(x-1-x0)+(x0+1)*p0,x<=x0?p0*(x+1):(x-x0)+(x0+1)*p0,ft); - itheta = x; - } - } else if (B0>1 || stereo) { - /* Uniform pdf */ - if (encode) - ec_enc_uint(ec, itheta, qn+1); - else - itheta = ec_dec_uint(ec, qn+1); - } else { - int fs=1, ft; - ft = ((qn>>1)+1)*((qn>>1)+1); - if (encode) - { - int fl; - - fs = itheta <= (qn>>1) ? itheta + 1 : qn + 1 - itheta; - fl = itheta <= (qn>>1) ? itheta*(itheta + 1)>>1 : - ft - ((qn + 1 - itheta)*(qn + 2 - itheta)>>1); - - ec_encode(ec, fl, fl+fs, ft); - } else { - /* Triangular pdf */ - int fl=0; - int fm; - fm = ec_decode(ec, ft); - - if (fm < ((qn>>1)*((qn>>1) + 1)>>1)) - { - itheta = (isqrt32(8*(opus_uint32)fm + 1) - 1)>>1; - fs = itheta + 1; - fl = itheta*(itheta + 1)>>1; - } - else - { - itheta = (2*(qn + 1) - - isqrt32(8*(opus_uint32)(ft - fm - 1) + 1))>>1; - fs = qn + 1 - itheta; - fl = ft - ((qn + 1 - itheta)*(qn + 2 - itheta)>>1); - } - - ec_dec_update(ec, fl, fl+fs, ft); - } - } - itheta = (opus_int32)itheta*16384/qn; - if (encode && stereo) - { - if (itheta==0) - intensity_stereo(m, X, Y, bandE, i, N); - else - stereo_split(X, Y, N); - } - /* NOTE: Renormalising X and Y *may* help fixed-point a bit at very high rate. - Let's do that at higher complexity */ - } else if (stereo) { - if (encode) - { - inv = itheta > 8192; - if (inv) - { - int j; - for (j=0;j2< 2< 8192; - *remaining_bits -= qalloc+sbits; - - x2 = c ? Y : X; - y2 = c ? X : Y; - if (sbits) - { - if (encode) - { - /* Here we only need to encode a sign for the side */ - sign = x2[0]*y2[1] - x2[1]*y2[0] < 0; - ec_enc_bits(ec, sign, 1); - } else { - sign = ec_dec_bits(ec, 1); - } - } - sign = 1-2*sign; - /* We use orig_fill here because we want to fold the side, but if - itheta==16384, we'll have cleared the low bits of fill. */ - cm = quant_band(encode, m, i, x2, NULL, N, mbits, spread, B, intensity, tf_change, lowband, ec, remaining_bits, LM, lowband_out, NULL, level, seed, gain, lowband_scratch, orig_fill); - /* We don't split N=2 bands, so cm is either 1 or 0 (for a fold-collapse), - and there's no need to worry about mixing with the other channel. */ - y2[0] = -sign*x2[1]; - y2[1] = sign*x2[0]; - if (resynth) - { - celt_norm tmp; - X[0] = MULT16_16_Q15(mid, X[0]); - X[1] = MULT16_16_Q15(mid, X[1]); - Y[0] = MULT16_16_Q15(side, Y[0]); - Y[1] = MULT16_16_Q15(side, Y[1]); - tmp = X[0]; - X[0] = SUB16(tmp,Y[0]); - Y[0] = ADD16(tmp,Y[0]); - tmp = X[1]; - X[1] = SUB16(tmp,Y[1]); - Y[1] = ADD16(tmp,Y[1]); - } - } else { - /* "Normal" split code */ - celt_norm *next_lowband2=NULL; - celt_norm *next_lowband_out1=NULL; - int next_level=0; - opus_int32 rebalance; - - /* Give more bits to low-energy MDCTs than they would otherwise deserve */ - if (B0>1 && !stereo && (itheta&0x3fff)) - { - if (itheta > 8192) - /* Rough approximation for pre-echo masking */ - delta -= delta>>(4-LM); - else - /* Corresponds to a forward-masking slope of 1.5 dB per 10 ms */ - delta = IMIN(0, delta + (N<>(5-LM))); - } - mbits = IMAX(0, IMIN(b, (b-delta)/2)); - sbits = b-mbits; - *remaining_bits -= qalloc; - - if (lowband && !stereo) - next_lowband2 = lowband+N; /* >32-bit split case */ - - /* Only stereo needs to pass on lowband_out. Otherwise, it's - handled at the end */ - if (stereo) - next_lowband_out1 = lowband_out; - else - next_level = level+1; - - rebalance = *remaining_bits; - if (mbits >= sbits) - { - /* In stereo mode, we do not apply a scaling to the mid because we need the normalized - mid for folding later */ - cm = quant_band(encode, m, i, X, NULL, N, mbits, spread, B, intensity, tf_change, - lowband, ec, remaining_bits, LM, next_lowband_out1, - NULL, next_level, seed, stereo ? Q15ONE : MULT16_16_P15(gain,mid), lowband_scratch, fill); - rebalance = mbits - (rebalance-*remaining_bits); - if (rebalance > 3<>B)<<((B0>>1)&(stereo-1)); - } else { - /* For a stereo split, the high bits of fill are always zero, so no - folding will be done to the side. */ - cm = quant_band(encode, m, i, Y, NULL, N, sbits, spread, B, intensity, tf_change, - next_lowband2, ec, remaining_bits, LM, NULL, - NULL, next_level, seed, MULT16_16_P15(gain,side), NULL, fill>>B)<<((B0>>1)&(stereo-1)); - rebalance = sbits - (rebalance-*remaining_bits); - if (rebalance > 3< 0) - { - *remaining_bits += curr_bits; - q--; - curr_bits = pulses2bits(m, i, LM, q); - *remaining_bits -= curr_bits; - } - - if (q!=0) - { - int K = get_pulses(q); - - /* Finally do the actual quantization */ - if (encode) - { - cm = alg_quant(X, N, K, spread, B, ec -#ifdef RESYNTH - , gain -#endif - ); - } else { - cm = alg_unquant(X, N, K, spread, B, ec, gain); - } - } else { - /* If there's no pulse, fill the band anyway */ - int j; - if (resynth) - { - unsigned cm_mask; - /*B can be as large as 16, so this shift might overflow an int on a - 16-bit platform; use a long to get defined behavior.*/ - cm_mask = (unsigned)(1UL<>20); - } - cm = cm_mask; - } else { - /* Folded spectrum */ - for (j=0;j1) - interleave_hadamard(X, N_B>>recombine, B0<>= 1; - N_B <<= 1; - cm |= cm>>B; - haar1(X, N_B, B); - } - - for (k=0;k>k, 1<eBands; - celt_norm * OPUS_RESTRICT norm, * OPUS_RESTRICT norm2; - VARDECL(celt_norm, _norm); - VARDECL(celt_norm, lowband_scratch); - int B; - int M; - int lowband_offset; - int update_lowband = 1; - int C = Y_ != NULL ? 2 : 1; -#ifdef RESYNTH - int resynth = 1; -#else - int resynth = !encode; -#endif - SAVE_STACK; - - M = 1<nbEBands], celt_norm); - ALLOC(lowband_scratch, M*(eBands[m->nbEBands]-eBands[m->nbEBands-1]), celt_norm); - norm = _norm; - norm2 = norm + M*eBands[m->nbEBands]; - - lowband_offset = 0; - for (i=start;i= M*eBands[start] && (update_lowband || lowband_offset==0)) - lowband_offset = i; - - tf_change = tf_res[i]; - if (i>=m->effEBands) - { - X=norm; - if (Y_!=NULL) - Y = norm; - } - - /* Get a conservative estimate of the collapse_mask's for the bands we're - going to be folding from. */ - if (lowband_offset != 0 && (spread!=SPREAD_AGGRESSIVE || B>1 || tf_change<0)) - { - int fold_start; - int fold_end; - int fold_i; - /* This ensures we never repeat spectral content within one band */ - effective_lowband = IMAX(M*eBands[start], M*eBands[lowband_offset]-N); - fold_start = lowband_offset; - while(M*eBands[--fold_start] > effective_lowband); - fold_end = lowband_offset-1; - while(M*eBands[++fold_end] < effective_lowband+N); - x_cm = y_cm = 0; - fold_i = fold_start; do { - x_cm |= collapse_masks[fold_i*C+0]; - y_cm |= collapse_masks[fold_i*C+C-1]; - } while (++fold_i(N< -#include "celt.h" -#include "pitch.h" -#include "bands.h" -#include "modes.h" -#include "entcode.h" -#include "quant_bands.h" -#include "rate.h" -#include "stack_alloc.h" -#include "mathops.h" -#include "float_cast.h" -#include -#include "celt_lpc.h" -#include "vq.h" - -#ifndef OPUS_VERSION -#define OPUS_VERSION "unknown" -#endif - -#ifdef CUSTOM_MODES -#define OPUS_CUSTOM_NOSTATIC -#else -#define OPUS_CUSTOM_NOSTATIC static inline -#endif - -static const unsigned char trim_icdf[11] = {126, 124, 119, 109, 87, 41, 19, 9, 4, 2, 0}; -/* Probs: NONE: 21.875%, LIGHT: 6.25%, NORMAL: 65.625%, AGGRESSIVE: 6.25% */ -static const unsigned char spread_icdf[4] = {25, 23, 2, 0}; - -static const unsigned char tapset_icdf[3]={2,1,0}; - -#ifdef CUSTOM_MODES -static const unsigned char toOpusTable[20] = { - 0xE0, 0xE8, 0xF0, 0xF8, - 0xC0, 0xC8, 0xD0, 0xD8, - 0xA0, 0xA8, 0xB0, 0xB8, - 0x00, 0x00, 0x00, 0x00, - 0x80, 0x88, 0x90, 0x98, -}; - -static const unsigned char fromOpusTable[16] = { - 0x80, 0x88, 0x90, 0x98, - 0x40, 0x48, 0x50, 0x58, - 0x20, 0x28, 0x30, 0x38, - 0x00, 0x08, 0x10, 0x18 -}; - -static inline int toOpus(unsigned char c) -{ - int ret=0; - if (c<0xA0) - ret = toOpusTable[c>>3]; - if (ret == 0) - return -1; - else - return ret|(c&0x7); -} - -static inline int fromOpus(unsigned char c) -{ - if (c<0x80) - return -1; - else - return fromOpusTable[(c>>3)-16] | (c&0x7); -} -#endif /* CUSTOM_MODES */ - -#define COMBFILTER_MAXPERIOD 1024 -#define COMBFILTER_MINPERIOD 15 - -static int resampling_factor(opus_int32 rate) -{ - int ret; - switch (rate) - { - case 48000: - ret = 1; - break; - case 24000: - ret = 2; - break; - case 16000: - ret = 3; - break; - case 12000: - ret = 4; - break; - case 8000: - ret = 6; - break; - default: -#ifndef CUSTOM_MODES - celt_assert(0); -#endif - ret = 0; - break; - } - return ret; -} - -/** Encoder state - @brief Encoder state - */ -struct OpusCustomEncoder { - const OpusCustomMode *mode; /**< Mode used by the encoder */ - int overlap; - int channels; - int stream_channels; - - int force_intra; - int clip; - int disable_pf; - int complexity; - int upsample; - int start, end; - - opus_int32 bitrate; - int vbr; - int signalling; - int constrained_vbr; /* If zero, VBR can do whatever it likes with the rate */ - int loss_rate; - int lsb_depth; - - /* Everything beyond this point gets cleared on a reset */ -#define ENCODER_RESET_START rng - - opus_uint32 rng; - int spread_decision; - opus_val32 delayedIntra; - int tonal_average; - int lastCodedBands; - int hf_average; - int tapset_decision; - - int prefilter_period; - opus_val16 prefilter_gain; - int prefilter_tapset; -#ifdef RESYNTH - int prefilter_period_old; - opus_val16 prefilter_gain_old; - int prefilter_tapset_old; -#endif - int consec_transient; - - opus_val32 preemph_memE[2]; - opus_val32 preemph_memD[2]; - - /* VBR-related parameters */ - opus_int32 vbr_reservoir; - opus_int32 vbr_drift; - opus_int32 vbr_offset; - opus_int32 vbr_count; - -#ifdef RESYNTH - celt_sig syn_mem[2][2*MAX_PERIOD]; -#endif - - celt_sig in_mem[1]; /* Size = channels*mode->overlap */ - /* celt_sig prefilter_mem[], Size = channels*COMBFILTER_MAXPERIOD */ - /* opus_val16 oldBandE[], Size = channels*mode->nbEBands */ - /* opus_val16 oldLogE[], Size = channels*mode->nbEBands */ - /* opus_val16 oldLogE2[], Size = channels*mode->nbEBands */ -#ifdef RESYNTH - /* opus_val16 overlap_mem[], Size = channels*overlap */ -#endif -}; - -int celt_encoder_get_size(int channels) -{ - CELTMode *mode = opus_custom_mode_create(48000, 960, NULL); - return opus_custom_encoder_get_size(mode, channels); -} - -OPUS_CUSTOM_NOSTATIC int opus_custom_encoder_get_size(const CELTMode *mode, int channels) -{ - int size = sizeof(struct CELTEncoder) - + (channels*mode->overlap-1)*sizeof(celt_sig) /* celt_sig in_mem[channels*mode->overlap]; */ - + channels*COMBFILTER_MAXPERIOD*sizeof(celt_sig) /* celt_sig prefilter_mem[channels*COMBFILTER_MAXPERIOD]; */ - + 3*channels*mode->nbEBands*sizeof(opus_val16); /* opus_val16 oldBandE[channels*mode->nbEBands]; */ - /* opus_val16 oldLogE[channels*mode->nbEBands]; */ - /* opus_val16 oldLogE2[channels*mode->nbEBands]; */ -#ifdef RESYNTH - size += channels*mode->overlap*sizeof(celt_sig); /* celt_sig overlap_mem[channels*mode->nbEBands]; */ -#endif - return size; -} - -#ifdef CUSTOM_MODES -CELTEncoder *opus_custom_encoder_create(const CELTMode *mode, int channels, int *error) -{ - int ret; - CELTEncoder *st = (CELTEncoder *)opus_alloc(opus_custom_encoder_get_size(mode, channels)); - /* init will handle the NULL case */ - ret = opus_custom_encoder_init(st, mode, channels); - if (ret != OPUS_OK) - { - opus_custom_encoder_destroy(st); - st = NULL; - } - if (error) - *error = ret; - return st; -} -#endif /* CUSTOM_MODES */ - -int celt_encoder_init(CELTEncoder *st, opus_int32 sampling_rate, int channels) -{ - int ret; - ret = opus_custom_encoder_init(st, opus_custom_mode_create(48000, 960, NULL), channels); - if (ret != OPUS_OK) - return ret; - st->upsample = resampling_factor(sampling_rate); - return OPUS_OK; -} - -OPUS_CUSTOM_NOSTATIC int opus_custom_encoder_init(CELTEncoder *st, const CELTMode *mode, int channels) -{ - if (channels < 0 || channels > 2) - return OPUS_BAD_ARG; - - if (st==NULL || mode==NULL) - return OPUS_ALLOC_FAIL; - - OPUS_CLEAR((char*)st, opus_custom_encoder_get_size(mode, channels)); - - st->mode = mode; - st->overlap = mode->overlap; - st->stream_channels = st->channels = channels; - - st->upsample = 1; - st->start = 0; - st->end = st->mode->effEBands; - st->signalling = 1; - - st->constrained_vbr = 1; - st->clip = 1; - - st->bitrate = OPUS_BITRATE_MAX; - st->vbr = 0; - st->force_intra = 0; - st->complexity = 5; - st->lsb_depth=24; - - opus_custom_encoder_ctl(st, OPUS_RESET_STATE); - - return OPUS_OK; -} - -#ifdef CUSTOM_MODES -void opus_custom_encoder_destroy(CELTEncoder *st) -{ - opus_free(st); -} -#endif /* CUSTOM_MODES */ - -static inline opus_val16 SIG2WORD16(celt_sig x) -{ -#ifdef FIXED_POINT - x = PSHR32(x, SIG_SHIFT); - x = MAX32(x, -32768); - x = MIN32(x, 32767); - return EXTRACT16(x); -#else - return (opus_val16)x; -#endif -} - -static int transient_analysis(const opus_val32 * OPUS_RESTRICT in, int len, int C, - int overlap) -{ - int i; - VARDECL(opus_val16, tmp); - opus_val32 mem0=0,mem1=0; - int is_transient = 0; - int block; - int N; - VARDECL(opus_val16, bins); - SAVE_STACK; - ALLOC(tmp, len, opus_val16); - - block = overlap/2; - N=len/block; - ALLOC(bins, N, opus_val16); - if (C==1) - { - for (i=0;i=3) - is_transient=1; - conseq = 0; - for (j=i+1;j=7) - is_transient=1; - } - RESTORE_STACK; -#ifdef FUZZING - is_transient = rand()&0x1; -#endif - return is_transient; -} - -/** Apply window and compute the MDCT for all sub-frames and - all channels in a frame */ -static void compute_mdcts(const CELTMode *mode, int shortBlocks, celt_sig * OPUS_RESTRICT in, celt_sig * OPUS_RESTRICT out, int C, int LM) -{ - if (C==1 && !shortBlocks) - { - const int overlap = OVERLAP(mode); - clt_mdct_forward(&mode->mdct, in, out, mode->window, overlap, mode->maxLM-LM, 1); - } else { - const int overlap = OVERLAP(mode); - int N = mode->shortMdctSize<shortMdctSize; - B = shortBlocks; - } - c=0; do { - for (b=0;bmdct, in+c*(B*N+overlap)+b*N, &out[b+c*N*B], mode->window, overlap, shortBlocks ? mode->maxLM : mode->maxLM-LM, B); - } - } while (++cshortMdctSize<shortMdctSize; - B = shortBlocks; - } - /* Prevents problems from the imdct doing the overlap-add */ - OPUS_CLEAR(x, overlap); - - for (b=0;bmdct, &X[b+c*N2*B], x+N2*b, mode->window, overlap, shortBlocks ? mode->maxLM : mode->maxLM-LM, B); - } - - for (j=0;j>LM;j++) - L2 = MAC16_16(L2, tmp[(j<eBands[len]-m->eBands[len-1])<eBands[i+1]-m->eBands[i])<eBands[i]<eBands[i]<>LM); - best_L1 = L1; - /*printf ("%f ", L1);*/ - for (k=0;k>(LM-k), 1<<(LM-k)); - else - haar1(tmp, N>>k, 1<>LM); - - if (L1 < best_L1) - { - best_L1 = L1; - best_level = k+1; - } - } - /*printf ("%d ", isTransient ? LM-best_level : best_level);*/ - if (isTransient) - metric[i] = best_level; - else - metric[i] = -best_level; - *tf_sum += metric[i]; - } - /*printf("\n");*/ - /* NOTE: Future optimized implementations could detect extreme transients and set - tf_select = 1 but so far we have not found a reliable way of making this useful */ - tf_select = 0; - - cost0 = 0; - cost1 = isTransient ? 0 : lambda; - /* Viterbi forward pass */ - for (i=1;i=0;i--) - { - if (tf_res[i+1] == 1) - tf_res[i] = path1[i+1]; - else - tf_res[i] = path0[i+1]; - } - RESTORE_STACK; -#ifdef FUZZING - tf_select = rand()&0x1; - tf_res[0] = rand()&0x1; - for (i=1;istorage*8; - tell = ec_tell(enc); - logp = isTransient ? 2 : 4; - /* Reserve space to code the tf_select decision. */ - tf_select_rsv = LM>0 && tell+logp+1 <= budget; - budget -= tf_select_rsv; - curr = tf_changed = 0; - for (i=start;istorage*8; - tell = ec_tell(dec); - logp = isTransient ? 2 : 4; - tf_select_rsv = LM>0 && tell+logp+1<=budget; - budget -= tf_select_rsv; - tf_changed = curr = 0; - for (i=start;inbEBands;i++) - { - int N; - N=(m->eBands[i+1]-m->eBands[i])<cache.caps[m->nbEBands*(2*LM+C-1)+i]+64)*C*N>>2; - } -} - -static int alloc_trim_analysis(const CELTMode *m, const celt_norm *X, - const opus_val16 *bandLogE, int end, int LM, int C, int N0) -{ - int i; - opus_val32 diff=0; - int c; - int trim_index = 5; - if (C==2) - { - opus_val16 sum = 0; /* Q10 */ - /* Compute inter-channel correlation for low frequencies */ - for (i=0;i<8;i++) - { - int j; - opus_val32 partial = 0; - for (j=m->eBands[i]<eBands[i+1]< QCONST16(.995f,10)) - trim_index-=4; - else if (sum > QCONST16(.92f,10)) - trim_index-=3; - else if (sum > QCONST16(.85f,10)) - trim_index-=2; - else if (sum > QCONST16(.8f,10)) - trim_index-=1; - } - - /* Estimate spectral tilt */ - c=0; do { - for (i=0;inbEBands]*(opus_int32)(2+2*i-m->nbEBands); - } - } while (++c QCONST16(2.f, DB_SHIFT)) - trim_index--; - if (diff > QCONST16(8.f, DB_SHIFT)) - trim_index--; - if (diff < -QCONST16(4.f, DB_SHIFT)) - trim_index++; - if (diff < -QCONST16(10.f, DB_SHIFT)) - trim_index++; - - if (trim_index<0) - trim_index = 0; - if (trim_index>10) - trim_index = 10; -#ifdef FUZZING - trim_index = rand()%11; -#endif - return trim_index; -} - -static int stereo_analysis(const CELTMode *m, const celt_norm *X, - int LM, int N0) -{ - int i; - int thetas; - opus_val32 sumLR = EPSILON, sumMS = EPSILON; - - /* Use the L1 norm to model the entropy of the L/R signal vs the M/S signal */ - for (i=0;i<13;i++) - { - int j; - for (j=m->eBands[i]<eBands[i+1]<eBands[13]<<(LM+1))+thetas, sumMS) - > MULT16_32_Q15(m->eBands[13]<<(LM+1), sumLR); -} - -int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc) -{ - int i, c, N; - opus_int32 bits; - ec_enc _enc; - VARDECL(celt_sig, in); - VARDECL(celt_sig, freq); - VARDECL(celt_norm, X); - VARDECL(celt_ener, bandE); - VARDECL(opus_val16, bandLogE); - VARDECL(int, fine_quant); - VARDECL(opus_val16, error); - VARDECL(int, pulses); - VARDECL(int, cap); - VARDECL(int, offsets); - VARDECL(int, fine_priority); - VARDECL(int, tf_res); - VARDECL(unsigned char, collapse_masks); - celt_sig *prefilter_mem; - opus_val16 *oldBandE, *oldLogE, *oldLogE2; - int shortBlocks=0; - int isTransient=0; - const int CC = st->channels; - const int C = st->stream_channels; - int LM, M; - int tf_select; - int nbFilledBytes, nbAvailableBytes; - int effEnd; - int codedBands; - int tf_sum; - int alloc_trim; - int pitch_index=COMBFILTER_MINPERIOD; - opus_val16 gain1 = 0; - int intensity=0; - int dual_stereo=0; - int effectiveBytes; - opus_val16 pf_threshold; - int dynalloc_logp; - opus_int32 vbr_rate; - opus_int32 total_bits; - opus_int32 total_boost; - opus_int32 balance; - opus_int32 tell; - int prefilter_tapset=0; - int pf_on; - int anti_collapse_rsv; - int anti_collapse_on=0; - int silence=0; - ALLOC_STACK; - - if (nbCompressedBytes<2 || pcm==NULL) - return OPUS_BAD_ARG; - - frame_size *= st->upsample; - for (LM=0;LM<=st->mode->maxLM;LM++) - if (st->mode->shortMdctSize<st->mode->maxLM) - return OPUS_BAD_ARG; - M=1<mode->shortMdctSize; - - prefilter_mem = st->in_mem+CC*(st->overlap); - oldBandE = (opus_val16*)(st->in_mem+CC*(st->overlap+COMBFILTER_MAXPERIOD)); - oldLogE = oldBandE + CC*st->mode->nbEBands; - oldLogE2 = oldLogE + CC*st->mode->nbEBands; - - if (enc==NULL) - { - tell=1; - nbFilledBytes=0; - } else { - tell=ec_tell(enc); - nbFilledBytes=(tell+4)>>3; - } - -#ifdef CUSTOM_MODES - if (st->signalling && enc==NULL) - { - int tmp = (st->mode->effEBands-st->end)>>1; - st->end = IMAX(1, st->mode->effEBands-tmp); - compressed[0] = tmp<<5; - compressed[0] |= LM<<3; - compressed[0] |= (C==2)<<2; - /* Convert "standard mode" to Opus header */ - if (st->mode->Fs==48000 && st->mode->shortMdctSize==120) - { - int c0 = toOpus(compressed[0]); - if (c0<0) - return OPUS_BAD_ARG; - compressed[0] = c0; - } - compressed++; - nbCompressedBytes--; - } -#else - celt_assert(st->signalling==0); -#endif - - /* Can't produce more than 1275 output bytes */ - nbCompressedBytes = IMIN(nbCompressedBytes,1275); - nbAvailableBytes = nbCompressedBytes - nbFilledBytes; - - if (st->vbr && st->bitrate!=OPUS_BITRATE_MAX) - { - opus_int32 den=st->mode->Fs>>BITRES; - vbr_rate=(st->bitrate*frame_size+(den>>1))/den; -#ifdef CUSTOM_MODES - if (st->signalling) - vbr_rate -= 8<>(3+BITRES); - } else { - opus_int32 tmp; - vbr_rate = 0; - tmp = st->bitrate*frame_size; - if (tell>1) - tmp += tell; - if (st->bitrate!=OPUS_BITRATE_MAX) - nbCompressedBytes = IMAX(2, IMIN(nbCompressedBytes, - (tmp+4*st->mode->Fs)/(8*st->mode->Fs)-!!st->signalling)); - effectiveBytes = nbCompressedBytes; - } - - if (enc==NULL) - { - ec_enc_init(&_enc, compressed, nbCompressedBytes); - enc = &_enc; - } - - if (vbr_rate>0) - { - /* Computes the max bit-rate allowed in VBR mode to avoid violating the - target rate and buffering. - We must do this up front so that bust-prevention logic triggers - correctly if we don't have enough bits. */ - if (st->constrained_vbr) - { - opus_int32 vbr_bound; - opus_int32 max_allowed; - /* We could use any multiple of vbr_rate as bound (depending on the - delay). - This is clamped to ensure we use at least two bytes if the encoder - was entirely empty, but to allow 0 in hybrid mode. */ - vbr_bound = vbr_rate; - max_allowed = IMIN(IMAX(tell==1?2:0, - (vbr_rate+vbr_bound-st->vbr_reservoir)>>(BITRES+3)), - nbAvailableBytes); - if(max_allowed < nbAvailableBytes) - { - nbCompressedBytes = nbFilledBytes+max_allowed; - nbAvailableBytes = max_allowed; - ec_enc_shrink(enc, nbCompressedBytes); - } - } - } - total_bits = nbCompressedBytes*8; - - effEnd = st->end; - if (effEnd > st->mode->effEBands) - effEnd = st->mode->effEBands; - - ALLOC(in, CC*(N+st->overlap), celt_sig); - - /* Find pitch period and gain */ - { - VARDECL(celt_sig, _pre); - celt_sig *pre[2]; - SAVE_STACK; - ALLOC(_pre, CC*(N+COMBFILTER_MAXPERIOD), celt_sig); - - pre[0] = _pre; - pre[1] = _pre + (N+COMBFILTER_MAXPERIOD); - - silence = 1; - c=0; do { - int count = 0; - const opus_val16 * OPUS_RESTRICT pcmp = pcm+c; - celt_sig * OPUS_RESTRICT inp = in+c*(N+st->overlap)+st->overlap; - - for (i=0;iclip) - x = MAX32(-65536.f, MIN32(65536.f,x)); -#endif - if (++count==st->upsample) - { - count=0; - pcmp+=CC; - } else { - x = 0; - } - /* Apply pre-emphasis */ - tmp = MULT16_16(st->mode->preemph[2], x); - *inp = tmp + st->preemph_memE[c]; - st->preemph_memE[c] = MULT16_32_Q15(st->mode->preemph[1], *inp) - - MULT16_32_Q15(st->mode->preemph[0], tmp); - silence = silence && *inp == 0; - inp++; - } - OPUS_COPY(pre[c], prefilter_mem+c*COMBFILTER_MAXPERIOD, COMBFILTER_MAXPERIOD); - OPUS_COPY(pre[c]+COMBFILTER_MAXPERIOD, in+c*(N+st->overlap)+st->overlap, N); - } while (++c0) - { - effectiveBytes=nbCompressedBytes=IMIN(nbCompressedBytes, nbFilledBytes+2); - total_bits=nbCompressedBytes*8; - nbAvailableBytes=2; - ec_enc_shrink(enc, nbCompressedBytes); - } - /* Pretend we've filled all the remaining bits with zeros - (that's what the initialiser did anyway) */ - tell = nbCompressedBytes*8; - enc->nbits_total+=tell-ec_tell(enc); - } - if (nbAvailableBytes>12*C && st->start==0 && !silence && !st->disable_pf && st->complexity >= 5) - { - VARDECL(opus_val16, pitch_buf); - ALLOC(pitch_buf, (COMBFILTER_MAXPERIOD+N)>>1, opus_val16); - - pitch_downsample(pre, pitch_buf, COMBFILTER_MAXPERIOD+N, CC); - pitch_search(pitch_buf+(COMBFILTER_MAXPERIOD>>1), pitch_buf, N, - COMBFILTER_MAXPERIOD-COMBFILTER_MINPERIOD, &pitch_index); - pitch_index = COMBFILTER_MAXPERIOD-pitch_index; - - gain1 = remove_doubling(pitch_buf, COMBFILTER_MAXPERIOD, COMBFILTER_MINPERIOD, - N, &pitch_index, st->prefilter_period, st->prefilter_gain); - if (pitch_index > COMBFILTER_MAXPERIOD-2) - pitch_index = COMBFILTER_MAXPERIOD-2; - gain1 = MULT16_16_Q15(QCONST16(.7f,15),gain1); - if (st->loss_rate>2) - gain1 = HALF32(gain1); - if (st->loss_rate>4) - gain1 = HALF32(gain1); - if (st->loss_rate>8) - gain1 = 0; - prefilter_tapset = st->tapset_decision; - } else { - gain1 = 0; - } - - /* Gain threshold for enabling the prefilter/postfilter */ - pf_threshold = QCONST16(.2f,15); - - /* Adjusting the threshold based on rate and continuity */ - if (abs(pitch_index-st->prefilter_period)*10>pitch_index) - pf_threshold += QCONST16(.2f,15); - if (nbAvailableBytes<25) - pf_threshold += QCONST16(.1f,15); - if (nbAvailableBytes<35) - pf_threshold += QCONST16(.1f,15); - if (st->prefilter_gain > QCONST16(.4f,15)) - pf_threshold -= QCONST16(.1f,15); - if (st->prefilter_gain > QCONST16(.55f,15)) - pf_threshold -= QCONST16(.1f,15); - - /* Hard threshold at 0.2 */ - pf_threshold = MAX16(pf_threshold, QCONST16(.2f,15)); - if (gain1start==0 && tell+16<=total_bits) - ec_enc_bit_logp(enc, 0, 1); - gain1 = 0; - pf_on = 0; - } else { - /*This block is not gated by a total bits check only because - of the nbAvailableBytes check above.*/ - int qg; - int octave; - - if (ABS16(gain1-st->prefilter_gain)prefilter_gain; - -#ifdef FIXED_POINT - qg = ((gain1+1536)>>10)/3-1; -#else - qg = (int)floor(.5f+gain1*32/3)-1; -#endif - qg = IMAX(0, IMIN(7, qg)); - ec_enc_bit_logp(enc, 1, 1); - pitch_index += 1; - octave = EC_ILOG(pitch_index)-5; - ec_enc_uint(enc, octave, 6); - ec_enc_bits(enc, pitch_index-(16<mode->shortMdctSize-st->mode->overlap; - st->prefilter_period=IMAX(st->prefilter_period, COMBFILTER_MINPERIOD); - OPUS_COPY(in+c*(N+st->overlap), st->in_mem+c*(st->overlap), st->overlap); - if (offset) - comb_filter(in+c*(N+st->overlap)+st->overlap, pre[c]+COMBFILTER_MAXPERIOD, - st->prefilter_period, st->prefilter_period, offset, -st->prefilter_gain, -st->prefilter_gain, - st->prefilter_tapset, st->prefilter_tapset, NULL, 0); - - comb_filter(in+c*(N+st->overlap)+st->overlap+offset, pre[c]+COMBFILTER_MAXPERIOD+offset, - st->prefilter_period, pitch_index, N-offset, -st->prefilter_gain, -gain1, - st->prefilter_tapset, prefilter_tapset, st->mode->window, st->mode->overlap); - OPUS_COPY(st->in_mem+c*(st->overlap), in+c*(N+st->overlap)+N, st->overlap); - - if (N>COMBFILTER_MAXPERIOD) - { - OPUS_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD, pre[c]+N, COMBFILTER_MAXPERIOD); - } else { - OPUS_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD, prefilter_mem+c*COMBFILTER_MAXPERIOD+N, COMBFILTER_MAXPERIOD-N); - OPUS_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD+COMBFILTER_MAXPERIOD-N, pre[c]+COMBFILTER_MAXPERIOD, N); - } - } while (++c0 && ec_tell(enc)+3<=total_bits) - { - if (st->complexity > 1) - { - isTransient = transient_analysis(in, N+st->overlap, CC, - st->overlap); - if (isTransient) - shortBlocks = M; - } - ec_enc_bit_logp(enc, isTransient, 3); - } - - ALLOC(freq, CC*N, celt_sig); /**< Interleaved signal MDCTs */ - ALLOC(bandE,st->mode->nbEBands*CC, celt_ener); - ALLOC(bandLogE,st->mode->nbEBands*CC, opus_val16); - /* Compute MDCTs */ - compute_mdcts(st->mode, shortBlocks, in, freq, CC, LM); - - if (CC==2&&C==1) - { - for (i=0;iupsample != 1) - { - c=0; do - { - int bound = N/st->upsample; - for (i=0;iupsample; - for (;imode, freq, bandE, effEnd, C, M); - - amp2Log2(st->mode, effEnd, st->end, bandE, bandLogE, C); - - /* Band normalisation */ - normalise_bands(st->mode, freq, X, bandE, effEnd, C, M); - - ALLOC(tf_res, st->mode->nbEBands, int); - tf_select = tf_analysis(st->mode, effEnd, C, isTransient, tf_res, effectiveBytes, X, N, LM, st->start, &tf_sum); - for (i=effEnd;iend;i++) - tf_res[i] = tf_res[effEnd-1]; - - ALLOC(error, C*st->mode->nbEBands, opus_val16); - quant_coarse_energy(st->mode, st->start, st->end, effEnd, bandLogE, - oldBandE, total_bits, error, enc, - C, LM, nbAvailableBytes, st->force_intra, - &st->delayedIntra, st->complexity >= 4, st->loss_rate); - - tf_encode(st->start, st->end, isTransient, tf_res, LM, tf_select, enc); - - if (ec_tell(enc)+4<=total_bits) - { - if (shortBlocks || st->complexity < 3 - || nbAvailableBytes < 10*C || st->start!=0) - { - if (st->complexity == 0) - st->spread_decision = SPREAD_NONE; - else - st->spread_decision = SPREAD_NORMAL; - } else { - st->spread_decision = spreading_decision(st->mode, X, - &st->tonal_average, st->spread_decision, &st->hf_average, - &st->tapset_decision, pf_on&&!shortBlocks, effEnd, C, M); - } - ec_enc_icdf(enc, st->spread_decision, spread_icdf, 5); - } - - ALLOC(cap, st->mode->nbEBands, int); - ALLOC(offsets, st->mode->nbEBands, int); - - init_caps(st->mode,cap,LM,C); - for (i=0;imode->nbEBands;i++) - offsets[i] = 0; - /* Dynamic allocation code */ - /* Make sure that dynamic allocation can't make us bust the budget */ - if (effectiveBytes > 50 && LM>=1) - { - int t1, t2; - if (LM <= 1) - { - t1 = 3; - t2 = 5; - } else { - t1 = 2; - t2 = 4; - } - for (i=st->start+1;iend-1;i++) - { - opus_val32 d2; - d2 = 2*bandLogE[i]-bandLogE[i-1]-bandLogE[i+1]; - if (C==2) - d2 = HALF32(d2 + 2*bandLogE[i+st->mode->nbEBands]- - bandLogE[i-1+st->mode->nbEBands]-bandLogE[i+1+st->mode->nbEBands]); -#ifdef FUZZING - if((rand()&0xF)==0) - { - offsets[i] += 1; - if((rand()&0x3)==0) - offsets[i] += 1+(rand()&0x3); - } -#else - if (d2 > SHL16(t1,DB_SHIFT)) - offsets[i] += 1; - if (d2 > SHL16(t2,DB_SHIFT)) - offsets[i] += 1; -#endif - } - } - dynalloc_logp = 6; - total_bits<<=BITRES; - total_boost = 0; - tell = ec_tell_frac(enc); - for (i=st->start;iend;i++) - { - int width, quanta; - int dynalloc_loop_logp; - int boost; - int j; - width = C*(st->mode->eBands[i+1]-st->mode->eBands[i])<mode, X, bandLogE, - st->end, LM, C, N); - ec_enc_icdf(enc, alloc_trim, trim_icdf, 7); - tell = ec_tell_frac(enc); - } - - /* Variable bitrate */ - if (vbr_rate>0) - { - opus_val16 alpha; - opus_int32 delta; - /* The target rate in 8th bits per frame */ - opus_int32 target; - opus_int32 min_allowed; - int lm_diff = st->mode->maxLM - LM; - - /* Don't attempt to use more than 510 kb/s, even for frames smaller than 20 ms. - The CELT allocator will just not be able to use more than that anyway. */ - nbCompressedBytes = IMIN(nbCompressedBytes,1275>>(3-LM)); - target = vbr_rate + (st->vbr_offset>>lm_diff) - ((40*C+20)<end-st->start)) - target = 7*target/4; - else if (tf_sum < -(st->end-st->start)) - target = 3*target/2; - else if (M > 1) - target-=(target+14)/28; - - /* The current offset is removed from the target and the space used - so far is added*/ - target=target+tell; - - /* In VBR mode the frame size must not be reduced so much that it would - result in the encoder running out of bits. - The margin of 2 bytes ensures that none of the bust-prevention logic - in the decoder will have triggered so far. */ - min_allowed = ((tell+total_boost+(1<<(BITRES+3))-1)>>(BITRES+3)) + 2 - nbFilledBytes; - - nbAvailableBytes = (target+(1<<(BITRES+2)))>>(BITRES+3); - nbAvailableBytes = IMAX(min_allowed,nbAvailableBytes); - nbAvailableBytes = IMIN(nbCompressedBytes,nbAvailableBytes+nbFilledBytes) - nbFilledBytes; - - /* By how much did we "miss" the target on that frame */ - delta = target - vbr_rate; - - target=nbAvailableBytes<<(BITRES+3); - - /*If the frame is silent we don't adjust our drift, otherwise - the encoder will shoot to very high rates after hitting a - span of silence, but we do allow the bitres to refill. - This means that we'll undershoot our target in CVBR/VBR modes - on files with lots of silence. */ - if(silence) - { - nbAvailableBytes = 2; - target = 2*8<vbr_count < 970) - { - st->vbr_count++; - alpha = celt_rcp(SHL32(EXTEND32(st->vbr_count+20),16)); - } else - alpha = QCONST16(.001f,15); - /* How many bits have we used in excess of what we're allowed */ - if (st->constrained_vbr) - st->vbr_reservoir += target - vbr_rate; - /*printf ("%d\n", st->vbr_reservoir);*/ - - /* Compute the offset we need to apply in order to reach the target */ - st->vbr_drift += (opus_int32)MULT16_32_Q15(alpha,(delta*(1<vbr_offset-st->vbr_drift); - st->vbr_offset = -st->vbr_drift; - /*printf ("%d\n", st->vbr_drift);*/ - - if (st->constrained_vbr && st->vbr_reservoir < 0) - { - /* We're under the min value -- increase rate */ - int adjust = (-st->vbr_reservoir)/(8<vbr_reservoir = 0; - /*printf ("+%d\n", adjust);*/ - } - nbCompressedBytes = IMIN(nbCompressedBytes,nbAvailableBytes+nbFilledBytes); - /* This moves the raw bits to take into account the new compressed size */ - ec_enc_shrink(enc, nbCompressedBytes); - } - if (C==2) - { - int effectiveRate; - - /* Always use MS for 2.5 ms frames until we can do a better analysis */ - if (LM!=0) - dual_stereo = stereo_analysis(st->mode, X, LM, N); - - /* Account for coarse energy */ - effectiveRate = (8*effectiveBytes - 80)>>LM; - - /* effectiveRate in kb/s */ - effectiveRate = 2*effectiveRate/5; - if (effectiveRate<35) - intensity = 8; - else if (effectiveRate<50) - intensity = 12; - else if (effectiveRate<68) - intensity = 16; - else if (effectiveRate<84) - intensity = 18; - else if (effectiveRate<102) - intensity = 19; - else if (effectiveRate<130) - intensity = 20; - else - intensity = 100; - intensity = IMIN(st->end,IMAX(st->start, intensity)); - } - - /* Bit allocation */ - ALLOC(fine_quant, st->mode->nbEBands, int); - ALLOC(pulses, st->mode->nbEBands, int); - ALLOC(fine_priority, st->mode->nbEBands, int); - - /* bits = packet size - where we are - safety*/ - bits = (((opus_int32)nbCompressedBytes*8)<=2&&bits>=((LM+2)<mode, st->start, st->end, offsets, cap, - alloc_trim, &intensity, &dual_stereo, bits, &balance, pulses, - fine_quant, fine_priority, C, LM, enc, 1, st->lastCodedBands); - st->lastCodedBands = codedBands; - - quant_fine_energy(st->mode, st->start, st->end, oldBandE, error, fine_quant, enc, C); - -#ifdef MEASURE_NORM_MSE - float X0[3000]; - float bandE0[60]; - c=0; do - for (i=0;imode->nbEBands;i++) - bandE0[i] = bandE[i]; -#endif - - /* Residual quantisation */ - ALLOC(collapse_masks, C*st->mode->nbEBands, unsigned char); - quant_all_bands(1, st->mode, st->start, st->end, X, C==2 ? X+N : NULL, collapse_masks, - bandE, pulses, shortBlocks, st->spread_decision, dual_stereo, intensity, tf_res, - nbCompressedBytes*(8<rng); - - if (anti_collapse_rsv > 0) - { - anti_collapse_on = st->consec_transient<2; -#ifdef FUZZING - anti_collapse_on = rand()&0x1; -#endif - ec_enc_bits(enc, anti_collapse_on, 1); - } - quant_energy_finalise(st->mode, st->start, st->end, oldBandE, error, fine_quant, fine_priority, nbCompressedBytes*8-ec_tell(enc), enc, C); - - if (silence) - { - for (i=0;imode->nbEBands;i++) - oldBandE[i] = -QCONST16(28.f,DB_SHIFT); - } - -#ifdef RESYNTH - /* Re-synthesis of the coded audio if required */ - { - celt_sig *out_mem[2]; - celt_sig *overlap_mem[2]; - - log2Amp(st->mode, st->start, st->end, bandE, oldBandE, C); - if (silence) - { - for (i=0;imode->nbEBands;i++) - bandE[i] = 0; - } - -#ifdef MEASURE_NORM_MSE - measure_norm_mse(st->mode, X, X0, bandE, bandE0, M, N, C); -#endif - if (anti_collapse_on) - { - anti_collapse(st->mode, X, collapse_masks, LM, C, N, - st->start, st->end, oldBandE, oldLogE, oldLogE2, pulses, st->rng); - } - - /* Synthesis */ - denormalise_bands(st->mode, X, freq, bandE, effEnd, C, M); - - OPUS_MOVE(st->syn_mem[0], st->syn_mem[0]+N, MAX_PERIOD); - if (CC==2) - OPUS_MOVE(st->syn_mem[1], st->syn_mem[1]+N, MAX_PERIOD); - - c=0; do - for (i=0;imode->eBands[st->start];i++) - freq[c*N+i] = 0; - while (++cmode->eBands[st->end];isyn_mem[0]+MAX_PERIOD; - if (CC==2) - out_mem[1] = st->syn_mem[1]+MAX_PERIOD; - - overlap_mem[0] = (celt_sig*)(oldLogE2 + CC*st->mode->nbEBands); - if (CC==2) - overlap_mem[1] = overlap_mem[0] + st->overlap; - - compute_inv_mdcts(st->mode, shortBlocks, freq, out_mem, overlap_mem, CC, LM); - - c=0; do { - st->prefilter_period=IMAX(st->prefilter_period, COMBFILTER_MINPERIOD); - st->prefilter_period_old=IMAX(st->prefilter_period_old, COMBFILTER_MINPERIOD); - comb_filter(out_mem[c], out_mem[c], st->prefilter_period_old, st->prefilter_period, st->mode->shortMdctSize, - st->prefilter_gain_old, st->prefilter_gain, st->prefilter_tapset_old, st->prefilter_tapset, - st->mode->window, st->overlap); - if (LM!=0) - comb_filter(out_mem[c]+st->mode->shortMdctSize, out_mem[c]+st->mode->shortMdctSize, st->prefilter_period, pitch_index, N-st->mode->shortMdctSize, - st->prefilter_gain, gain1, st->prefilter_tapset, prefilter_tapset, - st->mode->window, st->mode->overlap); - } while (++cupsample, st->mode->preemph, st->preemph_memD); - st->prefilter_period_old = st->prefilter_period; - st->prefilter_gain_old = st->prefilter_gain; - st->prefilter_tapset_old = st->prefilter_tapset; - } -#endif - - st->prefilter_period = pitch_index; - st->prefilter_gain = gain1; - st->prefilter_tapset = prefilter_tapset; -#ifdef RESYNTH - if (LM!=0) - { - st->prefilter_period_old = st->prefilter_period; - st->prefilter_gain_old = st->prefilter_gain; - st->prefilter_tapset_old = st->prefilter_tapset; - } -#endif - - if (CC==2&&C==1) { - for (i=0;imode->nbEBands;i++) - oldBandE[st->mode->nbEBands+i]=oldBandE[i]; - } - - if (!isTransient) - { - for (i=0;imode->nbEBands;i++) - oldLogE2[i] = oldLogE[i]; - for (i=0;imode->nbEBands;i++) - oldLogE[i] = oldBandE[i]; - } else { - for (i=0;imode->nbEBands;i++) - oldLogE[i] = MIN16(oldLogE[i], oldBandE[i]); - } - /* In case start or end were to change */ - c=0; do - { - for (i=0;istart;i++) - { - oldBandE[c*st->mode->nbEBands+i]=0; - oldLogE[c*st->mode->nbEBands+i]=oldLogE2[c*st->mode->nbEBands+i]=-QCONST16(28.f,DB_SHIFT); - } - for (i=st->end;imode->nbEBands;i++) - { - oldBandE[c*st->mode->nbEBands+i]=0; - oldLogE[c*st->mode->nbEBands+i]=oldLogE2[c*st->mode->nbEBands+i]=-QCONST16(28.f,DB_SHIFT); - } - } while (++cconsec_transient++; - else - st->consec_transient=0; - st->rng = enc->rng; - - /* If there's any room left (can only happen for very high rates), - it's already filled with zeros */ - ec_enc_done(enc); - -#ifdef CUSTOM_MODES - if (st->signalling) - nbCompressedBytes++; -#endif - - RESTORE_STACK; - if (ec_get_error(enc)) - return OPUS_INTERNAL_ERROR; - else - return nbCompressedBytes; -} - - -#ifdef CUSTOM_MODES - -#ifdef FIXED_POINT -int opus_custom_encode(CELTEncoder * OPUS_RESTRICT st, const opus_int16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes) -{ - return celt_encode_with_ec(st, pcm, frame_size, compressed, nbCompressedBytes, NULL); -} - -#ifndef DISABLE_FLOAT_API -int opus_custom_encode_float(CELTEncoder * OPUS_RESTRICT st, const float * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes) -{ - int j, ret, C, N; - VARDECL(opus_int16, in); - ALLOC_STACK; - - if (pcm==NULL) - return OPUS_BAD_ARG; - - C = st->channels; - N = frame_size; - ALLOC(in, C*N, opus_int16); - - for (j=0;jchannels; - N=frame_size; - ALLOC(in, C*N, celt_sig); - for (j=0;j10) - goto bad_arg; - st->complexity = value; - } - break; - case CELT_SET_START_BAND_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if (value<0 || value>=st->mode->nbEBands) - goto bad_arg; - st->start = value; - } - break; - case CELT_SET_END_BAND_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if (value<1 || value>st->mode->nbEBands) - goto bad_arg; - st->end = value; - } - break; - case CELT_SET_PREDICTION_REQUEST: - { - int value = va_arg(ap, opus_int32); - if (value<0 || value>2) - goto bad_arg; - st->disable_pf = value<=1; - st->force_intra = value==0; - } - break; - case OPUS_SET_PACKET_LOSS_PERC_REQUEST: - { - int value = va_arg(ap, opus_int32); - if (value<0 || value>100) - goto bad_arg; - st->loss_rate = value; - } - break; - case OPUS_SET_VBR_CONSTRAINT_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - st->constrained_vbr = value; - } - break; - case OPUS_SET_VBR_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - st->vbr = value; - } - break; - case OPUS_SET_BITRATE_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if (value<=500 && value!=OPUS_BITRATE_MAX) - goto bad_arg; - value = IMIN(value, 260000*st->channels); - st->bitrate = value; - } - break; - case CELT_SET_CHANNELS_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if (value<1 || value>2) - goto bad_arg; - st->stream_channels = value; - } - break; - case OPUS_SET_LSB_DEPTH_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if (value<8 || value>24) - goto bad_arg; - st->lsb_depth=value; - } - break; - case OPUS_GET_LSB_DEPTH_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - *value=st->lsb_depth; - } - break; - case OPUS_RESET_STATE: - { - int i; - opus_val16 *oldBandE, *oldLogE, *oldLogE2; - oldBandE = (opus_val16*)(st->in_mem+st->channels*(st->overlap+COMBFILTER_MAXPERIOD)); - oldLogE = oldBandE + st->channels*st->mode->nbEBands; - oldLogE2 = oldLogE + st->channels*st->mode->nbEBands; - OPUS_CLEAR((char*)&st->ENCODER_RESET_START, - opus_custom_encoder_get_size(st->mode, st->channels)- - ((char*)&st->ENCODER_RESET_START - (char*)st)); - for (i=0;ichannels*st->mode->nbEBands;i++) - oldLogE[i]=oldLogE2[i]=-QCONST16(28.f,DB_SHIFT); - st->vbr_offset = 0; - st->delayedIntra = 1; - st->spread_decision = SPREAD_NORMAL; - st->tonal_average = 256; - st->hf_average = 0; - st->tapset_decision = 0; - } - break; -#ifdef CUSTOM_MODES - case CELT_SET_INPUT_CLIPPING_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - st->clip = value; - } - break; -#endif - case CELT_SET_SIGNALLING_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - st->signalling = value; - } - break; - case CELT_GET_MODE_REQUEST: - { - const CELTMode ** value = va_arg(ap, const CELTMode**); - if (value==0) - goto bad_arg; - *value=st->mode; - } - break; - case OPUS_GET_FINAL_RANGE_REQUEST: - { - opus_uint32 * value = va_arg(ap, opus_uint32 *); - if (value==0) - goto bad_arg; - *value=st->rng; - } - break; - default: - goto bad_request; - } - va_end(ap); - return OPUS_OK; -bad_arg: - va_end(ap); - return OPUS_BAD_ARG; -bad_request: - va_end(ap); - return OPUS_UNIMPLEMENTED; -} - -/**********************************************************************/ -/* */ -/* DECODER */ -/* */ -/**********************************************************************/ -#define DECODE_BUFFER_SIZE 2048 - -/** Decoder state - @brief Decoder state - */ -struct OpusCustomDecoder { - const OpusCustomMode *mode; - int overlap; - int channels; - int stream_channels; - - int downsample; - int start, end; - int signalling; - - /* Everything beyond this point gets cleared on a reset */ -#define DECODER_RESET_START rng - - opus_uint32 rng; - int error; - int last_pitch_index; - int loss_count; - int postfilter_period; - int postfilter_period_old; - opus_val16 postfilter_gain; - opus_val16 postfilter_gain_old; - int postfilter_tapset; - int postfilter_tapset_old; - - celt_sig preemph_memD[2]; - - celt_sig _decode_mem[1]; /* Size = channels*(DECODE_BUFFER_SIZE+mode->overlap) */ - /* opus_val16 lpc[], Size = channels*LPC_ORDER */ - /* opus_val16 oldEBands[], Size = 2*mode->nbEBands */ - /* opus_val16 oldLogE[], Size = 2*mode->nbEBands */ - /* opus_val16 oldLogE2[], Size = 2*mode->nbEBands */ - /* opus_val16 backgroundLogE[], Size = 2*mode->nbEBands */ -}; - -int celt_decoder_get_size(int channels) -{ - const CELTMode *mode = opus_custom_mode_create(48000, 960, NULL); - return opus_custom_decoder_get_size(mode, channels); -} - -OPUS_CUSTOM_NOSTATIC int opus_custom_decoder_get_size(const CELTMode *mode, int channels) -{ - int size = sizeof(struct CELTDecoder) - + (channels*(DECODE_BUFFER_SIZE+mode->overlap)-1)*sizeof(celt_sig) - + channels*LPC_ORDER*sizeof(opus_val16) - + 4*2*mode->nbEBands*sizeof(opus_val16); - return size; -} - -#ifdef CUSTOM_MODES -CELTDecoder *opus_custom_decoder_create(const CELTMode *mode, int channels, int *error) -{ - int ret; - CELTDecoder *st = (CELTDecoder *)opus_alloc(opus_custom_decoder_get_size(mode, channels)); - ret = opus_custom_decoder_init(st, mode, channels); - if (ret != OPUS_OK) - { - opus_custom_decoder_destroy(st); - st = NULL; - } - if (error) - *error = ret; - return st; -} -#endif /* CUSTOM_MODES */ - -int celt_decoder_init(CELTDecoder *st, opus_int32 sampling_rate, int channels) -{ - int ret; - ret = opus_custom_decoder_init(st, opus_custom_mode_create(48000, 960, NULL), channels); - if (ret != OPUS_OK) - return ret; - st->downsample = resampling_factor(sampling_rate); - if (st->downsample==0) - return OPUS_BAD_ARG; - else - return OPUS_OK; -} - -OPUS_CUSTOM_NOSTATIC int opus_custom_decoder_init(CELTDecoder *st, const CELTMode *mode, int channels) -{ - if (channels < 0 || channels > 2) - return OPUS_BAD_ARG; - - if (st==NULL) - return OPUS_ALLOC_FAIL; - - OPUS_CLEAR((char*)st, opus_custom_decoder_get_size(mode, channels)); - - st->mode = mode; - st->overlap = mode->overlap; - st->stream_channels = st->channels = channels; - - st->downsample = 1; - st->start = 0; - st->end = st->mode->effEBands; - st->signalling = 1; - - st->loss_count = 0; - - opus_custom_decoder_ctl(st, OPUS_RESET_STATE); - - return OPUS_OK; -} - -#ifdef CUSTOM_MODES -void opus_custom_decoder_destroy(CELTDecoder *st) -{ - opus_free(st); -} -#endif /* CUSTOM_MODES */ - -static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, opus_val16 * OPUS_RESTRICT pcm, int N, int LM) -{ - int c; - int pitch_index; - opus_val16 fade = Q15ONE; - int i, len; - const int C = st->channels; - int offset; - celt_sig *out_mem[2]; - celt_sig *decode_mem[2]; - celt_sig *overlap_mem[2]; - opus_val16 *lpc; - opus_val32 *out_syn[2]; - opus_val16 *oldBandE, *oldLogE, *oldLogE2, *backgroundLogE; - const OpusCustomMode *mode; - int nbEBands; - int overlap; - const opus_int16 *eBands; - SAVE_STACK; - - mode = st->mode; - nbEBands = mode->nbEBands; - overlap = mode->overlap; - eBands = mode->eBands; - - c=0; do { - decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+st->overlap); - out_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE-MAX_PERIOD; - overlap_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE; - } while (++c_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*C); - oldBandE = lpc+C*LPC_ORDER; - oldLogE = oldBandE + 2*nbEBands; - oldLogE2 = oldLogE + 2*nbEBands; - backgroundLogE = oldLogE2 + 2*nbEBands; - - c=0; do { - out_syn[c] = out_mem[c]+MAX_PERIOD-N; - } while (++closs_count >= 5 || st->start!=0) - { - /* Noise-based PLC/CNG */ - VARDECL(celt_sig, freq); - VARDECL(celt_norm, X); - VARDECL(celt_ener, bandE); - opus_uint32 seed; - int effEnd; - - effEnd = st->end; - if (effEnd > mode->effEBands) - effEnd = mode->effEBands; - - ALLOC(freq, C*N, celt_sig); /**< Interleaved signal MDCTs */ - ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */ - ALLOC(bandE, nbEBands*C, celt_ener); - - if (st->loss_count >= 5) - log2Amp(mode, st->start, st->end, bandE, backgroundLogE, C); - else { - /* Energy decay */ - opus_val16 decay = st->loss_count==0 ? QCONST16(1.5f, DB_SHIFT) : QCONST16(.5f, DB_SHIFT); - c=0; do - { - for (i=st->start;iend;i++) - oldBandE[c*nbEBands+i] -= decay; - } while (++cstart, st->end, bandE, oldBandE, C); - } - seed = st->rng; - for (c=0;cmode->eBands[st->start]<start;ieffEBands;i++) - { - int j; - int boffs; - int blen; - boffs = N*c+(eBands[i]<>20); - } - renormalise_vector(X+boffs, blen, Q15ONE); - } - for (i=(st->mode->eBands[st->end]<rng = seed; - - denormalise_bands(mode, X, freq, bandE, mode->effEBands, C, 1<mode->eBands[st->start]<downsample!=1) - bound = IMIN(bound, N/st->downsample); - for (i=bound;iloss_count == 0) - { - opus_val16 pitch_buf[DECODE_BUFFER_SIZE>>1]; - /* Corresponds to a min pitch of 67 Hz. It's possible to save CPU in this - search by using only part of the decode buffer */ - int poffset = 720; - pitch_downsample(decode_mem, pitch_buf, DECODE_BUFFER_SIZE, C); - /* Max pitch is 100 samples (480 Hz) */ - pitch_search(pitch_buf+((poffset)>>1), pitch_buf, DECODE_BUFFER_SIZE-poffset, - poffset-100, &pitch_index); - pitch_index = poffset-pitch_index; - st->last_pitch_index = pitch_index; - } else { - pitch_index = st->last_pitch_index; - fade = QCONST16(.8f,15); - } - - ALLOC(etmp, overlap, opus_val32); - c=0; do { - opus_val16 exc[MAX_PERIOD]; - opus_val32 ac[LPC_ORDER+1]; - opus_val16 decay; - opus_val16 attenuation; - opus_val32 S1=0; - opus_val16 mem[LPC_ORDER]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - opus_val32 *e = out_syn[c]; - - - offset = MAX_PERIOD-pitch_index; - for (i=0;iloss_count == 0) - { - _celt_autocorr(exc, ac, mode->window, overlap, - LPC_ORDER, MAX_PERIOD); - - /* Noise floor -40 dB */ -#ifdef FIXED_POINT - ac[0] += SHR32(ac[0],13); -#else - ac[0] *= 1.0001f; -#endif - /* Lag windowing */ - for (i=1;i<=LPC_ORDER;i++) - { - /*ac[i] *= exp(-.5*(2*M_PI*.002*i)*(2*M_PI*.002*i));*/ -#ifdef FIXED_POINT - ac[i] -= MULT16_32_Q15(2*i*i, ac[i]); -#else - ac[i] -= ac[i]*(.008f*i)*(.008f*i); -#endif - } - - _celt_lpc(lpc+c*LPC_ORDER, ac, LPC_ORDER); - } - /* Samples just before the beginning of exc */ - for (i=0;i E2) - E1 = E2; - decay = celt_sqrt(frac_div32(SHR32(E1,1),E2)); - attenuation = decay; - } - - /* Move memory one frame to the left */ - OPUS_MOVE(decode_mem[c], decode_mem[c]+N, DECODE_BUFFER_SIZE-N+overlap); - - /* Extrapolate excitation with the right period, taking decay into account */ - for (i=0;i= MAX_PERIOD) - { - offset -= pitch_index; - attenuation = MULT16_16_Q15(attenuation, decay); - } - e[i] = SHL32(EXTEND32(MULT16_16_Q15(attenuation, exc[offset+i])), SIG_SHIFT); - /* Compute the energy of the previously decoded signal whose - excitation we're copying */ - tmp = ROUND16(out_mem[c][-N+offset+i],SIG_SHIFT); - S1 += SHR32(MULT16_16(tmp,tmp),8); - } - - /* Copy the last decoded samples (prior to the overlap region) to - synthesis filter memory so we can have a continuous signal. */ - for (i=0;i SHR32(S2,2))) -#else - /* Float test is written this way to catch NaNs at the same time */ - if (!(S1 > 0.2f*S2)) -#endif - { - for (i=0;iwindow[i], Q15ONE-ratio); - e[i] = MULT16_32_Q15(tmp_g, e[i]); - } - for (i=overlap;ipostfilter_period, st->postfilter_period, st->overlap, - -st->postfilter_gain, -st->postfilter_gain, st->postfilter_tapset, st->postfilter_tapset, - NULL, 0); - - /* Simulate TDAC on the concealed audio so that it blends with the - MDCT of next frames. */ - for (i=0;iwindow[i], etmp[overlap-1-i]) + - MULT16_32_Q15(mode->window[overlap-i-1], etmp[i ]); - out_mem[c][MAX_PERIOD+i] = MULT16_32_Q15(mode->window[overlap-i-1], tmp); - out_mem[c][MAX_PERIOD+overlap-i-1] = MULT16_32_Q15(mode->window[i], tmp); - } - } while (++cdownsample, mode->preemph, st->preemph_memD); - - st->loss_count++; - - RESTORE_STACK; -} - -int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, opus_val16 * OPUS_RESTRICT pcm, int frame_size, ec_dec *dec) -{ - int c, i, N; - int spread_decision; - opus_int32 bits; - ec_dec _dec; - VARDECL(celt_sig, freq); - VARDECL(celt_norm, X); - VARDECL(celt_ener, bandE); - VARDECL(int, fine_quant); - VARDECL(int, pulses); - VARDECL(int, cap); - VARDECL(int, offsets); - VARDECL(int, fine_priority); - VARDECL(int, tf_res); - VARDECL(unsigned char, collapse_masks); - celt_sig *out_mem[2]; - celt_sig *decode_mem[2]; - celt_sig *overlap_mem[2]; - celt_sig *out_syn[2]; - opus_val16 *lpc; - opus_val16 *oldBandE, *oldLogE, *oldLogE2, *backgroundLogE; - - int shortBlocks; - int isTransient; - int intra_ener; - const int CC = st->channels; - int LM, M; - int effEnd; - int codedBands; - int alloc_trim; - int postfilter_pitch; - opus_val16 postfilter_gain; - int intensity=0; - int dual_stereo=0; - opus_int32 total_bits; - opus_int32 balance; - opus_int32 tell; - int dynalloc_logp; - int postfilter_tapset; - int anti_collapse_rsv; - int anti_collapse_on=0; - int silence; - int C = st->stream_channels; - ALLOC_STACK; - - frame_size *= st->downsample; - - c=0; do { - decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+st->overlap); - out_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE-MAX_PERIOD; - overlap_mem[c] = decode_mem[c]+DECODE_BUFFER_SIZE; - } while (++c_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*CC); - oldBandE = lpc+CC*LPC_ORDER; - oldLogE = oldBandE + 2*st->mode->nbEBands; - oldLogE2 = oldLogE + 2*st->mode->nbEBands; - backgroundLogE = oldLogE2 + 2*st->mode->nbEBands; - -#ifdef CUSTOM_MODES - if (st->signalling && data!=NULL) - { - int data0=data[0]; - /* Convert "standard mode" to Opus header */ - if (st->mode->Fs==48000 && st->mode->shortMdctSize==120) - { - data0 = fromOpus(data0); - if (data0<0) - return OPUS_INVALID_PACKET; - } - st->end = IMAX(1, st->mode->effEBands-2*(data0>>5)); - LM = (data0>>3)&0x3; - C = 1 + ((data0>>2)&0x1); - data++; - len--; - if (LM>st->mode->maxLM) - return OPUS_INVALID_PACKET; - if (frame_size < st->mode->shortMdctSize<mode->shortMdctSize<mode->maxLM;LM++) - if (st->mode->shortMdctSize<st->mode->maxLM) - return OPUS_BAD_ARG; - } - M=1<1275 || pcm==NULL) - return OPUS_BAD_ARG; - - N = M*st->mode->shortMdctSize; - - effEnd = st->end; - if (effEnd > st->mode->effEBands) - effEnd = st->mode->effEBands; - - if (data == NULL || len<=1) - { - celt_decode_lost(st, pcm, N, LM); - RESTORE_STACK; - return frame_size/st->downsample; - } - - ALLOC(freq, IMAX(CC,C)*N, celt_sig); /**< Interleaved signal MDCTs */ - ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */ - ALLOC(bandE, st->mode->nbEBands*C, celt_ener); - c=0; do - for (i=0;imode->eBands[st->start];i++) - X[c*N+i] = 0; - while (++cmode->eBands[effEnd];imode->nbEBands;i++) - oldBandE[i]=MAX16(oldBandE[i],oldBandE[st->mode->nbEBands+i]); - } - - total_bits = len*8; - tell = ec_tell(dec); - - if (tell >= total_bits) - silence = 1; - else if (tell==1) - silence = ec_dec_bit_logp(dec, 15); - else - silence = 0; - if (silence) - { - /* Pretend we've read all the remaining bits */ - tell = len*8; - dec->nbits_total+=tell-ec_tell(dec); - } - - postfilter_gain = 0; - postfilter_pitch = 0; - postfilter_tapset = 0; - if (st->start==0 && tell+16 <= total_bits) - { - if(ec_dec_bit_logp(dec, 1)) - { - int qg, octave; - octave = ec_dec_uint(dec, 6); - postfilter_pitch = (16< 0 && tell+3 <= total_bits) - { - isTransient = ec_dec_bit_logp(dec, 3); - tell = ec_tell(dec); - } - else - isTransient = 0; - - if (isTransient) - shortBlocks = M; - else - shortBlocks = 0; - - /* Decode the global flags (first symbols in the stream) */ - intra_ener = tell+3<=total_bits ? ec_dec_bit_logp(dec, 3) : 0; - /* Get band energies */ - unquant_coarse_energy(st->mode, st->start, st->end, oldBandE, - intra_ener, dec, C, LM); - - ALLOC(tf_res, st->mode->nbEBands, int); - tf_decode(st->start, st->end, isTransient, tf_res, LM, dec); - - tell = ec_tell(dec); - spread_decision = SPREAD_NORMAL; - if (tell+4 <= total_bits) - spread_decision = ec_dec_icdf(dec, spread_icdf, 5); - - ALLOC(pulses, st->mode->nbEBands, int); - ALLOC(cap, st->mode->nbEBands, int); - ALLOC(offsets, st->mode->nbEBands, int); - ALLOC(fine_priority, st->mode->nbEBands, int); - - init_caps(st->mode,cap,LM,C); - - dynalloc_logp = 6; - total_bits<<=BITRES; - tell = ec_tell_frac(dec); - for (i=st->start;iend;i++) - { - int width, quanta; - int dynalloc_loop_logp; - int boost; - width = C*(st->mode->eBands[i+1]-st->mode->eBands[i])<0) - dynalloc_logp = IMAX(2, dynalloc_logp-1); - } - - ALLOC(fine_quant, st->mode->nbEBands, int); - alloc_trim = tell+(6<=2&&bits>=((LM+2)<mode, st->start, st->end, offsets, cap, - alloc_trim, &intensity, &dual_stereo, bits, &balance, pulses, - fine_quant, fine_priority, C, LM, dec, 0, 0); - - unquant_fine_energy(st->mode, st->start, st->end, oldBandE, fine_quant, dec, C); - - /* Decode fixed codebook */ - ALLOC(collapse_masks, C*st->mode->nbEBands, unsigned char); - quant_all_bands(0, st->mode, st->start, st->end, X, C==2 ? X+N : NULL, collapse_masks, - NULL, pulses, shortBlocks, spread_decision, dual_stereo, intensity, tf_res, - len*(8<rng); - - if (anti_collapse_rsv > 0) - { - anti_collapse_on = ec_dec_bits(dec, 1); - } - - unquant_energy_finalise(st->mode, st->start, st->end, oldBandE, - fine_quant, fine_priority, len*8-ec_tell(dec), dec, C); - - if (anti_collapse_on) - anti_collapse(st->mode, X, collapse_masks, LM, C, N, - st->start, st->end, oldBandE, oldLogE, oldLogE2, pulses, st->rng); - - log2Amp(st->mode, st->start, st->end, bandE, oldBandE, C); - - if (silence) - { - for (i=0;imode->nbEBands;i++) - { - bandE[i] = 0; - oldBandE[i] = -QCONST16(28.f,DB_SHIFT); - } - } - /* Synthesis */ - denormalise_bands(st->mode, X, freq, bandE, effEnd, C, M); - - OPUS_MOVE(decode_mem[0], decode_mem[0]+N, DECODE_BUFFER_SIZE-N); - if (CC==2) - OPUS_MOVE(decode_mem[1], decode_mem[1]+N, DECODE_BUFFER_SIZE-N); - - c=0; do - for (i=0;imode->eBands[st->start];i++) - freq[c*N+i] = 0; - while (++cmode->eBands[effEnd]; - if (st->downsample!=1) - bound = IMIN(bound, N/st->downsample); - for (i=bound;imode, shortBlocks, freq, out_syn, overlap_mem, CC, LM); - - c=0; do { - st->postfilter_period=IMAX(st->postfilter_period, COMBFILTER_MINPERIOD); - st->postfilter_period_old=IMAX(st->postfilter_period_old, COMBFILTER_MINPERIOD); - comb_filter(out_syn[c], out_syn[c], st->postfilter_period_old, st->postfilter_period, st->mode->shortMdctSize, - st->postfilter_gain_old, st->postfilter_gain, st->postfilter_tapset_old, st->postfilter_tapset, - st->mode->window, st->overlap); - if (LM!=0) - comb_filter(out_syn[c]+st->mode->shortMdctSize, out_syn[c]+st->mode->shortMdctSize, st->postfilter_period, postfilter_pitch, N-st->mode->shortMdctSize, - st->postfilter_gain, postfilter_gain, st->postfilter_tapset, postfilter_tapset, - st->mode->window, st->mode->overlap); - - } while (++cpostfilter_period_old = st->postfilter_period; - st->postfilter_gain_old = st->postfilter_gain; - st->postfilter_tapset_old = st->postfilter_tapset; - st->postfilter_period = postfilter_pitch; - st->postfilter_gain = postfilter_gain; - st->postfilter_tapset = postfilter_tapset; - if (LM!=0) - { - st->postfilter_period_old = st->postfilter_period; - st->postfilter_gain_old = st->postfilter_gain; - st->postfilter_tapset_old = st->postfilter_tapset; - } - - if (C==1) { - for (i=0;imode->nbEBands;i++) - oldBandE[st->mode->nbEBands+i]=oldBandE[i]; - } - - /* In case start or end were to change */ - if (!isTransient) - { - for (i=0;i<2*st->mode->nbEBands;i++) - oldLogE2[i] = oldLogE[i]; - for (i=0;i<2*st->mode->nbEBands;i++) - oldLogE[i] = oldBandE[i]; - for (i=0;i<2*st->mode->nbEBands;i++) - backgroundLogE[i] = MIN16(backgroundLogE[i] + M*QCONST16(0.001f,DB_SHIFT), oldBandE[i]); - } else { - for (i=0;i<2*st->mode->nbEBands;i++) - oldLogE[i] = MIN16(oldLogE[i], oldBandE[i]); - } - c=0; do - { - for (i=0;istart;i++) - { - oldBandE[c*st->mode->nbEBands+i]=0; - oldLogE[c*st->mode->nbEBands+i]=oldLogE2[c*st->mode->nbEBands+i]=-QCONST16(28.f,DB_SHIFT); - } - for (i=st->end;imode->nbEBands;i++) - { - oldBandE[c*st->mode->nbEBands+i]=0; - oldLogE[c*st->mode->nbEBands+i]=oldLogE2[c*st->mode->nbEBands+i]=-QCONST16(28.f,DB_SHIFT); - } - } while (++c<2); - st->rng = dec->rng; - - deemphasis(out_syn, pcm, N, CC, st->downsample, st->mode->preemph, st->preemph_memD); - st->loss_count = 0; - RESTORE_STACK; - if (ec_tell(dec) > 8*len) - return OPUS_INTERNAL_ERROR; - if(ec_get_error(dec)) - st->error = 1; - return frame_size/st->downsample; -} - - -#ifdef CUSTOM_MODES - -#ifdef FIXED_POINT -int opus_custom_decode(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, opus_int16 * OPUS_RESTRICT pcm, int frame_size) -{ - return celt_decode_with_ec(st, data, len, pcm, frame_size, NULL); -} - -#ifndef DISABLE_FLOAT_API -int opus_custom_decode_float(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, float * OPUS_RESTRICT pcm, int frame_size) -{ - int j, ret, C, N; - VARDECL(opus_int16, out); - ALLOC_STACK; - - if (pcm==NULL) - return OPUS_BAD_ARG; - - C = st->channels; - N = frame_size; - - ALLOC(out, C*N, opus_int16); - ret=celt_decode_with_ec(st, data, len, out, frame_size, NULL); - if (ret>0) - for (j=0;jchannels; - N = frame_size; - ALLOC(out, C*N, celt_sig); - - ret=celt_decode_with_ec(st, data, len, out, frame_size, NULL); - - if (ret>0) - for (j=0;j=st->mode->nbEBands) - goto bad_arg; - st->start = value; - } - break; - case CELT_SET_END_BAND_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if (value<1 || value>st->mode->nbEBands) - goto bad_arg; - st->end = value; - } - break; - case CELT_SET_CHANNELS_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if (value<1 || value>2) - goto bad_arg; - st->stream_channels = value; - } - break; - case CELT_GET_AND_CLEAR_ERROR_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - if (value==NULL) - goto bad_arg; - *value=st->error; - st->error = 0; - } - break; - case OPUS_GET_LOOKAHEAD_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - if (value==NULL) - goto bad_arg; - *value = st->overlap/st->downsample; - } - break; - case OPUS_RESET_STATE: - { - int i; - opus_val16 *lpc, *oldBandE, *oldLogE, *oldLogE2; - lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*st->channels); - oldBandE = lpc+st->channels*LPC_ORDER; - oldLogE = oldBandE + 2*st->mode->nbEBands; - oldLogE2 = oldLogE + 2*st->mode->nbEBands; - OPUS_CLEAR((char*)&st->DECODER_RESET_START, - opus_custom_decoder_get_size(st->mode, st->channels)- - ((char*)&st->DECODER_RESET_START - (char*)st)); - for (i=0;i<2*st->mode->nbEBands;i++) - oldLogE[i]=oldLogE2[i]=-QCONST16(28.f,DB_SHIFT); - } - break; - case OPUS_GET_PITCH_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - if (value==NULL) - goto bad_arg; - *value = st->postfilter_period; - } - break; - case CELT_GET_MODE_REQUEST: - { - const CELTMode ** value = va_arg(ap, const CELTMode**); - if (value==0) - goto bad_arg; - *value=st->mode; - } - break; - case CELT_SET_SIGNALLING_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - st->signalling = value; - } - break; - case OPUS_GET_FINAL_RANGE_REQUEST: - { - opus_uint32 * value = va_arg(ap, opus_uint32 *); - if (value==0) - goto bad_arg; - *value=st->rng; - } - break; - default: - goto bad_request; - } - va_end(ap); - return OPUS_OK; -bad_arg: - va_end(ap); - return OPUS_BAD_ARG; -bad_request: - va_end(ap); - return OPUS_UNIMPLEMENTED; -} - - - -const char *opus_strerror(int error) -{ - static const char * const error_strings[8] = { - "success", - "invalid argument", - "buffer too small", - "internal error", - "corrupted stream", - "request not implemented", - "invalid state", - "memory allocation failed" - }; - if (error > 0 || error < -7) - return "unknown error"; - else - return error_strings[-error]; -} - -const char *opus_get_version_string(void) -{ - return "libopus " OPUS_VERSION -#ifdef FIXED_POINT - "-fixed" -#endif -#ifdef FUZZING - "-fuzzing" -#endif - ; -} diff --git a/src/opus-1.0.2/celt/celt.h b/src/opus-1.0.2/celt/celt.h deleted file mode 100644 index 218cd883..00000000 --- a/src/opus-1.0.2/celt/celt.h +++ /dev/null @@ -1,117 +0,0 @@ -/* Copyright (c) 2007-2008 CSIRO - Copyright (c) 2007-2009 Xiph.Org Foundation - Copyright (c) 2008 Gregory Maxwell - Written by Jean-Marc Valin and Gregory Maxwell */ -/** - @file celt.h - @brief Contains all the functions for encoding and decoding audio - */ - -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef CELT_H -#define CELT_H - -#include "opus_types.h" -#include "opus_defines.h" -#include "opus_custom.h" -#include "entenc.h" -#include "entdec.h" -#include "arch.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define CELTEncoder OpusCustomEncoder -#define CELTDecoder OpusCustomDecoder -#define CELTMode OpusCustomMode - -#define _celt_check_mode_ptr_ptr(ptr) ((ptr) + ((ptr) - (const CELTMode**)(ptr))) - -/* Encoder/decoder Requests */ - -#define CELT_SET_PREDICTION_REQUEST 10002 -/** Controls the use of interframe prediction. - 0=Independent frames - 1=Short term interframe prediction allowed - 2=Long term prediction allowed - */ -#define CELT_SET_PREDICTION(x) CELT_SET_PREDICTION_REQUEST, __opus_check_int(x) - -#define CELT_SET_INPUT_CLIPPING_REQUEST 10004 -#define CELT_SET_INPUT_CLIPPING(x) CELT_SET_INPUT_CLIPPING_REQUEST, __opus_check_int(x) - -#define CELT_GET_AND_CLEAR_ERROR_REQUEST 10007 -#define CELT_GET_AND_CLEAR_ERROR(x) CELT_GET_AND_CLEAR_ERROR_REQUEST, __opus_check_int_ptr(x) - -#define CELT_SET_CHANNELS_REQUEST 10008 -#define CELT_SET_CHANNELS(x) CELT_SET_CHANNELS_REQUEST, __opus_check_int(x) - - -/* Internal */ -#define CELT_SET_START_BAND_REQUEST 10010 -#define CELT_SET_START_BAND(x) CELT_SET_START_BAND_REQUEST, __opus_check_int(x) - -#define CELT_SET_END_BAND_REQUEST 10012 -#define CELT_SET_END_BAND(x) CELT_SET_END_BAND_REQUEST, __opus_check_int(x) - -#define CELT_GET_MODE_REQUEST 10015 -/** Get the CELTMode used by an encoder or decoder */ -#define CELT_GET_MODE(x) CELT_GET_MODE_REQUEST, _celt_check_mode_ptr_ptr(x) - -#define CELT_SET_SIGNALLING_REQUEST 10016 -#define CELT_SET_SIGNALLING(x) CELT_SET_SIGNALLING_REQUEST, __opus_check_int(x) - - - -/* Encoder stuff */ - -int celt_encoder_get_size(int channels); - -int celt_encode_with_ec(OpusCustomEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc); - -int celt_encoder_init(CELTEncoder *st, opus_int32 sampling_rate, int channels); - - - -/* Decoder stuff */ - -int celt_decoder_get_size(int channels); - - -int celt_decoder_init(CELTDecoder *st, opus_int32 sampling_rate, int channels); - -int celt_decode_with_ec(OpusCustomDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, opus_val16 * OPUS_RESTRICT pcm, int frame_size, ec_dec *dec); - -#define celt_encoder_ctl opus_custom_encoder_ctl -#define celt_decoder_ctl opus_custom_decoder_ctl - -#ifdef __cplusplus -} -#endif - -#endif /* CELT_H */ diff --git a/src/opus-1.0.2/celt/celt_lpc.c b/src/opus-1.0.2/celt/celt_lpc.c deleted file mode 100644 index d2addbf2..00000000 --- a/src/opus-1.0.2/celt/celt_lpc.c +++ /dev/null @@ -1,188 +0,0 @@ -/* Copyright (c) 2009-2010 Xiph.Org Foundation - Written by Jean-Marc Valin */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "celt_lpc.h" -#include "stack_alloc.h" -#include "mathops.h" - -void _celt_lpc( - opus_val16 *_lpc, /* out: [0...p-1] LPC coefficients */ -const opus_val32 *ac, /* in: [0...p] autocorrelation values */ -int p -) -{ - int i, j; - opus_val32 r; - opus_val32 error = ac[0]; -#ifdef FIXED_POINT - opus_val32 lpc[LPC_ORDER]; -#else - float *lpc = _lpc; -#endif - - for (i = 0; i < p; i++) - lpc[i] = 0; - if (ac[0] != 0) - { - for (i = 0; i < p; i++) { - /* Sum up this iteration's reflection coefficient */ - opus_val32 rr = 0; - for (j = 0; j < i; j++) - rr += MULT32_32_Q31(lpc[j],ac[i - j]); - rr += SHR32(ac[i + 1],3); - r = -frac_div32(SHL32(rr,3), error); - /* Update LPC coefficients and total error */ - lpc[i] = SHR32(r,3); - for (j = 0; j < (i+1)>>1; j++) - { - opus_val32 tmp1, tmp2; - tmp1 = lpc[j]; - tmp2 = lpc[i-1-j]; - lpc[j] = tmp1 + MULT32_32_Q31(r,tmp2); - lpc[i-1-j] = tmp2 + MULT32_32_Q31(r,tmp1); - } - - error = error - MULT32_32_Q31(MULT32_32_Q31(r,r),error); - /* Bail out once we get 30 dB gain */ -#ifdef FIXED_POINT - if (error=1;j--) - { - mem[j]=mem[j-1]; - } - mem[0] = x[i]; - y[i] = ROUND16(sum, SIG_SHIFT); - } -} - -void celt_iir(const opus_val32 *x, - const opus_val16 *den, - opus_val32 *y, - int N, - int ord, - opus_val16 *mem) -{ - int i,j; - for (i=0;i=1;j--) - { - mem[j]=mem[j-1]; - } - mem[0] = ROUND16(sum,SIG_SHIFT); - y[i] = sum; - } -} - -void _celt_autocorr( - const opus_val16 *x, /* in: [0...n-1] samples x */ - opus_val32 *ac, /* out: [0...lag-1] ac values */ - const opus_val16 *window, - int overlap, - int lag, - int n - ) -{ - opus_val32 d; - int i; - VARDECL(opus_val16, xx); - SAVE_STACK; - ALLOC(xx, n, opus_val16); - celt_assert(n>0); - celt_assert(overlap>=0); - for (i=0;i=0) - { - for (i = lag, d = 0; i < n; i++) - d += xx[i] * xx[i-lag]; - ac[lag] = d; - /*printf ("%f ", ac[lag]);*/ - lag--; - } - /*printf ("\n");*/ - ac[0] += 10; - - RESTORE_STACK; -} diff --git a/src/opus-1.0.2/celt/celt_lpc.h b/src/opus-1.0.2/celt/celt_lpc.h deleted file mode 100644 index 2baa77ed..00000000 --- a/src/opus-1.0.2/celt/celt_lpc.h +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright (c) 2009-2010 Xiph.Org Foundation - Written by Jean-Marc Valin */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef PLC_H -#define PLC_H - -#include "arch.h" - -#define LPC_ORDER 24 - -void _celt_lpc(opus_val16 *_lpc, const opus_val32 *ac, int p); - -void celt_fir(const opus_val16 *x, - const opus_val16 *num, - opus_val16 *y, - int N, - int ord, - opus_val16 *mem); - -void celt_iir(const opus_val32 *x, - const opus_val16 *den, - opus_val32 *y, - int N, - int ord, - opus_val16 *mem); - -void _celt_autocorr(const opus_val16 *x, opus_val32 *ac, const opus_val16 *window, int overlap, int lag, int n); - -#endif /* PLC_H */ diff --git a/src/opus-1.0.2/celt/cwrs.c b/src/opus-1.0.2/celt/cwrs.c deleted file mode 100644 index 8edc919d..00000000 --- a/src/opus-1.0.2/celt/cwrs.c +++ /dev/null @@ -1,645 +0,0 @@ -/* Copyright (c) 2007-2008 CSIRO - Copyright (c) 2007-2009 Xiph.Org Foundation - Copyright (c) 2007-2009 Timothy B. Terriberry - Written by Timothy B. Terriberry and Jean-Marc Valin */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "os_support.h" -#include "cwrs.h" -#include "mathops.h" -#include "arch.h" - -#ifdef CUSTOM_MODES - -/*Guaranteed to return a conservatively large estimate of the binary logarithm - with frac bits of fractional precision. - Tested for all possible 32-bit inputs with frac=4, where the maximum - overestimation is 0.06254243 bits.*/ -int log2_frac(opus_uint32 val, int frac) -{ - int l; - l=EC_ILOG(val); - if(val&(val-1)){ - /*This is (val>>l-16), but guaranteed to round up, even if adding a bias - before the shift would cause overflow (e.g., for 0xFFFFxxxx). - Doesn't work for val=0, but that case fails the test above.*/ - if(l>16)val=((val-1)>>(l-16))+1; - else val<<=16-l; - l=(l-1)<>16); - l+=b<>b; - val=(val*val+0x7FFF)>>15; - } - while(frac-->0); - /*If val is not exactly 0x8000, then we have to round up the remainder.*/ - return l+(val>0x8000); - } - /*Exact powers of two require no rounding.*/ - else return (l-1)<0); - celt_assert(_d<=54); - shift=EC_ILOG(_d^(_d-1)); - inv=INV_TABLE[(_d-1)>>shift]; - shift--; - one=1<>shift)-(_c>>shift)+ - ((_a*(_b&mask)+one-(_c&mask))>>shift)-1)*inv&MASK32; -} - -#endif /* SMALL_FOOTPRINT */ - -/*Although derived separately, the pulse vector coding scheme is equivalent to - a Pyramid Vector Quantizer \cite{Fis86}. - Some additional notes about an early version appear at - http://people.xiph.org/~tterribe/notes/cwrs.html, but the codebook ordering - and the definitions of some terms have evolved since that was written. - - The conversion from a pulse vector to an integer index (encoding) and back - (decoding) is governed by two related functions, V(N,K) and U(N,K). - - V(N,K) = the number of combinations, with replacement, of N items, taken K - at a time, when a sign bit is added to each item taken at least once (i.e., - the number of N-dimensional unit pulse vectors with K pulses). - One way to compute this is via - V(N,K) = K>0 ? sum(k=1...K,2**k*choose(N,k)*choose(K-1,k-1)) : 1, - where choose() is the binomial function. - A table of values for N<10 and K<10 looks like: - V[10][10] = { - {1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {1, 2, 2, 2, 2, 2, 2, 2, 2, 2}, - {1, 4, 8, 12, 16, 20, 24, 28, 32, 36}, - {1, 6, 18, 38, 66, 102, 146, 198, 258, 326}, - {1, 8, 32, 88, 192, 360, 608, 952, 1408, 1992}, - {1, 10, 50, 170, 450, 1002, 1970, 3530, 5890, 9290}, - {1, 12, 72, 292, 912, 2364, 5336, 10836, 20256, 35436}, - {1, 14, 98, 462, 1666, 4942, 12642, 28814, 59906, 115598}, - {1, 16, 128, 688, 2816, 9424, 27008, 68464, 157184, 332688}, - {1, 18, 162, 978, 4482, 16722, 53154, 148626, 374274, 864146} - }; - - U(N,K) = the number of such combinations wherein N-1 objects are taken at - most K-1 at a time. - This is given by - U(N,K) = sum(k=0...K-1,V(N-1,k)) - = K>0 ? (V(N-1,K-1) + V(N,K-1))/2 : 0. - The latter expression also makes clear that U(N,K) is half the number of such - combinations wherein the first object is taken at least once. - Although it may not be clear from either of these definitions, U(N,K) is the - natural function to work with when enumerating the pulse vector codebooks, - not V(N,K). - U(N,K) is not well-defined for N=0, but with the extension - U(0,K) = K>0 ? 0 : 1, - the function becomes symmetric: U(N,K) = U(K,N), with a similar table: - U[10][10] = { - {1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - {0, 1, 1, 1, 1, 1, 1, 1, 1, 1}, - {0, 1, 3, 5, 7, 9, 11, 13, 15, 17}, - {0, 1, 5, 13, 25, 41, 61, 85, 113, 145}, - {0, 1, 7, 25, 63, 129, 231, 377, 575, 833}, - {0, 1, 9, 41, 129, 321, 681, 1289, 2241, 3649}, - {0, 1, 11, 61, 231, 681, 1683, 3653, 7183, 13073}, - {0, 1, 13, 85, 377, 1289, 3653, 8989, 19825, 40081}, - {0, 1, 15, 113, 575, 2241, 7183, 19825, 48639, 108545}, - {0, 1, 17, 145, 833, 3649, 13073, 40081, 108545, 265729} - }; - - With this extension, V(N,K) may be written in terms of U(N,K): - V(N,K) = U(N,K) + U(N,K+1) - for all N>=0, K>=0. - Thus U(N,K+1) represents the number of combinations where the first element - is positive or zero, and U(N,K) represents the number of combinations where - it is negative. - With a large enough table of U(N,K) values, we could write O(N) encoding - and O(min(N*log(K),N+K)) decoding routines, but such a table would be - prohibitively large for small embedded devices (K may be as large as 32767 - for small N, and N may be as large as 200). - - Both functions obey the same recurrence relation: - V(N,K) = V(N-1,K) + V(N,K-1) + V(N-1,K-1), - U(N,K) = U(N-1,K) + U(N,K-1) + U(N-1,K-1), - for all N>0, K>0, with different initial conditions at N=0 or K=0. - This allows us to construct a row of one of the tables above given the - previous row or the next row. - Thus we can derive O(NK) encoding and decoding routines with O(K) memory - using only addition and subtraction. - - When encoding, we build up from the U(2,K) row and work our way forwards. - When decoding, we need to start at the U(N,K) row and work our way backwards, - which requires a means of computing U(N,K). - U(N,K) may be computed from two previous values with the same N: - U(N,K) = ((2*N-1)*U(N,K-1) - U(N,K-2))/(K-1) + U(N,K-2) - for all N>1, and since U(N,K) is symmetric, a similar relation holds for two - previous values with the same K: - U(N,K>1) = ((2*K-1)*U(N-1,K) - U(N-2,K))/(N-1) + U(N-2,K) - for all K>1. - This allows us to construct an arbitrary row of the U(N,K) table by starting - with the first two values, which are constants. - This saves roughly 2/3 the work in our O(NK) decoding routine, but costs O(K) - multiplications. - Similar relations can be derived for V(N,K), but are not used here. - - For N>0 and K>0, U(N,K) and V(N,K) take on the form of an (N-1)-degree - polynomial for fixed N. - The first few are - U(1,K) = 1, - U(2,K) = 2*K-1, - U(3,K) = (2*K-2)*K+1, - U(4,K) = (((4*K-6)*K+8)*K-3)/3, - U(5,K) = ((((2*K-4)*K+10)*K-8)*K+3)/3, - and - V(1,K) = 2, - V(2,K) = 4*K, - V(3,K) = 4*K*K+2, - V(4,K) = 8*(K*K+2)*K/3, - V(5,K) = ((4*K*K+20)*K*K+6)/3, - for all K>0. - This allows us to derive O(N) encoding and O(N*log(K)) decoding routines for - small N (and indeed decoding is also O(N) for N<3). - - @ARTICLE{Fis86, - author="Thomas R. Fischer", - title="A Pyramid Vector Quantizer", - journal="IEEE Transactions on Information Theory", - volume="IT-32", - number=4, - pages="568--583", - month=Jul, - year=1986 - }*/ - -#ifndef SMALL_FOOTPRINT -/*Compute U(2,_k). - Note that this may be called with _k=32768 (maxK[2]+1).*/ -static inline unsigned ucwrs2(unsigned _k){ - celt_assert(_k>0); - return _k+(_k-1); -} - -/*Compute V(2,_k).*/ -static inline opus_uint32 ncwrs2(int _k){ - celt_assert(_k>0); - return 4*(opus_uint32)_k; -} - -/*Compute U(3,_k). - Note that this may be called with _k=32768 (maxK[3]+1).*/ -static inline opus_uint32 ucwrs3(unsigned _k){ - celt_assert(_k>0); - return (2*(opus_uint32)_k-2)*_k+1; -} - -/*Compute V(3,_k).*/ -static inline opus_uint32 ncwrs3(int _k){ - celt_assert(_k>0); - return 2*(2*(unsigned)_k*(opus_uint32)_k+1); -} - -/*Compute U(4,_k).*/ -static inline opus_uint32 ucwrs4(int _k){ - celt_assert(_k>0); - return imusdiv32odd(2*_k,(2*_k-3)*(opus_uint32)_k+4,3,1); -} - -/*Compute V(4,_k).*/ -static inline opus_uint32 ncwrs4(int _k){ - celt_assert(_k>0); - return ((_k*(opus_uint32)_k+2)*_k)/3<<3; -} - -#endif /* SMALL_FOOTPRINT */ - -/*Computes the next row/column of any recurrence that obeys the relation - u[i][j]=u[i-1][j]+u[i][j-1]+u[i-1][j-1]. - _ui0 is the base case for the new row/column.*/ -static inline void unext(opus_uint32 *_ui,unsigned _len,opus_uint32 _ui0){ - opus_uint32 ui1; - unsigned j; - /*This do-while will overrun the array if we don't have storage for at least - 2 values.*/ - j=1; do { - ui1=UADD32(UADD32(_ui[j],_ui[j-1]),_ui0); - _ui[j-1]=_ui0; - _ui0=ui1; - } while (++j<_len); - _ui[j-1]=_ui0; -} - -/*Computes the previous row/column of any recurrence that obeys the relation - u[i-1][j]=u[i][j]-u[i][j-1]-u[i-1][j-1]. - _ui0 is the base case for the new row/column.*/ -static inline void uprev(opus_uint32 *_ui,unsigned _n,opus_uint32 _ui0){ - opus_uint32 ui1; - unsigned j; - /*This do-while will overrun the array if we don't have storage for at least - 2 values.*/ - j=1; do { - ui1=USUB32(USUB32(_ui[j],_ui[j-1]),_ui0); - _ui[j-1]=_ui0; - _ui0=ui1; - } while (++j<_n); - _ui[j-1]=_ui0; -} - -/*Compute V(_n,_k), as well as U(_n,0..._k+1). - _u: On exit, _u[i] contains U(_n,i) for i in [0..._k+1].*/ -static opus_uint32 ncwrs_urow(unsigned _n,unsigned _k,opus_uint32 *_u){ - opus_uint32 um2; - unsigned len; - unsigned k; - len=_k+2; - /*We require storage at least 3 values (e.g., _k>0).*/ - celt_assert(len>=3); - _u[0]=0; - _u[1]=um2=1; -#ifndef SMALL_FOOTPRINT - /*_k>52 doesn't work in the false branch due to the limits of INV_TABLE, - but _k isn't tested here because k<=52 for n=7*/ - if(_n<=6) -#endif - { - /*If _n==0, _u[0] should be 1 and the rest should be 0.*/ - /*If _n==1, _u[i] should be 1 for i>1.*/ - celt_assert(_n>=2); - /*If _k==0, the following do-while loop will overflow the buffer.*/ - celt_assert(_k>0); - k=2; - do _u[k]=(k<<1)-1; - while(++k=len)break; - _u[k]=um1=imusdiv32odd(n2m1,um2,um1,(k-1)>>1)+um1; - } - } -#endif /* SMALL_FOOTPRINT */ - return _u[_k]+_u[_k+1]; -} - -#ifndef SMALL_FOOTPRINT - -/*Returns the _i'th combination of _k elements (at most 32767) chosen from a - set of size 1 with associated sign bits. - _y: Returns the vector of pulses.*/ -static inline void cwrsi1(int _k,opus_uint32 _i,int *_y){ - int s; - s=-(int)_i; - _y[0]=(_k+s)^s; -} - -/*Returns the _i'th combination of _k elements (at most 32767) chosen from a - set of size 2 with associated sign bits. - _y: Returns the vector of pulses.*/ -static inline void cwrsi2(int _k,opus_uint32 _i,int *_y){ - opus_uint32 p; - int s; - int yj; - p=ucwrs2(_k+1U); - s=-(_i>=p); - _i-=p&s; - yj=_k; - _k=(_i+1)>>1; - p=_k?ucwrs2(_k):0; - _i-=p; - yj-=_k; - _y[0]=(yj+s)^s; - cwrsi1(_k,_i,_y+1); -} - -/*Returns the _i'th combination of _k elements (at most 32767) chosen from a - set of size 3 with associated sign bits. - _y: Returns the vector of pulses.*/ -static void cwrsi3(int _k,opus_uint32 _i,int *_y){ - opus_uint32 p; - int s; - int yj; - p=ucwrs3(_k+1U); - s=-(_i>=p); - _i-=p&s; - yj=_k; - /*Finds the maximum _k such that ucwrs3(_k)<=_i (tested for all - _i<2147418113=U(3,32768)).*/ - _k=_i>0?(isqrt32(2*_i-1)+1)>>1:0; - p=_k?ucwrs3(_k):0; - _i-=p; - yj-=_k; - _y[0]=(yj+s)^s; - cwrsi2(_k,_i,_y+1); -} - -/*Returns the _i'th combination of _k elements (at most 1172) chosen from a set - of size 4 with associated sign bits. - _y: Returns the vector of pulses.*/ -static void cwrsi4(int _k,opus_uint32 _i,int *_y){ - opus_uint32 p; - int s; - int yj; - int kl; - int kr; - p=ucwrs4(_k+1); - s=-(_i>=p); - _i-=p&s; - yj=_k; - /*We could solve a cubic for k here, but the form of the direct solution does - not lend itself well to exact integer arithmetic. - Instead we do a binary search on U(4,K).*/ - kl=0; - kr=_k; - for(;;){ - _k=(kl+kr)>>1; - p=_k?ucwrs4(_k):0; - if(p<_i){ - if(_k>=kr)break; - kl=_k+1; - } - else if(p>_i)kr=_k-1; - else break; - } - _i-=p; - yj-=_k; - _y[0]=(yj+s)^s; - cwrsi3(_k,_i,_y+1); -} - -#endif /* SMALL_FOOTPRINT */ - -/*Returns the _i'th combination of _k elements chosen from a set of size _n - with associated sign bits. - _y: Returns the vector of pulses. - _u: Must contain entries [0..._k+1] of row _n of U() on input. - Its contents will be destructively modified.*/ -static void cwrsi(int _n,int _k,opus_uint32 _i,int *_y,opus_uint32 *_u){ - int j; - celt_assert(_n>0); - j=0; - do{ - opus_uint32 p; - int s; - int yj; - p=_u[_k+1]; - s=-(_i>=p); - _i-=p&s; - yj=_k; - p=_u[_k]; - while(p>_i)p=_u[--_k]; - _i-=p; - yj-=_k; - _y[j]=(yj+s)^s; - uprev(_u,_k+2,0); - } - while(++j<_n); -} - -/*Returns the index of the given combination of K elements chosen from a set - of size 1 with associated sign bits. - _y: The vector of pulses, whose sum of absolute values is K. - _k: Returns K.*/ -static inline opus_uint32 icwrs1(const int *_y,int *_k){ - *_k=abs(_y[0]); - return _y[0]<0; -} - -#ifndef SMALL_FOOTPRINT - -/*Returns the index of the given combination of K elements chosen from a set - of size 2 with associated sign bits. - _y: The vector of pulses, whose sum of absolute values is K. - _k: Returns K.*/ -static inline opus_uint32 icwrs2(const int *_y,int *_k){ - opus_uint32 i; - int k; - i=icwrs1(_y+1,&k); - i+=k?ucwrs2(k):0; - k+=abs(_y[0]); - if(_y[0]<0)i+=ucwrs2(k+1U); - *_k=k; - return i; -} - -/*Returns the index of the given combination of K elements chosen from a set - of size 3 with associated sign bits. - _y: The vector of pulses, whose sum of absolute values is K. - _k: Returns K.*/ -static inline opus_uint32 icwrs3(const int *_y,int *_k){ - opus_uint32 i; - int k; - i=icwrs2(_y+1,&k); - i+=k?ucwrs3(k):0; - k+=abs(_y[0]); - if(_y[0]<0)i+=ucwrs3(k+1U); - *_k=k; - return i; -} - -/*Returns the index of the given combination of K elements chosen from a set - of size 4 with associated sign bits. - _y: The vector of pulses, whose sum of absolute values is K. - _k: Returns K.*/ -static inline opus_uint32 icwrs4(const int *_y,int *_k){ - opus_uint32 i; - int k; - i=icwrs3(_y+1,&k); - i+=k?ucwrs4(k):0; - k+=abs(_y[0]); - if(_y[0]<0)i+=ucwrs4(k+1); - *_k=k; - return i; -} - -#endif /* SMALL_FOOTPRINT */ - -/*Returns the index of the given combination of K elements chosen from a set - of size _n with associated sign bits. - _y: The vector of pulses, whose sum of absolute values must be _k. - _nc: Returns V(_n,_k).*/ -static inline opus_uint32 icwrs(int _n,int _k,opus_uint32 *_nc,const int *_y, - opus_uint32 *_u){ - opus_uint32 i; - int j; - int k; - /*We can't unroll the first two iterations of the loop unless _n>=2.*/ - celt_assert(_n>=2); - _u[0]=0; - for(k=1;k<=_k+1;k++)_u[k]=(k<<1)-1; - i=icwrs1(_y+_n-1,&k); - j=_n-2; - i+=_u[k]; - k+=abs(_y[j]); - if(_y[j]<0)i+=_u[k+1]; - while(j-->0){ - unext(_u,_k+2,0); - i+=_u[k]; - k+=abs(_y[j]); - if(_y[j]<0)i+=_u[k+1]; - } - *_nc=_u[k]+_u[k+1]; - return i; -} - -#ifdef CUSTOM_MODES -void get_required_bits(opus_int16 *_bits,int _n,int _maxk,int _frac){ - int k; - /*_maxk==0 => there's nothing to do.*/ - celt_assert(_maxk>0); - _bits[0]=0; - if (_n==1) - { - for (k=1;k<=_maxk;k++) - _bits[k] = 1<<_frac; - } - else { - VARDECL(opus_uint32,u); - SAVE_STACK; - ALLOC(u,_maxk+2U,opus_uint32); - ncwrs_urow(_n,_maxk,u); - for(k=1;k<=_maxk;k++) - _bits[k]=log2_frac(u[k]+u[k+1],_frac); - RESTORE_STACK; - } -} -#endif /* CUSTOM_MODES */ - -void encode_pulses(const int *_y,int _n,int _k,ec_enc *_enc){ - opus_uint32 i; - celt_assert(_k>0); -#ifndef SMALL_FOOTPRINT - switch(_n){ - case 2:{ - i=icwrs2(_y,&_k); - ec_enc_uint(_enc,i,ncwrs2(_k)); - }break; - case 3:{ - i=icwrs3(_y,&_k); - ec_enc_uint(_enc,i,ncwrs3(_k)); - }break; - case 4:{ - i=icwrs4(_y,&_k); - ec_enc_uint(_enc,i,ncwrs4(_k)); - }break; - default: - { -#endif - VARDECL(opus_uint32,u); - opus_uint32 nc; - SAVE_STACK; - ALLOC(u,_k+2U,opus_uint32); - i=icwrs(_n,_k,&nc,_y,u); - ec_enc_uint(_enc,i,nc); - RESTORE_STACK; -#ifndef SMALL_FOOTPRINT - } - break; - } -#endif -} - -void decode_pulses(int *_y,int _n,int _k,ec_dec *_dec) -{ - celt_assert(_k>0); -#ifndef SMALL_FOOTPRINT - switch(_n){ - case 2:cwrsi2(_k,ec_dec_uint(_dec,ncwrs2(_k)),_y);break; - case 3:cwrsi3(_k,ec_dec_uint(_dec,ncwrs3(_k)),_y);break; - case 4:cwrsi4(_k,ec_dec_uint(_dec,ncwrs4(_k)),_y);break; - default: - { -#endif - VARDECL(opus_uint32,u); - SAVE_STACK; - ALLOC(u,_k+2U,opus_uint32); - cwrsi(_n,_k,ec_dec_uint(_dec,ncwrs_urow(_n,_k,u)),_y,u); - RESTORE_STACK; -#ifndef SMALL_FOOTPRINT - } - break; - } -#endif -} diff --git a/src/opus-1.0.2/celt/cwrs.h b/src/opus-1.0.2/celt/cwrs.h deleted file mode 100644 index 7dfbd076..00000000 --- a/src/opus-1.0.2/celt/cwrs.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (c) 2007-2008 CSIRO - Copyright (c) 2007-2009 Xiph.Org Foundation - Copyright (c) 2007-2009 Timothy B. Terriberry - Written by Timothy B. Terriberry and Jean-Marc Valin */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef CWRS_H -#define CWRS_H - -#include "arch.h" -#include "stack_alloc.h" -#include "entenc.h" -#include "entdec.h" - -#ifdef CUSTOM_MODES -int log2_frac(opus_uint32 val, int frac); -#endif - -void get_required_bits(opus_int16 *bits, int N, int K, int frac); - -void encode_pulses(const int *_y, int N, int K, ec_enc *enc); - -void decode_pulses(int *_y, int N, int K, ec_dec *dec); - -#endif /* CWRS_H */ diff --git a/src/opus-1.0.2/celt/ecintrin.h b/src/opus-1.0.2/celt/ecintrin.h deleted file mode 100644 index be57dd40..00000000 --- a/src/opus-1.0.2/celt/ecintrin.h +++ /dev/null @@ -1,87 +0,0 @@ -/* Copyright (c) 2003-2008 Timothy B. Terriberry - Copyright (c) 2008 Xiph.Org Foundation */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/*Some common macros for potential platform-specific optimization.*/ -#include "opus_types.h" -#include -#include -#include "arch.h" -#if !defined(_ecintrin_H) -# define _ecintrin_H (1) - -/*Some specific platforms may have optimized intrinsic or inline assembly - versions of these functions which can substantially improve performance. - We define macros for them to allow easy incorporation of these non-ANSI - features.*/ - -/*Modern gcc (4.x) can compile the naive versions of min and max with cmov if - given an appropriate architecture, but the branchless bit-twiddling versions - are just as fast, and do not require any special target architecture. - Earlier gcc versions (3.x) compiled both code to the same assembly - instructions, because of the way they represented ((_b)>(_a)) internally.*/ -# define EC_MINI(_a,_b) ((_a)+(((_b)-(_a))&-((_b)<(_a)))) - -/*Count leading zeros. - This macro should only be used for implementing ec_ilog(), if it is defined. - All other code should use EC_ILOG() instead.*/ -#if defined(_MSC_VER) && (_MSC_VER >= 1400) -# include -/*In _DEBUG mode this is not an intrinsic by default.*/ -# pragma intrinsic(_BitScanReverse) - -static __inline int ec_bsr(unsigned long _x){ - unsigned long ret; - _BitScanReverse(&ret,_x); - return (int)ret; -} -# define EC_CLZ0 (1) -# define EC_CLZ(_x) (-ec_bsr(_x)) -#elif defined(ENABLE_TI_DSPLIB) -# include "dsplib.h" -# define EC_CLZ0 (31) -# define EC_CLZ(_x) (_lnorm(_x)) -#elif __GNUC_PREREQ(3,4) -# if INT_MAX>=2147483647 -# define EC_CLZ0 ((int)sizeof(unsigned)*CHAR_BIT) -# define EC_CLZ(_x) (__builtin_clz(_x)) -# elif LONG_MAX>=2147483647L -# define EC_CLZ0 ((int)sizeof(unsigned long)*CHAR_BIT) -# define EC_CLZ(_x) (__builtin_clzl(_x)) -# endif -#endif - -#if defined(EC_CLZ) -/*Note that __builtin_clz is not defined when _x==0, according to the gcc - documentation (and that of the BSR instruction that implements it on x86). - The majority of the time we can never pass it zero. - When we need to, it can be special cased.*/ -# define EC_ILOG(_x) (EC_CLZ0-EC_CLZ(_x)) -#else -int ec_ilog(opus_uint32 _v); -# define EC_ILOG(_x) (ec_ilog(_x)) -#endif -#endif diff --git a/src/opus-1.0.2/celt/entcode.c b/src/opus-1.0.2/celt/entcode.c deleted file mode 100644 index fa5d7c7c..00000000 --- a/src/opus-1.0.2/celt/entcode.c +++ /dev/null @@ -1,93 +0,0 @@ -/* Copyright (c) 2001-2011 Timothy B. Terriberry -*/ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "entcode.h" -#include "arch.h" - -#if !defined(EC_CLZ) -/*This is a fallback for systems where we don't know how to access - a BSR or CLZ instruction (see ecintrin.h). - If you are optimizing Opus on a new platform and it has a native CLZ or - BZR (e.g. cell, MIPS, x86, etc) then making it available to Opus will be - an easy performance win.*/ -int ec_ilog(opus_uint32 _v){ - /*On a Pentium M, this branchless version tested as the fastest on - 1,000,000,000 random 32-bit integers, edging out a similar version with - branches, and a 256-entry LUT version.*/ - int ret; - int m; - ret=!!_v; - m=!!(_v&0xFFFF0000)<<4; - _v>>=m; - ret|=m; - m=!!(_v&0xFF00)<<3; - _v>>=m; - ret|=m; - m=!!(_v&0xF0)<<2; - _v>>=m; - ret|=m; - m=!!(_v&0xC)<<1; - _v>>=m; - ret|=m; - ret+=!!(_v&0x2); - return ret; -} -#endif - -opus_uint32 ec_tell_frac(ec_ctx *_this){ - opus_uint32 nbits; - opus_uint32 r; - int l; - int i; - /*To handle the non-integral number of bits still left in the encoder/decoder - state, we compute the worst-case number of bits of val that must be - encoded to ensure that the value is inside the range for any possible - subsequent bits. - The computation here is independent of val itself (the decoder does not - even track that value), even though the real number of bits used after - ec_enc_done() may be 1 smaller if rng is a power of two and the - corresponding trailing bits of val are all zeros. - If we did try to track that special case, then coding a value with a - probability of 1/(1<nbits_total<rng); - r=_this->rng>>(l-16); - for(i=BITRES;i-->0;){ - int b; - r=r*r>>15; - b=(int)(r>>16); - l=l<<1|b; - r>>=b; - } - return nbits-l; -} diff --git a/src/opus-1.0.2/celt/entcode.h b/src/opus-1.0.2/celt/entcode.h deleted file mode 100644 index aebecc06..00000000 --- a/src/opus-1.0.2/celt/entcode.h +++ /dev/null @@ -1,116 +0,0 @@ -/* Copyright (c) 2001-2011 Timothy B. Terriberry - Copyright (c) 2008-2009 Xiph.Org Foundation */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "opus_types.h" - -#if !defined(_entcode_H) -# define _entcode_H (1) -# include -# include -# include "ecintrin.h" - -/*OPT: ec_window must be at least 32 bits, but if you have fast arithmetic on a - larger type, you can speed up the decoder by using it here.*/ -typedef opus_uint32 ec_window; -typedef struct ec_ctx ec_ctx; -typedef struct ec_ctx ec_enc; -typedef struct ec_ctx ec_dec; - -# define EC_WINDOW_SIZE ((int)sizeof(ec_window)*CHAR_BIT) - -/*The number of bits to use for the range-coded part of unsigned integers.*/ -# define EC_UINT_BITS (8) - -/*The resolution of fractional-precision bit usage measurements, i.e., - 3 => 1/8th bits.*/ -# define BITRES 3 - -/*The entropy encoder/decoder context. - We use the same structure for both, so that common functions like ec_tell() - can be used on either one.*/ -struct ec_ctx{ - /*Buffered input/output.*/ - unsigned char *buf; - /*The size of the buffer.*/ - opus_uint32 storage; - /*The offset at which the last byte containing raw bits was read/written.*/ - opus_uint32 end_offs; - /*Bits that will be read from/written at the end.*/ - ec_window end_window; - /*Number of valid bits in end_window.*/ - int nend_bits; - /*The total number of whole bits read/written. - This does not include partial bits currently in the range coder.*/ - int nbits_total; - /*The offset at which the next range coder byte will be read/written.*/ - opus_uint32 offs; - /*The number of values in the current range.*/ - opus_uint32 rng; - /*In the decoder: the difference between the top of the current range and - the input value, minus one. - In the encoder: the low end of the current range.*/ - opus_uint32 val; - /*In the decoder: the saved normalization factor from ec_decode(). - In the encoder: the number of oustanding carry propagating symbols.*/ - opus_uint32 ext; - /*A buffered input/output symbol, awaiting carry propagation.*/ - int rem; - /*Nonzero if an error occurred.*/ - int error; -}; - -static inline opus_uint32 ec_range_bytes(ec_ctx *_this){ - return _this->offs; -} - -static inline unsigned char *ec_get_buffer(ec_ctx *_this){ - return _this->buf; -} - -static inline int ec_get_error(ec_ctx *_this){ - return _this->error; -} - -/*Returns the number of bits "used" by the encoded or decoded symbols so far. - This same number can be computed in either the encoder or the decoder, and is - suitable for making coding decisions. - Return: The number of bits. - This will always be slightly larger than the exact value (e.g., all - rounding error is in the positive direction).*/ -static inline int ec_tell(ec_ctx *_this){ - return _this->nbits_total-EC_ILOG(_this->rng); -} - -/*Returns the number of bits "used" by the encoded or decoded symbols so far. - This same number can be computed in either the encoder or the decoder, and is - suitable for making coding decisions. - Return: The number of bits scaled by 2**BITRES. - This will always be slightly larger than the exact value (e.g., all - rounding error is in the positive direction).*/ -opus_uint32 ec_tell_frac(ec_ctx *_this); - -#endif diff --git a/src/opus-1.0.2/celt/entdec.c b/src/opus-1.0.2/celt/entdec.c deleted file mode 100644 index 75e3e45a..00000000 --- a/src/opus-1.0.2/celt/entdec.c +++ /dev/null @@ -1,245 +0,0 @@ -/* Copyright (c) 2001-2011 Timothy B. Terriberry - Copyright (c) 2008-2009 Xiph.Org Foundation */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "os_support.h" -#include "arch.h" -#include "entdec.h" -#include "mfrngcod.h" - -/*A range decoder. - This is an entropy decoder based upon \cite{Mar79}, which is itself a - rediscovery of the FIFO arithmetic code introduced by \cite{Pas76}. - It is very similar to arithmetic encoding, except that encoding is done with - digits in any base, instead of with bits, and so it is faster when using - larger bases (i.e.: a byte). - The author claims an average waste of $\frac{1}{2}\log_b(2b)$ bits, where $b$ - is the base, longer than the theoretical optimum, but to my knowledge there - is no published justification for this claim. - This only seems true when using near-infinite precision arithmetic so that - the process is carried out with no rounding errors. - - An excellent description of implementation details is available at - http://www.arturocampos.com/ac_range.html - A recent work \cite{MNW98} which proposes several changes to arithmetic - encoding for efficiency actually re-discovers many of the principles - behind range encoding, and presents a good theoretical analysis of them. - - End of stream is handled by writing out the smallest number of bits that - ensures that the stream will be correctly decoded regardless of the value of - any subsequent bits. - ec_tell() can be used to determine how many bits were needed to decode - all the symbols thus far; other data can be packed in the remaining bits of - the input buffer. - @PHDTHESIS{Pas76, - author="Richard Clark Pasco", - title="Source coding algorithms for fast data compression", - school="Dept. of Electrical Engineering, Stanford University", - address="Stanford, CA", - month=May, - year=1976 - } - @INPROCEEDINGS{Mar79, - author="Martin, G.N.N.", - title="Range encoding: an algorithm for removing redundancy from a digitised - message", - booktitle="Video & Data Recording Conference", - year=1979, - address="Southampton", - month=Jul - } - @ARTICLE{MNW98, - author="Alistair Moffat and Radford Neal and Ian H. Witten", - title="Arithmetic Coding Revisited", - journal="{ACM} Transactions on Information Systems", - year=1998, - volume=16, - number=3, - pages="256--294", - month=Jul, - URL="http://www.stanford.edu/class/ee398/handouts/papers/Moffat98ArithmCoding.pdf" - }*/ - -static int ec_read_byte(ec_dec *_this){ - return _this->offs<_this->storage?_this->buf[_this->offs++]:0; -} - -static int ec_read_byte_from_end(ec_dec *_this){ - return _this->end_offs<_this->storage? - _this->buf[_this->storage-++(_this->end_offs)]:0; -} - -/*Normalizes the contents of val and rng so that rng lies entirely in the - high-order symbol.*/ -static void ec_dec_normalize(ec_dec *_this){ - /*If the range is too small, rescale it and input some bits.*/ - while(_this->rng<=EC_CODE_BOT){ - int sym; - _this->nbits_total+=EC_SYM_BITS; - _this->rng<<=EC_SYM_BITS; - /*Use up the remaining bits from our last symbol.*/ - sym=_this->rem; - /*Read the next value from the input.*/ - _this->rem=ec_read_byte(_this); - /*Take the rest of the bits we need from this new symbol.*/ - sym=(sym<rem)>>(EC_SYM_BITS-EC_CODE_EXTRA); - /*And subtract them from val, capped to be less than EC_CODE_TOP.*/ - _this->val=((_this->val<buf=_buf; - _this->storage=_storage; - _this->end_offs=0; - _this->end_window=0; - _this->nend_bits=0; - /*This is the offset from which ec_tell() will subtract partial bits. - The final value after the ec_dec_normalize() call will be the same as in - the encoder, but we have to compensate for the bits that are added there.*/ - _this->nbits_total=EC_CODE_BITS+1 - -((EC_CODE_BITS-EC_CODE_EXTRA)/EC_SYM_BITS)*EC_SYM_BITS; - _this->offs=0; - _this->rng=1U<rem=ec_read_byte(_this); - _this->val=_this->rng-1-(_this->rem>>(EC_SYM_BITS-EC_CODE_EXTRA)); - _this->error=0; - /*Normalize the interval.*/ - ec_dec_normalize(_this); -} - -unsigned ec_decode(ec_dec *_this,unsigned _ft){ - unsigned s; - _this->ext=_this->rng/_ft; - s=(unsigned)(_this->val/_this->ext); - return _ft-EC_MINI(s+1,_ft); -} - -unsigned ec_decode_bin(ec_dec *_this,unsigned _bits){ - unsigned s; - _this->ext=_this->rng>>_bits; - s=(unsigned)(_this->val/_this->ext); - return (1U<<_bits)-EC_MINI(s+1U,1U<<_bits); -} - -void ec_dec_update(ec_dec *_this,unsigned _fl,unsigned _fh,unsigned _ft){ - opus_uint32 s; - s=IMUL32(_this->ext,_ft-_fh); - _this->val-=s; - _this->rng=_fl>0?IMUL32(_this->ext,_fh-_fl):_this->rng-s; - ec_dec_normalize(_this); -} - -/*The probability of having a "one" is 1/(1<<_logp).*/ -int ec_dec_bit_logp(ec_dec *_this,unsigned _logp){ - opus_uint32 r; - opus_uint32 d; - opus_uint32 s; - int ret; - r=_this->rng; - d=_this->val; - s=r>>_logp; - ret=dval=d-s; - _this->rng=ret?s:r-s; - ec_dec_normalize(_this); - return ret; -} - -int ec_dec_icdf(ec_dec *_this,const unsigned char *_icdf,unsigned _ftb){ - opus_uint32 r; - opus_uint32 d; - opus_uint32 s; - opus_uint32 t; - int ret; - s=_this->rng; - d=_this->val; - r=s>>_ftb; - ret=-1; - do{ - t=s; - s=IMUL32(r,_icdf[++ret]); - } - while(dval=d-s; - _this->rng=t-s; - ec_dec_normalize(_this); - return ret; -} - -opus_uint32 ec_dec_uint(ec_dec *_this,opus_uint32 _ft){ - unsigned ft; - unsigned s; - int ftb; - /*In order to optimize EC_ILOG(), it is undefined for the value 0.*/ - celt_assert(_ft>1); - _ft--; - ftb=EC_ILOG(_ft); - if(ftb>EC_UINT_BITS){ - opus_uint32 t; - ftb-=EC_UINT_BITS; - ft=(unsigned)(_ft>>ftb)+1; - s=ec_decode(_this,ft); - ec_dec_update(_this,s,s+1,ft); - t=(opus_uint32)s<error=1; - return _ft; - } - else{ - _ft++; - s=ec_decode(_this,(unsigned)_ft); - ec_dec_update(_this,s,s+1,(unsigned)_ft); - return s; - } -} - -opus_uint32 ec_dec_bits(ec_dec *_this,unsigned _bits){ - ec_window window; - int available; - opus_uint32 ret; - window=_this->end_window; - available=_this->nend_bits; - if((unsigned)available<_bits){ - do{ - window|=(ec_window)ec_read_byte_from_end(_this)<>=_bits; - available-=_bits; - _this->end_window=window; - _this->nend_bits=available; - _this->nbits_total+=_bits; - return ret; -} diff --git a/src/opus-1.0.2/celt/entdec.h b/src/opus-1.0.2/celt/entdec.h deleted file mode 100644 index d8ab3187..00000000 --- a/src/opus-1.0.2/celt/entdec.h +++ /dev/null @@ -1,100 +0,0 @@ -/* Copyright (c) 2001-2011 Timothy B. Terriberry - Copyright (c) 2008-2009 Xiph.Org Foundation */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#if !defined(_entdec_H) -# define _entdec_H (1) -# include -# include "entcode.h" - -/*Initializes the decoder. - _buf: The input buffer to use. - Return: 0 on success, or a negative value on error.*/ -void ec_dec_init(ec_dec *_this,unsigned char *_buf,opus_uint32 _storage); - -/*Calculates the cumulative frequency for the next symbol. - This can then be fed into the probability model to determine what that - symbol is, and the additional frequency information required to advance to - the next symbol. - This function cannot be called more than once without a corresponding call to - ec_dec_update(), or decoding will not proceed correctly. - _ft: The total frequency of the symbols in the alphabet the next symbol was - encoded with. - Return: A cumulative frequency representing the encoded symbol. - If the cumulative frequency of all the symbols before the one that - was encoded was fl, and the cumulative frequency of all the symbols - up to and including the one encoded is fh, then the returned value - will fall in the range [fl,fh).*/ -unsigned ec_decode(ec_dec *_this,unsigned _ft); - -/*Equivalent to ec_decode() with _ft==1<<_bits.*/ -unsigned ec_decode_bin(ec_dec *_this,unsigned _bits); - -/*Advance the decoder past the next symbol using the frequency information the - symbol was encoded with. - Exactly one call to ec_decode() must have been made so that all necessary - intermediate calculations are performed. - _fl: The cumulative frequency of all symbols that come before the symbol - decoded. - _fh: The cumulative frequency of all symbols up to and including the symbol - decoded. - Together with _fl, this defines the range [_fl,_fh) in which the value - returned above must fall. - _ft: The total frequency of the symbols in the alphabet the symbol decoded - was encoded in. - This must be the same as passed to the preceding call to ec_decode().*/ -void ec_dec_update(ec_dec *_this,unsigned _fl,unsigned _fh,unsigned _ft); - -/* Decode a bit that has a 1/(1<<_logp) probability of being a one */ -int ec_dec_bit_logp(ec_dec *_this,unsigned _logp); - -/*Decodes a symbol given an "inverse" CDF table. - No call to ec_dec_update() is necessary after this call. - _icdf: The "inverse" CDF, such that symbol s falls in the range - [s>0?ft-_icdf[s-1]:0,ft-_icdf[s]), where ft=1<<_ftb. - The values must be monotonically non-increasing, and the last value - must be 0. - _ftb: The number of bits of precision in the cumulative distribution. - Return: The decoded symbol s.*/ -int ec_dec_icdf(ec_dec *_this,const unsigned char *_icdf,unsigned _ftb); - -/*Extracts a raw unsigned integer with a non-power-of-2 range from the stream. - The bits must have been encoded with ec_enc_uint(). - No call to ec_dec_update() is necessary after this call. - _ft: The number of integers that can be decoded (one more than the max). - This must be at least one, and no more than 2**32-1. - Return: The decoded bits.*/ -opus_uint32 ec_dec_uint(ec_dec *_this,opus_uint32 _ft); - -/*Extracts a sequence of raw bits from the stream. - The bits must have been encoded with ec_enc_bits(). - No call to ec_dec_update() is necessary after this call. - _ftb: The number of bits to extract. - This must be between 0 and 25, inclusive. - Return: The decoded bits.*/ -opus_uint32 ec_dec_bits(ec_dec *_this,unsigned _ftb); - -#endif diff --git a/src/opus-1.0.2/celt/entenc.c b/src/opus-1.0.2/celt/entenc.c deleted file mode 100644 index a7e34ece..00000000 --- a/src/opus-1.0.2/celt/entenc.c +++ /dev/null @@ -1,294 +0,0 @@ -/* Copyright (c) 2001-2011 Timothy B. Terriberry - Copyright (c) 2008-2009 Xiph.Org Foundation */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#if defined(HAVE_CONFIG_H) -# include "config.h" -#endif -#include "os_support.h" -#include "arch.h" -#include "entenc.h" -#include "mfrngcod.h" - -/*A range encoder. - See entdec.c and the references for implementation details \cite{Mar79,MNW98}. - - @INPROCEEDINGS{Mar79, - author="Martin, G.N.N.", - title="Range encoding: an algorithm for removing redundancy from a digitised - message", - booktitle="Video \& Data Recording Conference", - year=1979, - address="Southampton", - month=Jul - } - @ARTICLE{MNW98, - author="Alistair Moffat and Radford Neal and Ian H. Witten", - title="Arithmetic Coding Revisited", - journal="{ACM} Transactions on Information Systems", - year=1998, - volume=16, - number=3, - pages="256--294", - month=Jul, - URL="http://www.stanford.edu/class/ee398/handouts/papers/Moffat98ArithmCoding.pdf" - }*/ - -static int ec_write_byte(ec_enc *_this,unsigned _value){ - if(_this->offs+_this->end_offs>=_this->storage)return -1; - _this->buf[_this->offs++]=(unsigned char)_value; - return 0; -} - -static int ec_write_byte_at_end(ec_enc *_this,unsigned _value){ - if(_this->offs+_this->end_offs>=_this->storage)return -1; - _this->buf[_this->storage-++(_this->end_offs)]=(unsigned char)_value; - return 0; -} - -/*Outputs a symbol, with a carry bit. - If there is a potential to propagate a carry over several symbols, they are - buffered until it can be determined whether or not an actual carry will - occur. - If the counter for the buffered symbols overflows, then the stream becomes - undecodable. - This gives a theoretical limit of a few billion symbols in a single packet on - 32-bit systems. - The alternative is to truncate the range in order to force a carry, but - requires similar carry tracking in the decoder, needlessly slowing it down.*/ -static void ec_enc_carry_out(ec_enc *_this,int _c){ - if(_c!=EC_SYM_MAX){ - /*No further carry propagation possible, flush buffer.*/ - int carry; - carry=_c>>EC_SYM_BITS; - /*Don't output a byte on the first write. - This compare should be taken care of by branch-prediction thereafter.*/ - if(_this->rem>=0)_this->error|=ec_write_byte(_this,_this->rem+carry); - if(_this->ext>0){ - unsigned sym; - sym=(EC_SYM_MAX+carry)&EC_SYM_MAX; - do _this->error|=ec_write_byte(_this,sym); - while(--(_this->ext)>0); - } - _this->rem=_c&EC_SYM_MAX; - } - else _this->ext++; -} - -static void ec_enc_normalize(ec_enc *_this){ - /*If the range is too small, output some bits and rescale it.*/ - while(_this->rng<=EC_CODE_BOT){ - ec_enc_carry_out(_this,(int)(_this->val>>EC_CODE_SHIFT)); - /*Move the next-to-high-order symbol into the high-order position.*/ - _this->val=(_this->val<rng<<=EC_SYM_BITS; - _this->nbits_total+=EC_SYM_BITS; - } -} - -void ec_enc_init(ec_enc *_this,unsigned char *_buf,opus_uint32 _size){ - _this->buf=_buf; - _this->end_offs=0; - _this->end_window=0; - _this->nend_bits=0; - /*This is the offset from which ec_tell() will subtract partial bits.*/ - _this->nbits_total=EC_CODE_BITS+1; - _this->offs=0; - _this->rng=EC_CODE_TOP; - _this->rem=-1; - _this->val=0; - _this->ext=0; - _this->storage=_size; - _this->error=0; -} - -void ec_encode(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _ft){ - opus_uint32 r; - r=_this->rng/_ft; - if(_fl>0){ - _this->val+=_this->rng-IMUL32(r,(_ft-_fl)); - _this->rng=IMUL32(r,(_fh-_fl)); - } - else _this->rng-=IMUL32(r,(_ft-_fh)); - ec_enc_normalize(_this); -} - -void ec_encode_bin(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _bits){ - opus_uint32 r; - r=_this->rng>>_bits; - if(_fl>0){ - _this->val+=_this->rng-IMUL32(r,((1U<<_bits)-_fl)); - _this->rng=IMUL32(r,(_fh-_fl)); - } - else _this->rng-=IMUL32(r,((1U<<_bits)-_fh)); - ec_enc_normalize(_this); -} - -/*The probability of having a "one" is 1/(1<<_logp).*/ -void ec_enc_bit_logp(ec_enc *_this,int _val,unsigned _logp){ - opus_uint32 r; - opus_uint32 s; - opus_uint32 l; - r=_this->rng; - l=_this->val; - s=r>>_logp; - r-=s; - if(_val)_this->val=l+r; - _this->rng=_val?s:r; - ec_enc_normalize(_this); -} - -void ec_enc_icdf(ec_enc *_this,int _s,const unsigned char *_icdf,unsigned _ftb){ - opus_uint32 r; - r=_this->rng>>_ftb; - if(_s>0){ - _this->val+=_this->rng-IMUL32(r,_icdf[_s-1]); - _this->rng=IMUL32(r,_icdf[_s-1]-_icdf[_s]); - } - else _this->rng-=IMUL32(r,_icdf[_s]); - ec_enc_normalize(_this); -} - -void ec_enc_uint(ec_enc *_this,opus_uint32 _fl,opus_uint32 _ft){ - unsigned ft; - unsigned fl; - int ftb; - /*In order to optimize EC_ILOG(), it is undefined for the value 0.*/ - celt_assert(_ft>1); - _ft--; - ftb=EC_ILOG(_ft); - if(ftb>EC_UINT_BITS){ - ftb-=EC_UINT_BITS; - ft=(_ft>>ftb)+1; - fl=(unsigned)(_fl>>ftb); - ec_encode(_this,fl,fl+1,ft); - ec_enc_bits(_this,_fl&(((opus_uint32)1<end_window; - used=_this->nend_bits; - celt_assert(_bits>0); - if(used+_bits>EC_WINDOW_SIZE){ - do{ - _this->error|=ec_write_byte_at_end(_this,(unsigned)window&EC_SYM_MAX); - window>>=EC_SYM_BITS; - used-=EC_SYM_BITS; - } - while(used>=EC_SYM_BITS); - } - window|=(ec_window)_fl<end_window=window; - _this->nend_bits=used; - _this->nbits_total+=_bits; -} - -void ec_enc_patch_initial_bits(ec_enc *_this,unsigned _val,unsigned _nbits){ - int shift; - unsigned mask; - celt_assert(_nbits<=EC_SYM_BITS); - shift=EC_SYM_BITS-_nbits; - mask=((1<<_nbits)-1)<offs>0){ - /*The first byte has been finalized.*/ - _this->buf[0]=(unsigned char)((_this->buf[0]&~mask)|_val<rem>=0){ - /*The first byte is still awaiting carry propagation.*/ - _this->rem=(_this->rem&~mask)|_val<rng<=(EC_CODE_TOP>>_nbits)){ - /*The renormalization loop has never been run.*/ - _this->val=(_this->val&~((opus_uint32)mask<error=-1; -} - -void ec_enc_shrink(ec_enc *_this,opus_uint32 _size){ - celt_assert(_this->offs+_this->end_offs<=_size); - OPUS_MOVE(_this->buf+_size-_this->end_offs, - _this->buf+_this->storage-_this->end_offs,_this->end_offs); - _this->storage=_size; -} - -void ec_enc_done(ec_enc *_this){ - ec_window window; - int used; - opus_uint32 msk; - opus_uint32 end; - int l; - /*We output the minimum number of bits that ensures that the symbols encoded - thus far will be decoded correctly regardless of the bits that follow.*/ - l=EC_CODE_BITS-EC_ILOG(_this->rng); - msk=(EC_CODE_TOP-1)>>l; - end=(_this->val+msk)&~msk; - if((end|msk)>=_this->val+_this->rng){ - l++; - msk>>=1; - end=(_this->val+msk)&~msk; - } - while(l>0){ - ec_enc_carry_out(_this,(int)(end>>EC_CODE_SHIFT)); - end=(end<rem>=0||_this->ext>0)ec_enc_carry_out(_this,0); - /*If we have buffered extra bits, flush them as well.*/ - window=_this->end_window; - used=_this->nend_bits; - while(used>=EC_SYM_BITS){ - _this->error|=ec_write_byte_at_end(_this,(unsigned)window&EC_SYM_MAX); - window>>=EC_SYM_BITS; - used-=EC_SYM_BITS; - } - /*Clear any excess space and add any remaining extra bits to the last byte.*/ - if(!_this->error){ - OPUS_CLEAR(_this->buf+_this->offs, - _this->storage-_this->offs-_this->end_offs); - if(used>0){ - /*If there's no range coder data at all, give up.*/ - if(_this->end_offs>=_this->storage)_this->error=-1; - else{ - l=-l; - /*If we've busted, don't add too many extra bits to the last byte; it - would corrupt the range coder data, and that's more important.*/ - if(_this->offs+_this->end_offs>=_this->storage&&lerror=-1; - } - _this->buf[_this->storage-_this->end_offs-1]|=(unsigned char)window; - } - } - } -} diff --git a/src/opus-1.0.2/celt/entenc.h b/src/opus-1.0.2/celt/entenc.h deleted file mode 100644 index 796bc4d5..00000000 --- a/src/opus-1.0.2/celt/entenc.h +++ /dev/null @@ -1,110 +0,0 @@ -/* Copyright (c) 2001-2011 Timothy B. Terriberry - Copyright (c) 2008-2009 Xiph.Org Foundation */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#if !defined(_entenc_H) -# define _entenc_H (1) -# include -# include "entcode.h" - -/*Initializes the encoder. - _buf: The buffer to store output bytes in. - _size: The size of the buffer, in chars.*/ -void ec_enc_init(ec_enc *_this,unsigned char *_buf,opus_uint32 _size); -/*Encodes a symbol given its frequency information. - The frequency information must be discernable by the decoder, assuming it - has read only the previous symbols from the stream. - It is allowable to change the frequency information, or even the entire - source alphabet, so long as the decoder can tell from the context of the - previously encoded information that it is supposed to do so as well. - _fl: The cumulative frequency of all symbols that come before the one to be - encoded. - _fh: The cumulative frequency of all symbols up to and including the one to - be encoded. - Together with _fl, this defines the range [_fl,_fh) in which the - decoded value will fall. - _ft: The sum of the frequencies of all the symbols*/ -void ec_encode(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _ft); - -/*Equivalent to ec_encode() with _ft==1<<_bits.*/ -void ec_encode_bin(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _bits); - -/* Encode a bit that has a 1/(1<<_logp) probability of being a one */ -void ec_enc_bit_logp(ec_enc *_this,int _val,unsigned _logp); - -/*Encodes a symbol given an "inverse" CDF table. - _s: The index of the symbol to encode. - _icdf: The "inverse" CDF, such that symbol _s falls in the range - [_s>0?ft-_icdf[_s-1]:0,ft-_icdf[_s]), where ft=1<<_ftb. - The values must be monotonically non-increasing, and the last value - must be 0. - _ftb: The number of bits of precision in the cumulative distribution.*/ -void ec_enc_icdf(ec_enc *_this,int _s,const unsigned char *_icdf,unsigned _ftb); - -/*Encodes a raw unsigned integer in the stream. - _fl: The integer to encode. - _ft: The number of integers that can be encoded (one more than the max). - This must be at least one, and no more than 2**32-1.*/ -void ec_enc_uint(ec_enc *_this,opus_uint32 _fl,opus_uint32 _ft); - -/*Encodes a sequence of raw bits in the stream. - _fl: The bits to encode. - _ftb: The number of bits to encode. - This must be between 1 and 25, inclusive.*/ -void ec_enc_bits(ec_enc *_this,opus_uint32 _fl,unsigned _ftb); - -/*Overwrites a few bits at the very start of an existing stream, after they - have already been encoded. - This makes it possible to have a few flags up front, where it is easy for - decoders to access them without parsing the whole stream, even if their - values are not determined until late in the encoding process, without having - to buffer all the intermediate symbols in the encoder. - In order for this to work, at least _nbits bits must have already been - encoded using probabilities that are an exact power of two. - The encoder can verify the number of encoded bits is sufficient, but cannot - check this latter condition. - _val: The bits to encode (in the least _nbits significant bits). - They will be decoded in order from most-significant to least. - _nbits: The number of bits to overwrite. - This must be no more than 8.*/ -void ec_enc_patch_initial_bits(ec_enc *_this,unsigned _val,unsigned _nbits); - -/*Compacts the data to fit in the target size. - This moves up the raw bits at the end of the current buffer so they are at - the end of the new buffer size. - The caller must ensure that the amount of data that's already been written - will fit in the new size. - _size: The number of bytes in the new buffer. - This must be large enough to contain the bits already written, and - must be no larger than the existing size.*/ -void ec_enc_shrink(ec_enc *_this,opus_uint32 _size); - -/*Indicates that there are no more symbols to encode. - All reamining output bytes are flushed to the output buffer. - ec_enc_init() must be called before the encoder can be used again.*/ -void ec_enc_done(ec_enc *_this); - -#endif diff --git a/src/opus-1.0.2/celt/fixed_debug.h b/src/opus-1.0.2/celt/fixed_debug.h deleted file mode 100644 index f11d890d..00000000 --- a/src/opus-1.0.2/celt/fixed_debug.h +++ /dev/null @@ -1,763 +0,0 @@ -/* Copyright (C) 2003-2008 Jean-Marc Valin - Copyright (C) 2007-2012 Xiph.Org Foundation */ -/** - @file fixed_debug.h - @brief Fixed-point operations with debugging -*/ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef FIXED_DEBUG_H -#define FIXED_DEBUG_H - -#include - -#ifdef CELT_C -#include "opus_defines.h" -OPUS_EXPORT opus_int64 celt_mips=0; -#else -extern opus_int64 celt_mips; -#endif - -#define MULT16_16SU(a,b) ((opus_val32)(opus_val16)(a)*(opus_val32)(opus_uint16)(b)) -#define MULT32_32_Q31(a,b) ADD32(ADD32(SHL32(MULT16_16(SHR32((a),16),SHR((b),16)),1), SHR32(MULT16_16SU(SHR32((a),16),((b)&0x0000ffff)),15)), SHR32(MULT16_16SU(SHR32((b),16),((a)&0x0000ffff)),15)) - -/** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */ -#define MULT16_32_Q16(a,b) ADD32(MULT16_16((a),SHR32((b),16)), SHR32(MULT16_16SU((a),((b)&0x0000ffff)),16)) - -#define MULT16_32_P16(a,b) MULT16_32_PX(a,b,16) - -#define QCONST16(x,bits) ((opus_val16)(.5+(x)*(((opus_val32)1)<<(bits)))) -#define QCONST32(x,bits) ((opus_val32)(.5+(x)*(((opus_val32)1)<<(bits)))) - -#define VERIFY_SHORT(x) ((x)<=32767&&(x)>=-32768) -#define VERIFY_INT(x) ((x)<=2147483647LL&&(x)>=-2147483648LL) -#define VERIFY_UINT(x) ((x)<=(2147483647LLU<<1)) - -#define SHR(a,b) SHR32(a,b) -#define PSHR(a,b) PSHR32(a,b) - -static inline short NEG16(int x) -{ - int res; - if (!VERIFY_SHORT(x)) - { - fprintf (stderr, "NEG16: input is not short: %d\n", (int)x); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - res = -x; - if (!VERIFY_SHORT(res)) - { - fprintf (stderr, "NEG16: output is not short: %d\n", (int)res); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - celt_mips++; - return res; -} -static inline int NEG32(opus_int64 x) -{ - opus_int64 res; - if (!VERIFY_INT(x)) - { - fprintf (stderr, "NEG16: input is not int: %d\n", (int)x); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - res = -x; - if (!VERIFY_INT(res)) - { - fprintf (stderr, "NEG16: output is not int: %d\n", (int)res); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - celt_mips+=2; - return res; -} - -#define EXTRACT16(x) EXTRACT16_(x, __FILE__, __LINE__) -static inline short EXTRACT16_(int x, char *file, int line) -{ - int res; - if (!VERIFY_SHORT(x)) - { - fprintf (stderr, "EXTRACT16: input is not short: %d in %s: line %d\n", x, file, line); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - res = x; - celt_mips++; - return res; -} - -#define EXTEND32(x) EXTEND32_(x, __FILE__, __LINE__) -static inline int EXTEND32_(int x, char *file, int line) -{ - int res; - if (!VERIFY_SHORT(x)) - { - fprintf (stderr, "EXTEND32: input is not short: %d in %s: line %d\n", x, file, line); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - res = x; - celt_mips++; - return res; -} - -#define SHR16(a, shift) SHR16_(a, shift, __FILE__, __LINE__) -static inline short SHR16_(int a, int shift, char *file, int line) -{ - int res; - if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift)) - { - fprintf (stderr, "SHR16: inputs are not short: %d >> %d in %s: line %d\n", a, shift, file, line); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - res = a>>shift; - if (!VERIFY_SHORT(res)) - { - fprintf (stderr, "SHR16: output is not short: %d in %s: line %d\n", res, file, line); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - celt_mips++; - return res; -} -#define SHL16(a, shift) SHL16_(a, shift, __FILE__, __LINE__) -static inline short SHL16_(int a, int shift, char *file, int line) -{ - int res; - if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift)) - { - fprintf (stderr, "SHL16: inputs are not short: %d %d in %s: line %d\n", a, shift, file, line); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - res = a<>shift; - if (!VERIFY_INT(res)) - { - fprintf (stderr, "SHR32: output is not int: %d\n", (int)res); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - celt_mips+=2; - return res; -} -#define SHL32(a, shift) SHL32_(a, shift, __FILE__, __LINE__) -static inline int SHL32_(opus_int64 a, int shift, char *file, int line) -{ - opus_int64 res; - if (!VERIFY_INT(a) || !VERIFY_SHORT(shift)) - { - fprintf (stderr, "SHL32: inputs are not int: %lld %d in %s: line %d\n", a, shift, file, line); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - res = a<>1))),shift)) -#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift))) - -#define ROUND16(x,a) (celt_mips--,EXTRACT16(PSHR32((x),(a)))) -#define HALF16(x) (SHR16(x,1)) -#define HALF32(x) (SHR32(x,1)) - -//#define SHR(a,shift) ((a) >> (shift)) -//#define SHL(a,shift) ((a) << (shift)) - -#define ADD16(a, b) ADD16_(a, b, __FILE__, __LINE__) -static inline short ADD16_(int a, int b, char *file, int line) -{ - int res; - if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) - { - fprintf (stderr, "ADD16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - res = a+b; - if (!VERIFY_SHORT(res)) - { - fprintf (stderr, "ADD16: output is not short: %d+%d=%d in %s: line %d\n", a,b,res, file, line); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - celt_mips++; - return res; -} - -#define SUB16(a, b) SUB16_(a, b, __FILE__, __LINE__) -static inline short SUB16_(int a, int b, char *file, int line) -{ - int res; - if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) - { - fprintf (stderr, "SUB16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - res = a-b; - if (!VERIFY_SHORT(res)) - { - fprintf (stderr, "SUB16: output is not short: %d in %s: line %d\n", res, file, line); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - celt_mips++; - return res; -} - -#define ADD32(a, b) ADD32_(a, b, __FILE__, __LINE__) -static inline int ADD32_(opus_int64 a, opus_int64 b, char *file, int line) -{ - opus_int64 res; - if (!VERIFY_INT(a) || !VERIFY_INT(b)) - { - fprintf (stderr, "ADD32: inputs are not int: %d %d in %s: line %d\n", (int)a, (int)b, file, line); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - res = a+b; - if (!VERIFY_INT(res)) - { - fprintf (stderr, "ADD32: output is not int: %d in %s: line %d\n", (int)res, file, line); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - celt_mips+=2; - return res; -} - -#define SUB32(a, b) SUB32_(a, b, __FILE__, __LINE__) -static inline int SUB32_(opus_int64 a, opus_int64 b, char *file, int line) -{ - opus_int64 res; - if (!VERIFY_INT(a) || !VERIFY_INT(b)) - { - fprintf (stderr, "SUB32: inputs are not int: %d %d in %s: line %d\n", (int)a, (int)b, file, line); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - res = a-b; - if (!VERIFY_INT(res)) - { - fprintf (stderr, "SUB32: output is not int: %d in %s: line %d\n", (int)res, file, line); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - celt_mips+=2; - return res; -} - -#undef UADD32 -#define UADD32(a, b) UADD32_(a, b, __FILE__, __LINE__) -static inline unsigned int UADD32_(opus_uint64 a, opus_uint64 b, char *file, int line) -{ - opus_uint64 res; - if (!VERIFY_UINT(a) || !VERIFY_UINT(b)) - { - fprintf (stderr, "UADD32: inputs are not uint32: %llu %llu in %s: line %d\n", a, b, file, line); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - res = a+b; - if (!VERIFY_UINT(res)) - { - fprintf (stderr, "UADD32: output is not uint32: %llu in %s: line %d\n", res, file, line); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - celt_mips+=2; - return res; -} - -#undef USUB32 -#define USUB32(a, b) USUB32_(a, b, __FILE__, __LINE__) -static inline unsigned int USUB32_(opus_uint64 a, opus_uint64 b, char *file, int line) -{ - opus_uint64 res; - if (!VERIFY_UINT(a) || !VERIFY_UINT(b)) - { - fprintf (stderr, "USUB32: inputs are not uint32: %llu %llu in %s: line %d\n", a, b, file, line); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - if (a=((opus_val32)(1)<<(15+Q))) - { - fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - res = (((opus_int64)a)*(opus_int64)b) >> Q; - if (!VERIFY_INT(res)) - { - fprintf (stderr, "MULT16_32_Q%d: output is not int: %d*%d=%d in %s: line %d\n", Q, (int)a, (int)b,(int)res, file, line); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - if (Q==15) - celt_mips+=3; - else - celt_mips+=4; - return res; -} - -#define MULT16_32_PX(a, b, Q) MULT16_32_PX_(a, b, Q, __FILE__, __LINE__) -static inline int MULT16_32_PX_(int a, opus_int64 b, int Q, char *file, int line) -{ - opus_int64 res; - if (!VERIFY_SHORT(a) || !VERIFY_INT(b)) - { - fprintf (stderr, "MULT16_32_P%d: inputs are not short+int: %d %d in %s: line %d\n\n", Q, (int)a, (int)b, file, line); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - if (ABS32(b)>=((opus_int64)(1)<<(15+Q))) - { - fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n\n", Q, (int)a, (int)b,file, line); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - res = ((((opus_int64)a)*(opus_int64)b) + (((opus_val32)(1)<>1))>> Q; - if (!VERIFY_INT(res)) - { - fprintf (stderr, "MULT16_32_P%d: output is not int: %d*%d=%d in %s: line %d\n\n", Q, (int)a, (int)b,(int)res, file, line); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - if (Q==15) - celt_mips+=4; - else - celt_mips+=5; - return res; -} - -#define MULT16_32_Q15(a,b) MULT16_32_QX(a,b,15) -#define MAC16_32_Q15(c,a,b) (celt_mips-=2,ADD32((c),MULT16_32_Q15((a),(b)))) - -static inline int SATURATE(int a, int b) -{ - if (a>b) - a=b; - if (a<-b) - a = -b; - celt_mips+=3; - return a; -} - -static inline int MULT16_16_Q11_32(int a, int b) -{ - opus_int64 res; - if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) - { - fprintf (stderr, "MULT16_16_Q11: inputs are not short: %d %d\n", a, b); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - res = ((opus_int64)a)*b; - res >>= 11; - if (!VERIFY_INT(res)) - { - fprintf (stderr, "MULT16_16_Q11: output is not short: %d*%d=%d\n", (int)a, (int)b, (int)res); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - celt_mips+=3; - return res; -} -static inline short MULT16_16_Q13(int a, int b) -{ - opus_int64 res; - if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) - { - fprintf (stderr, "MULT16_16_Q13: inputs are not short: %d %d\n", a, b); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - res = ((opus_int64)a)*b; - res >>= 13; - if (!VERIFY_SHORT(res)) - { - fprintf (stderr, "MULT16_16_Q13: output is not short: %d*%d=%d\n", a, b, (int)res); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - celt_mips+=3; - return res; -} -static inline short MULT16_16_Q14(int a, int b) -{ - opus_int64 res; - if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) - { - fprintf (stderr, "MULT16_16_Q14: inputs are not short: %d %d\n", a, b); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - res = ((opus_int64)a)*b; - res >>= 14; - if (!VERIFY_SHORT(res)) - { - fprintf (stderr, "MULT16_16_Q14: output is not short: %d\n", (int)res); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - celt_mips+=3; - return res; -} - -#define MULT16_16_Q15(a, b) MULT16_16_Q15_(a, b, __FILE__, __LINE__) -static inline short MULT16_16_Q15_(int a, int b, char *file, int line) -{ - opus_int64 res; - if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) - { - fprintf (stderr, "MULT16_16_Q15: inputs are not short: %d %d in %s: line %d\n", a, b, file, line); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - res = ((opus_int64)a)*b; - res >>= 15; - if (!VERIFY_SHORT(res)) - { - fprintf (stderr, "MULT16_16_Q15: output is not short: %d in %s: line %d\n", (int)res, file, line); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - celt_mips+=1; - return res; -} - -static inline short MULT16_16_P13(int a, int b) -{ - opus_int64 res; - if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) - { - fprintf (stderr, "MULT16_16_P13: inputs are not short: %d %d\n", a, b); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - res = ((opus_int64)a)*b; - res += 4096; - if (!VERIFY_INT(res)) - { - fprintf (stderr, "MULT16_16_P13: overflow: %d*%d=%d\n", a, b, (int)res); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - res >>= 13; - if (!VERIFY_SHORT(res)) - { - fprintf (stderr, "MULT16_16_P13: output is not short: %d*%d=%d\n", a, b, (int)res); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - celt_mips+=4; - return res; -} -static inline short MULT16_16_P14(int a, int b) -{ - opus_int64 res; - if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) - { - fprintf (stderr, "MULT16_16_P14: inputs are not short: %d %d\n", a, b); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - res = ((opus_int64)a)*b; - res += 8192; - if (!VERIFY_INT(res)) - { - fprintf (stderr, "MULT16_16_P14: overflow: %d*%d=%d\n", a, b, (int)res); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - res >>= 14; - if (!VERIFY_SHORT(res)) - { - fprintf (stderr, "MULT16_16_P14: output is not short: %d*%d=%d\n", a, b, (int)res); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - celt_mips+=4; - return res; -} -static inline short MULT16_16_P15(int a, int b) -{ - opus_int64 res; - if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) - { - fprintf (stderr, "MULT16_16_P15: inputs are not short: %d %d\n", a, b); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - res = ((opus_int64)a)*b; - res += 16384; - if (!VERIFY_INT(res)) - { - fprintf (stderr, "MULT16_16_P15: overflow: %d*%d=%d\n", a, b, (int)res); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - res >>= 15; - if (!VERIFY_SHORT(res)) - { - fprintf (stderr, "MULT16_16_P15: output is not short: %d*%d=%d\n", a, b, (int)res); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - celt_mips+=2; - return res; -} - -#define DIV32_16(a, b) DIV32_16_(a, b, __FILE__, __LINE__) - -static inline int DIV32_16_(opus_int64 a, opus_int64 b, char *file, int line) -{ - opus_int64 res; - if (b==0) - { - fprintf(stderr, "DIV32_16: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - return 0; - } - if (!VERIFY_INT(a) || !VERIFY_SHORT(b)) - { - fprintf (stderr, "DIV32_16: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - res = a/b; - if (!VERIFY_SHORT(res)) - { - fprintf (stderr, "DIV32_16: output is not short: %d / %d = %d in %s: line %d\n", (int)a,(int)b,(int)res, file, line); - if (res>32767) - res = 32767; - if (res<-32768) - res = -32768; -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - celt_mips+=35; - return res; -} - -#define DIV32(a, b) DIV32_(a, b, __FILE__, __LINE__) -static inline int DIV32_(opus_int64 a, opus_int64 b, char *file, int line) -{ - opus_int64 res; - if (b==0) - { - fprintf(stderr, "DIV32: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - return 0; - } - - if (!VERIFY_INT(a) || !VERIFY_INT(b)) - { - fprintf (stderr, "DIV32: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - res = a/b; - if (!VERIFY_INT(res)) - { - fprintf (stderr, "DIV32: output is not int: %d in %s: line %d\n", (int)res, file, line); -#ifdef FIXED_DEBUG_ASSERT - celt_assert(0); -#endif - } - celt_mips+=70; - return res; -} - -#undef PRINT_MIPS -#define PRINT_MIPS(file) do {fprintf (file, "total complexity = %llu MIPS\n", celt_mips);} while (0); - -#endif diff --git a/src/opus-1.0.2/celt/fixed_generic.h b/src/opus-1.0.2/celt/fixed_generic.h deleted file mode 100644 index 71e28d62..00000000 --- a/src/opus-1.0.2/celt/fixed_generic.h +++ /dev/null @@ -1,129 +0,0 @@ -/* Copyright (C) 2007-2009 Xiph.Org Foundation - Copyright (C) 2003-2008 Jean-Marc Valin - Copyright (C) 2007-2008 CSIRO */ -/** - @file fixed_generic.h - @brief Generic fixed-point operations -*/ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef FIXED_GENERIC_H -#define FIXED_GENERIC_H - -/** Multiply a 16-bit signed value by a 16-bit unsigned value. The result is a 32-bit signed value */ -#define MULT16_16SU(a,b) ((opus_val32)(opus_val16)(a)*(opus_val32)(opus_uint16)(b)) - -/** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */ -#define MULT16_32_Q16(a,b) ADD32(MULT16_16((a),SHR((b),16)), SHR(MULT16_16SU((a),((b)&0x0000ffff)),16)) - -/** 16x32 multiplication, followed by a 16-bit shift right (round-to-nearest). Results fits in 32 bits */ -#define MULT16_32_P16(a,b) ADD32(MULT16_16((a),SHR((b),16)), PSHR(MULT16_16((a),((b)&0x0000ffff)),16)) - -/** 16x32 multiplication, followed by a 15-bit shift right. Results fits in 32 bits */ -#define MULT16_32_Q15(a,b) ADD32(SHL(MULT16_16((a),SHR((b),16)),1), SHR(MULT16_16SU((a),((b)&0x0000ffff)),15)) - -/** 32x32 multiplication, followed by a 31-bit shift right. Results fits in 32 bits */ -#define MULT32_32_Q31(a,b) ADD32(ADD32(SHL(MULT16_16(SHR((a),16),SHR((b),16)),1), SHR(MULT16_16SU(SHR((a),16),((b)&0x0000ffff)),15)), SHR(MULT16_16SU(SHR((b),16),((a)&0x0000ffff)),15)) - -/** Compile-time conversion of float constant to 16-bit value */ -#define QCONST16(x,bits) ((opus_val16)(.5+(x)*(((opus_val32)1)<<(bits)))) - -/** Compile-time conversion of float constant to 32-bit value */ -#define QCONST32(x,bits) ((opus_val32)(.5+(x)*(((opus_val32)1)<<(bits)))) - -/** Negate a 16-bit value */ -#define NEG16(x) (-(x)) -/** Negate a 32-bit value */ -#define NEG32(x) (-(x)) - -/** Change a 32-bit value into a 16-bit value. The value is assumed to fit in 16-bit, otherwise the result is undefined */ -#define EXTRACT16(x) ((opus_val16)(x)) -/** Change a 16-bit value into a 32-bit value */ -#define EXTEND32(x) ((opus_val32)(x)) - -/** Arithmetic shift-right of a 16-bit value */ -#define SHR16(a,shift) ((a) >> (shift)) -/** Arithmetic shift-left of a 16-bit value */ -#define SHL16(a,shift) ((opus_int16)((opus_uint16)(a)<<(shift))) -/** Arithmetic shift-right of a 32-bit value */ -#define SHR32(a,shift) ((a) >> (shift)) -/** Arithmetic shift-left of a 32-bit value */ -#define SHL32(a,shift) ((opus_int32)((opus_uint32)(a)<<(shift))) - -/** 32-bit arithmetic shift right with rounding-to-nearest instead of rounding down */ -#define PSHR32(a,shift) (SHR32((a)+((EXTEND32(1)<<((shift))>>1)),shift)) -/** 32-bit arithmetic shift right where the argument can be negative */ -#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift))) - -/** "RAW" macros, should not be used outside of this header file */ -#define SHR(a,shift) ((a) >> (shift)) -#define SHL(a,shift) SHL32(a,shift) -#define PSHR(a,shift) (SHR((a)+((EXTEND32(1)<<((shift))>>1)),shift)) -#define SATURATE(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x))) - -/** Shift by a and round-to-neareast 32-bit value. Result is a 16-bit value */ -#define ROUND16(x,a) (EXTRACT16(PSHR32((x),(a)))) -/** Divide by two */ -#define HALF16(x) (SHR16(x,1)) -#define HALF32(x) (SHR32(x,1)) - -/** Add two 16-bit values */ -#define ADD16(a,b) ((opus_val16)((opus_val16)(a)+(opus_val16)(b))) -/** Subtract two 16-bit values */ -#define SUB16(a,b) ((opus_val16)(a)-(opus_val16)(b)) -/** Add two 32-bit values */ -#define ADD32(a,b) ((opus_val32)(a)+(opus_val32)(b)) -/** Subtract two 32-bit values */ -#define SUB32(a,b) ((opus_val32)(a)-(opus_val32)(b)) - -/** 16x16 multiplication where the result fits in 16 bits */ -#define MULT16_16_16(a,b) ((((opus_val16)(a))*((opus_val16)(b)))) - -/* (opus_val32)(opus_val16) gives TI compiler a hint that it's 16x16->32 multiply */ -/** 16x16 multiplication where the result fits in 32 bits */ -#define MULT16_16(a,b) (((opus_val32)(opus_val16)(a))*((opus_val32)(opus_val16)(b))) - -/** 16x16 multiply-add where the result fits in 32 bits */ -#define MAC16_16(c,a,b) (ADD32((c),MULT16_16((a),(b)))) -/** 16x32 multiply-add, followed by a 15-bit shift right. Results fits in 32 bits */ -#define MAC16_32_Q15(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15))) - -#define MULT16_16_Q11_32(a,b) (SHR(MULT16_16((a),(b)),11)) -#define MULT16_16_Q13(a,b) (SHR(MULT16_16((a),(b)),13)) -#define MULT16_16_Q14(a,b) (SHR(MULT16_16((a),(b)),14)) -#define MULT16_16_Q15(a,b) (SHR(MULT16_16((a),(b)),15)) - -#define MULT16_16_P13(a,b) (SHR(ADD32(4096,MULT16_16((a),(b))),13)) -#define MULT16_16_P14(a,b) (SHR(ADD32(8192,MULT16_16((a),(b))),14)) -#define MULT16_16_P15(a,b) (SHR(ADD32(16384,MULT16_16((a),(b))),15)) - -/** Divide a 32-bit value by a 16-bit value. Result fits in 16 bits */ -#define DIV32_16(a,b) ((opus_val16)(((opus_val32)(a))/((opus_val16)(b)))) - -/** Divide a 32-bit value by a 32-bit value. Result fits in 32 bits */ -#define DIV32(a,b) (((opus_val32)(a))/((opus_val32)(b))) - -#endif diff --git a/src/opus-1.0.2/celt/float_cast.h b/src/opus-1.0.2/celt/float_cast.h deleted file mode 100644 index 5ded2915..00000000 --- a/src/opus-1.0.2/celt/float_cast.h +++ /dev/null @@ -1,140 +0,0 @@ -/* Copyright (C) 2001 Erik de Castro Lopo */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* Version 1.1 */ - -#ifndef FLOAT_CAST_H -#define FLOAT_CAST_H - - -#include "arch.h" - -/*============================================================================ -** On Intel Pentium processors (especially PIII and probably P4), converting -** from float to int is very slow. To meet the C specs, the code produced by -** most C compilers targeting Pentium needs to change the FPU rounding mode -** before the float to int conversion is performed. -** -** Changing the FPU rounding mode causes the FPU pipeline to be flushed. It -** is this flushing of the pipeline which is so slow. -** -** Fortunately the ISO C99 specifications define the functions lrint, lrintf, -** llrint and llrintf which fix this problem as a side effect. -** -** On Unix-like systems, the configure process should have detected the -** presence of these functions. If they weren't found we have to replace them -** here with a standard C cast. -*/ - -/* -** The C99 prototypes for lrint and lrintf are as follows: -** -** long int lrintf (float x) ; -** long int lrint (double x) ; -*/ - -/* The presence of the required functions are detected during the configure -** process and the values HAVE_LRINT and HAVE_LRINTF are set accordingly in -** the config.h file. -*/ - -#if (HAVE_LRINTF) - -/* These defines enable functionality introduced with the 1999 ISO C -** standard. They must be defined before the inclusion of math.h to -** engage them. If optimisation is enabled, these functions will be -** inlined. With optimisation switched off, you have to link in the -** maths library using -lm. -*/ - -#define _ISOC9X_SOURCE 1 -#define _ISOC99_SOURCE 1 - -#define __USE_ISOC9X 1 -#define __USE_ISOC99 1 - -#include -#define float2int(x) lrintf(x) - -#elif (defined(HAVE_LRINT)) - -#define _ISOC9X_SOURCE 1 -#define _ISOC99_SOURCE 1 - -#define __USE_ISOC9X 1 -#define __USE_ISOC99 1 - -#include -#define float2int(x) lrint(x) - -#elif (defined(_MSC_VER) && _MSC_VER >= 1400) && (defined (WIN64) || defined (_WIN64)) - #include - - __inline long int float2int(float value) - { - return _mm_cvtss_si32(_mm_load_ss(&value)); - } -#elif (defined(_MSC_VER) && _MSC_VER >= 1400) && (defined (WIN32) || defined (_WIN32)) - #include - - /* Win32 doesn't seem to have these functions. - ** Therefore implement inline versions of these functions here. - */ - - __inline long int - float2int (float flt) - { int intgr; - - _asm - { fld flt - fistp intgr - } ; - - return intgr ; - } - -#else - -#if (defined(__GNUC__) && defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) - /* supported by gcc in C99 mode, but not by all other compilers */ - #warning "Don't have the functions lrint() and lrintf ()." - #warning "Replacing these functions with a standard C cast." -#endif /* __STDC_VERSION__ >= 199901L */ - #include - #define float2int(flt) ((int)(floor(.5+flt))) -#endif - -#ifndef DISABLE_FLOAT_API -static inline opus_int16 FLOAT2INT16(float x) -{ - x = x*CELT_SIG_SCALE; - x = MAX32(x, -32768); - x = MIN32(x, 32767); - return (opus_int16)float2int(x); -} -#endif /* DISABLE_FLOAT_API */ - -#endif /* FLOAT_CAST_H */ diff --git a/src/opus-1.0.2/celt/kiss_fft.c b/src/opus-1.0.2/celt/kiss_fft.c deleted file mode 100644 index dcd69686..00000000 --- a/src/opus-1.0.2/celt/kiss_fft.c +++ /dev/null @@ -1,722 +0,0 @@ -/*Copyright (c) 2003-2004, Mark Borgerding - Lots of modifications by Jean-Marc Valin - Copyright (c) 2005-2007, Xiph.Org Foundation - Copyright (c) 2008, Xiph.Org Foundation, CSIRO - - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE.*/ - -/* This code is originally from Mark Borgerding's KISS-FFT but has been - heavily modified to better suit Opus */ - -#ifndef SKIP_CONFIG_H -# ifdef HAVE_CONFIG_H -# include "config.h" -# endif -#endif - -#include "_kiss_fft_guts.h" -#include "arch.h" -#include "os_support.h" -#include "mathops.h" -#include "stack_alloc.h" -#include "os_support.h" - -/* The guts header contains all the multiplication and addition macros that are defined for - complex numbers. It also delares the kf_ internal functions. -*/ - -static void kf_bfly2( - kiss_fft_cpx * Fout, - const size_t fstride, - const kiss_fft_state *st, - int m, - int N, - int mm - ) -{ - kiss_fft_cpx * Fout2; - const kiss_twiddle_cpx * tw1; - int i,j; - kiss_fft_cpx * Fout_beg = Fout; - for (i=0;itwiddles; - for(j=0;jr = SHR32(Fout->r, 1);Fout->i = SHR32(Fout->i, 1); - Fout2->r = SHR32(Fout2->r, 1);Fout2->i = SHR32(Fout2->i, 1); - C_MUL (t, *Fout2 , *tw1); - tw1 += fstride; - C_SUB( *Fout2 , *Fout , t ); - C_ADDTO( *Fout , t ); - ++Fout2; - ++Fout; - } - } -} - -static void ki_bfly2( - kiss_fft_cpx * Fout, - const size_t fstride, - const kiss_fft_state *st, - int m, - int N, - int mm - ) -{ - kiss_fft_cpx * Fout2; - const kiss_twiddle_cpx * tw1; - kiss_fft_cpx t; - int i,j; - kiss_fft_cpx * Fout_beg = Fout; - for (i=0;itwiddles; - for(j=0;jtwiddles; - for (j=0;jr = PSHR32(Fout->r, 2); - Fout->i = PSHR32(Fout->i, 2); - C_SUB( scratch[5] , *Fout, scratch[1] ); - C_ADDTO(*Fout, scratch[1]); - C_ADD( scratch[3] , scratch[0] , scratch[2] ); - C_SUB( scratch[4] , scratch[0] , scratch[2] ); - Fout[m2].r = PSHR32(Fout[m2].r, 2); - Fout[m2].i = PSHR32(Fout[m2].i, 2); - C_SUB( Fout[m2], *Fout, scratch[3] ); - tw1 += fstride; - tw2 += fstride*2; - tw3 += fstride*3; - C_ADDTO( *Fout , scratch[3] ); - - Fout[m].r = scratch[5].r + scratch[4].i; - Fout[m].i = scratch[5].i - scratch[4].r; - Fout[m3].r = scratch[5].r - scratch[4].i; - Fout[m3].i = scratch[5].i + scratch[4].r; - ++Fout; - } - } -} - -static void ki_bfly4( - kiss_fft_cpx * Fout, - const size_t fstride, - const kiss_fft_state *st, - int m, - int N, - int mm - ) -{ - const kiss_twiddle_cpx *tw1,*tw2,*tw3; - kiss_fft_cpx scratch[6]; - const size_t m2=2*m; - const size_t m3=3*m; - int i, j; - - kiss_fft_cpx * Fout_beg = Fout; - for (i=0;itwiddles; - for (j=0;jtwiddles[fstride*m]; - for (i=0;itwiddles; - k=m; - do { - C_FIXDIV(*Fout,3); C_FIXDIV(Fout[m],3); C_FIXDIV(Fout[m2],3); - - C_MUL(scratch[1],Fout[m] , *tw1); - C_MUL(scratch[2],Fout[m2] , *tw2); - - C_ADD(scratch[3],scratch[1],scratch[2]); - C_SUB(scratch[0],scratch[1],scratch[2]); - tw1 += fstride; - tw2 += fstride*2; - - Fout[m].r = Fout->r - HALF_OF(scratch[3].r); - Fout[m].i = Fout->i - HALF_OF(scratch[3].i); - - C_MULBYSCALAR( scratch[0] , epi3.i ); - - C_ADDTO(*Fout,scratch[3]); - - Fout[m2].r = Fout[m].r + scratch[0].i; - Fout[m2].i = Fout[m].i - scratch[0].r; - - Fout[m].r -= scratch[0].i; - Fout[m].i += scratch[0].r; - - ++Fout; - } while(--k); - } -} - -static void ki_bfly3( - kiss_fft_cpx * Fout, - const size_t fstride, - const kiss_fft_state *st, - int m, - int N, - int mm - ) -{ - int i, k; - const size_t m2 = 2*m; - const kiss_twiddle_cpx *tw1,*tw2; - kiss_fft_cpx scratch[5]; - kiss_twiddle_cpx epi3; - - kiss_fft_cpx * Fout_beg = Fout; - epi3 = st->twiddles[fstride*m]; - for (i=0;itwiddles; - k=m; - do{ - - C_MULC(scratch[1],Fout[m] , *tw1); - C_MULC(scratch[2],Fout[m2] , *tw2); - - C_ADD(scratch[3],scratch[1],scratch[2]); - C_SUB(scratch[0],scratch[1],scratch[2]); - tw1 += fstride; - tw2 += fstride*2; - - Fout[m].r = Fout->r - HALF_OF(scratch[3].r); - Fout[m].i = Fout->i - HALF_OF(scratch[3].i); - - C_MULBYSCALAR( scratch[0] , -epi3.i ); - - C_ADDTO(*Fout,scratch[3]); - - Fout[m2].r = Fout[m].r + scratch[0].i; - Fout[m2].i = Fout[m].i - scratch[0].r; - - Fout[m].r -= scratch[0].i; - Fout[m].i += scratch[0].r; - - ++Fout; - }while(--k); - } -} - -static void kf_bfly5( - kiss_fft_cpx * Fout, - const size_t fstride, - const kiss_fft_state *st, - int m, - int N, - int mm - ) -{ - kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4; - int i, u; - kiss_fft_cpx scratch[13]; - const kiss_twiddle_cpx * twiddles = st->twiddles; - const kiss_twiddle_cpx *tw; - kiss_twiddle_cpx ya,yb; - kiss_fft_cpx * Fout_beg = Fout; - - ya = twiddles[fstride*m]; - yb = twiddles[fstride*2*m]; - tw=st->twiddles; - - for (i=0;ir += scratch[7].r + scratch[8].r; - Fout0->i += scratch[7].i + scratch[8].i; - - scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r); - scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r); - - scratch[6].r = S_MUL(scratch[10].i,ya.i) + S_MUL(scratch[9].i,yb.i); - scratch[6].i = -S_MUL(scratch[10].r,ya.i) - S_MUL(scratch[9].r,yb.i); - - C_SUB(*Fout1,scratch[5],scratch[6]); - C_ADD(*Fout4,scratch[5],scratch[6]); - - scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r); - scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r); - scratch[12].r = - S_MUL(scratch[10].i,yb.i) + S_MUL(scratch[9].i,ya.i); - scratch[12].i = S_MUL(scratch[10].r,yb.i) - S_MUL(scratch[9].r,ya.i); - - C_ADD(*Fout2,scratch[11],scratch[12]); - C_SUB(*Fout3,scratch[11],scratch[12]); - - ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4; - } - } -} - -static void ki_bfly5( - kiss_fft_cpx * Fout, - const size_t fstride, - const kiss_fft_state *st, - int m, - int N, - int mm - ) -{ - kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4; - int i, u; - kiss_fft_cpx scratch[13]; - const kiss_twiddle_cpx * twiddles = st->twiddles; - const kiss_twiddle_cpx *tw; - kiss_twiddle_cpx ya,yb; - kiss_fft_cpx * Fout_beg = Fout; - - ya = twiddles[fstride*m]; - yb = twiddles[fstride*2*m]; - tw=st->twiddles; - - for (i=0;ir += scratch[7].r + scratch[8].r; - Fout0->i += scratch[7].i + scratch[8].i; - - scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r); - scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r); - - scratch[6].r = -S_MUL(scratch[10].i,ya.i) - S_MUL(scratch[9].i,yb.i); - scratch[6].i = S_MUL(scratch[10].r,ya.i) + S_MUL(scratch[9].r,yb.i); - - C_SUB(*Fout1,scratch[5],scratch[6]); - C_ADD(*Fout4,scratch[5],scratch[6]); - - scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r); - scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r); - scratch[12].r = S_MUL(scratch[10].i,yb.i) - S_MUL(scratch[9].i,ya.i); - scratch[12].i = -S_MUL(scratch[10].r,yb.i) + S_MUL(scratch[9].r,ya.i); - - C_ADD(*Fout2,scratch[11],scratch[12]); - C_SUB(*Fout3,scratch[11],scratch[12]); - - ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4; - } - } -} - -#endif - - -#ifdef CUSTOM_MODES - -static -void compute_bitrev_table( - int Fout, - opus_int16 *f, - const size_t fstride, - int in_stride, - opus_int16 * factors, - const kiss_fft_state *st - ) -{ - const int p=*factors++; /* the radix */ - const int m=*factors++; /* stage's fft length/p */ - - /*printf ("fft %d %d %d %d %d %d\n", p*m, m, p, s2, fstride*in_stride, N);*/ - if (m==1) - { - int j; - for (j=0;j32000 || (opus_int32)p*(opus_int32)p > n) - p = n; /* no more factors, skip to end */ - } - n /= p; -#ifdef RADIX_TWO_ONLY - if (p!=2 && p != 4) -#else - if (p>5) -#endif - { - return 0; - } - *facbuf++ = p; - *facbuf++ = n; - } while (n > 1); - return 1; -} - -static void compute_twiddles(kiss_twiddle_cpx *twiddles, int nfft) -{ - int i; -#ifdef FIXED_POINT - for (i=0;i= memneeded) - st = (kiss_fft_state*)mem; - *lenmem = memneeded; - } - if (st) { - opus_int16 *bitrev; - kiss_twiddle_cpx *twiddles; - - st->nfft=nfft; -#ifndef FIXED_POINT - st->scale = 1.f/nfft; -#endif - if (base != NULL) - { - st->twiddles = base->twiddles; - st->shift = 0; - while (nfft<shift != base->nfft && st->shift < 32) - st->shift++; - if (st->shift>=32) - goto fail; - } else { - st->twiddles = twiddles = (kiss_twiddle_cpx*)KISS_FFT_MALLOC(sizeof(kiss_twiddle_cpx)*nfft); - compute_twiddles(twiddles, nfft); - st->shift = -1; - } - if (!kf_factor(nfft,st->factors)) - { - goto fail; - } - - /* bitrev */ - st->bitrev = bitrev = (opus_int16*)KISS_FFT_MALLOC(sizeof(opus_int16)*nfft); - if (st->bitrev==NULL) - goto fail; - compute_bitrev_table(0, bitrev, 1,1, st->factors,st); - } - return st; -fail: - opus_fft_free(st); - return NULL; -} - -kiss_fft_state *opus_fft_alloc(int nfft,void * mem,size_t * lenmem ) -{ - return opus_fft_alloc_twiddles(nfft, mem, lenmem, NULL); -} - -void opus_fft_free(const kiss_fft_state *cfg) -{ - if (cfg) - { - opus_free((opus_int16*)cfg->bitrev); - if (cfg->shift < 0) - opus_free((kiss_twiddle_cpx*)cfg->twiddles); - opus_free((kiss_fft_state*)cfg); - } -} - -#endif /* CUSTOM_MODES */ - -void opus_fft(const kiss_fft_state *st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout) -{ - int m2, m; - int p; - int L; - int fstride[MAXFACTORS]; - int i; - int shift; - - /* st->shift can be -1 */ - shift = st->shift>0 ? st->shift : 0; - - celt_assert2 (fin != fout, "In-place FFT not supported"); - /* Bit-reverse the input */ - for (i=0;infft;i++) - { - fout[st->bitrev[i]] = fin[i]; -#ifndef FIXED_POINT - fout[st->bitrev[i]].r *= st->scale; - fout[st->bitrev[i]].i *= st->scale; -#endif - } - - fstride[0] = 1; - L=0; - do { - p = st->factors[2*L]; - m = st->factors[2*L+1]; - fstride[L+1] = fstride[L]*p; - L++; - } while(m!=1); - m = st->factors[2*L-1]; - for (i=L-1;i>=0;i--) - { - if (i!=0) - m2 = st->factors[2*i-1]; - else - m2 = 1; - switch (st->factors[2*i]) - { - case 2: - kf_bfly2(fout,fstride[i]<shift can be -1 */ - shift = st->shift>0 ? st->shift : 0; - celt_assert2 (fin != fout, "In-place FFT not supported"); - /* Bit-reverse the input */ - for (i=0;infft;i++) - fout[st->bitrev[i]] = fin[i]; - - fstride[0] = 1; - L=0; - do { - p = st->factors[2*L]; - m = st->factors[2*L+1]; - fstride[L+1] = fstride[L]*p; - L++; - } while(m!=1); - m = st->factors[2*L-1]; - for (i=L-1;i>=0;i--) - { - if (i!=0) - m2 = st->factors[2*i-1]; - else - m2 = 1; - switch (st->factors[2*i]) - { - case 2: - ki_bfly2(fout,fstride[i]< -#include -#include "arch.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef USE_SIMD -# include -# define kiss_fft_scalar __m128 -#define KISS_FFT_MALLOC(nbytes) memalign(16,nbytes) -#else -#define KISS_FFT_MALLOC opus_alloc -#endif - -#ifdef FIXED_POINT -#include "arch.h" - -# define kiss_fft_scalar opus_int32 -# define kiss_twiddle_scalar opus_int16 - - -#else -# ifndef kiss_fft_scalar -/* default is float */ -# define kiss_fft_scalar float -# define kiss_twiddle_scalar float -# define KF_SUFFIX _celt_single -# endif -#endif - -typedef struct { - kiss_fft_scalar r; - kiss_fft_scalar i; -}kiss_fft_cpx; - -typedef struct { - kiss_twiddle_scalar r; - kiss_twiddle_scalar i; -}kiss_twiddle_cpx; - -#define MAXFACTORS 8 -/* e.g. an fft of length 128 has 4 factors - as far as kissfft is concerned - 4*4*4*2 - */ - -typedef struct kiss_fft_state{ - int nfft; -#ifndef FIXED_POINT - kiss_fft_scalar scale; -#endif - int shift; - opus_int16 factors[2*MAXFACTORS]; - const opus_int16 *bitrev; - const kiss_twiddle_cpx *twiddles; -} kiss_fft_state; - -/*typedef struct kiss_fft_state* kiss_fft_cfg;*/ - -/** - * opus_fft_alloc - * - * Initialize a FFT (or IFFT) algorithm's cfg/state buffer. - * - * typical usage: kiss_fft_cfg mycfg=opus_fft_alloc(1024,0,NULL,NULL); - * - * The return value from fft_alloc is a cfg buffer used internally - * by the fft routine or NULL. - * - * If lenmem is NULL, then opus_fft_alloc will allocate a cfg buffer using malloc. - * The returned value should be free()d when done to avoid memory leaks. - * - * The state can be placed in a user supplied buffer 'mem': - * If lenmem is not NULL and mem is not NULL and *lenmem is large enough, - * then the function places the cfg in mem and the size used in *lenmem - * and returns mem. - * - * If lenmem is not NULL and ( mem is NULL or *lenmem is not large enough), - * then the function returns NULL and places the minimum cfg - * buffer size in *lenmem. - * */ - -kiss_fft_state *opus_fft_alloc_twiddles(int nfft,void * mem,size_t * lenmem, const kiss_fft_state *base); - -kiss_fft_state *opus_fft_alloc(int nfft,void * mem,size_t * lenmem); - -/** - * opus_fft(cfg,in_out_buf) - * - * Perform an FFT on a complex input buffer. - * for a forward FFT, - * fin should be f[0] , f[1] , ... ,f[nfft-1] - * fout will be F[0] , F[1] , ... ,F[nfft-1] - * Note that each element is complex and can be accessed like - f[k].r and f[k].i - * */ -void opus_fft(const kiss_fft_state *cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout); -void opus_ifft(const kiss_fft_state *cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout); - -void opus_fft_free(const kiss_fft_state *cfg); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/opus-1.0.2/celt/laplace.c b/src/opus-1.0.2/celt/laplace.c deleted file mode 100644 index a7bca874..00000000 --- a/src/opus-1.0.2/celt/laplace.c +++ /dev/null @@ -1,134 +0,0 @@ -/* Copyright (c) 2007 CSIRO - Copyright (c) 2007-2009 Xiph.Org Foundation - Written by Jean-Marc Valin */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "laplace.h" -#include "mathops.h" - -/* The minimum probability of an energy delta (out of 32768). */ -#define LAPLACE_LOG_MINP (0) -#define LAPLACE_MINP (1<>15; -} - -void ec_laplace_encode(ec_enc *enc, int *value, unsigned fs, int decay) -{ - unsigned fl; - int val = *value; - fl = 0; - if (val) - { - int s; - int i; - s = -(val<0); - val = (val+s)^s; - fl = fs; - fs = ec_laplace_get_freq1(fs, decay); - /* Search the decaying part of the PDF.*/ - for (i=1; fs > 0 && i < val; i++) - { - fs *= 2; - fl += fs+2*LAPLACE_MINP; - fs = (fs*(opus_int32)decay)>>15; - } - /* Everything beyond that has probability LAPLACE_MINP. */ - if (!fs) - { - int di; - int ndi_max; - ndi_max = (32768-fl+LAPLACE_MINP-1)>>LAPLACE_LOG_MINP; - ndi_max = (ndi_max-s)>>1; - di = IMIN(val - i, ndi_max - 1); - fl += (2*di+1+s)*LAPLACE_MINP; - fs = IMIN(LAPLACE_MINP, 32768-fl); - *value = (i+di+s)^s; - } - else - { - fs += LAPLACE_MINP; - fl += fs&~s; - } - celt_assert(fl+fs<=32768); - celt_assert(fs>0); - } - ec_encode_bin(enc, fl, fl+fs, 15); -} - -int ec_laplace_decode(ec_dec *dec, unsigned fs, int decay) -{ - int val=0; - unsigned fl; - unsigned fm; - fm = ec_decode_bin(dec, 15); - fl = 0; - if (fm >= fs) - { - val++; - fl = fs; - fs = ec_laplace_get_freq1(fs, decay)+LAPLACE_MINP; - /* Search the decaying part of the PDF.*/ - while(fs > LAPLACE_MINP && fm >= fl+2*fs) - { - fs *= 2; - fl += fs; - fs = ((fs-2*LAPLACE_MINP)*(opus_int32)decay)>>15; - fs += LAPLACE_MINP; - val++; - } - /* Everything beyond that has probability LAPLACE_MINP. */ - if (fs <= LAPLACE_MINP) - { - int di; - di = (fm-fl)>>(LAPLACE_LOG_MINP+1); - val += di; - fl += 2*di*LAPLACE_MINP; - } - if (fm < fl+fs) - val = -val; - else - fl += fs; - } - celt_assert(fl<32768); - celt_assert(fs>0); - celt_assert(fl<=fm); - celt_assert(fm>1; - b=1U<>=1; - bshift--; - } - while(bshift>=0); - return g; -} - -#ifdef FIXED_POINT - -opus_val32 frac_div32(opus_val32 a, opus_val32 b) -{ - opus_val16 rcp; - opus_val32 result, rem; - int shift = celt_ilog2(b)-29; - a = VSHR32(a,shift); - b = VSHR32(b,shift); - /* 16-bit reciprocal */ - rcp = ROUND16(celt_rcp(ROUND16(b,16)),3); - result = MULT16_32_Q15(rcp, a); - rem = PSHR32(a,2)-MULT32_32_Q31(result, b); - result = ADD32(result, SHL32(MULT16_32_Q15(rcp, rem),2)); - if (result >= 536870912) /* 2^29 */ - return 2147483647; /* 2^31 - 1 */ - else if (result <= -536870912) /* -2^29 */ - return -2147483647; /* -2^31 */ - else - return SHL32(result, 2); -} - -/** Reciprocal sqrt approximation in the range [0.25,1) (Q16 in, Q14 out) */ -opus_val16 celt_rsqrt_norm(opus_val32 x) -{ - opus_val16 n; - opus_val16 r; - opus_val16 r2; - opus_val16 y; - /* Range of n is [-16384,32767] ([-0.5,1) in Q15). */ - n = x-32768; - /* Get a rough initial guess for the root. - The optimal minimax quadratic approximation (using relative error) is - r = 1.437799046117536+n*(-0.823394375837328+n*0.4096419668459485). - Coefficients here, and the final result r, are Q14.*/ - r = ADD16(23557, MULT16_16_Q15(n, ADD16(-13490, MULT16_16_Q15(n, 6713)))); - /* We want y = x*r*r-1 in Q15, but x is 32-bit Q16 and r is Q14. - We can compute the result from n and r using Q15 multiplies with some - adjustment, carefully done to avoid overflow. - Range of y is [-1564,1594]. */ - r2 = MULT16_16_Q15(r, r); - y = SHL16(SUB16(ADD16(MULT16_16_Q15(r2, n), r2), 16384), 1); - /* Apply a 2nd-order Householder iteration: r += r*y*(y*0.375-0.5). - This yields the Q14 reciprocal square root of the Q16 x, with a maximum - relative error of 1.04956E-4, a (relative) RMSE of 2.80979E-5, and a - peak absolute error of 2.26591/16384. */ - return ADD16(r, MULT16_16_Q15(r, MULT16_16_Q15(y, - SUB16(MULT16_16_Q15(y, 12288), 16384)))); -} - -/** Sqrt approximation (QX input, QX/2 output) */ -opus_val32 celt_sqrt(opus_val32 x) -{ - int k; - opus_val16 n; - opus_val32 rt; - static const opus_val16 C[5] = {23175, 11561, -3011, 1699, -664}; - if (x==0) - return 0; - k = (celt_ilog2(x)>>1)-7; - x = VSHR32(x, 2*k); - n = x-32768; - rt = ADD16(C[0], MULT16_16_Q15(n, ADD16(C[1], MULT16_16_Q15(n, ADD16(C[2], - MULT16_16_Q15(n, ADD16(C[3], MULT16_16_Q15(n, (C[4]))))))))); - rt = VSHR32(rt,7-k); - return rt; -} - -#define L1 32767 -#define L2 -7651 -#define L3 8277 -#define L4 -626 - -static inline opus_val16 _celt_cos_pi_2(opus_val16 x) -{ - opus_val16 x2; - - x2 = MULT16_16_P15(x,x); - return ADD16(1,MIN16(32766,ADD32(SUB16(L1,x2), MULT16_16_P15(x2, ADD32(L2, MULT16_16_P15(x2, ADD32(L3, MULT16_16_P15(L4, x2 - )))))))); -} - -#undef L1 -#undef L2 -#undef L3 -#undef L4 - -opus_val16 celt_cos_norm(opus_val32 x) -{ - x = x&0x0001ffff; - if (x>SHL32(EXTEND32(1), 16)) - x = SUB32(SHL32(EXTEND32(1), 17),x); - if (x&0x00007fff) - { - if (x0, "celt_rcp() only defined for positive values"); - i = celt_ilog2(x); - /* n is Q15 with range [0,1). */ - n = VSHR32(x,i-15)-32768; - /* Start with a linear approximation: - r = 1.8823529411764706-0.9411764705882353*n. - The coefficients and the result are Q14 in the range [15420,30840].*/ - r = ADD16(30840, MULT16_16_Q15(-15420, n)); - /* Perform two Newton iterations: - r -= r*((r*n)-1.Q15) - = r*((r*n)+(r-1.Q15)). */ - r = SUB16(r, MULT16_16_Q15(r, - ADD16(MULT16_16_Q15(r, n), ADD16(r, -32768)))); - /* We subtract an extra 1 in the second iteration to avoid overflow; it also - neatly compensates for truncation error in the rest of the process. */ - r = SUB16(r, ADD16(1, MULT16_16_Q15(r, - ADD16(MULT16_16_Q15(r, n), ADD16(r, -32768))))); - /* r is now the Q15 solution to 2/(n+1), with a maximum relative error - of 7.05346E-5, a (relative) RMSE of 2.14418E-5, and a peak absolute - error of 1.24665/32768. */ - return VSHR32(EXTEND32(r),i-16); -} - -#endif diff --git a/src/opus-1.0.2/celt/mathops.h b/src/opus-1.0.2/celt/mathops.h deleted file mode 100644 index 4e977956..00000000 --- a/src/opus-1.0.2/celt/mathops.h +++ /dev/null @@ -1,237 +0,0 @@ -/* Copyright (c) 2002-2008 Jean-Marc Valin - Copyright (c) 2007-2008 CSIRO - Copyright (c) 2007-2009 Xiph.Org Foundation - Written by Jean-Marc Valin */ -/** - @file mathops.h - @brief Various math functions -*/ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef MATHOPS_H -#define MATHOPS_H - -#include "arch.h" -#include "entcode.h" -#include "os_support.h" - -/* Multiplies two 16-bit fractional values. Bit-exactness of this macro is important */ -#define FRAC_MUL16(a,b) ((16384+((opus_int32)(opus_int16)(a)*(opus_int16)(b)))>>15) - -unsigned isqrt32(opus_uint32 _val); - -#ifndef FIXED_POINT - -#define PI 3.141592653f -#define celt_sqrt(x) ((float)sqrt(x)) -#define celt_rsqrt(x) (1.f/celt_sqrt(x)) -#define celt_rsqrt_norm(x) (celt_rsqrt(x)) -#define celt_cos_norm(x) ((float)cos((.5f*PI)*(x))) -#define celt_rcp(x) (1.f/(x)) -#define celt_div(a,b) ((a)/(b)) -#define frac_div32(a,b) ((float)(a)/(b)) - -#ifdef FLOAT_APPROX - -/* Note: This assumes radix-2 floating point with the exponent at bits 23..30 and an offset of 127 - denorm, +/- inf and NaN are *not* handled */ - -/** Base-2 log approximation (log2(x)). */ -static inline float celt_log2(float x) -{ - int integer; - float frac; - union { - float f; - opus_uint32 i; - } in; - in.f = x; - integer = (in.i>>23)-127; - in.i -= integer<<23; - frac = in.f - 1.5f; - frac = -0.41445418f + frac*(0.95909232f - + frac*(-0.33951290f + frac*0.16541097f)); - return 1+integer+frac; -} - -/** Base-2 exponential approximation (2^x). */ -static inline float celt_exp2(float x) -{ - int integer; - float frac; - union { - float f; - opus_uint32 i; - } res; - integer = floor(x); - if (integer < -50) - return 0; - frac = x-integer; - /* K0 = 1, K1 = log(2), K2 = 3-4*log(2), K3 = 3*log(2) - 2 */ - res.f = 0.99992522f + frac * (0.69583354f - + frac * (0.22606716f + 0.078024523f*frac)); - res.i = (res.i + (integer<<23)) & 0x7fffffff; - return res.f; -} - -#else -#define celt_log2(x) ((float)(1.442695040888963387*log(x))) -#define celt_exp2(x) ((float)exp(0.6931471805599453094*(x))) -#endif - -#endif - -#ifdef FIXED_POINT - -#include "os_support.h" - -#ifndef OVERRIDE_CELT_ILOG2 -/** Integer log in base2. Undefined for zero and negative numbers */ -static inline opus_int16 celt_ilog2(opus_int32 x) -{ - celt_assert2(x>0, "celt_ilog2() only defined for strictly positive numbers"); - return EC_ILOG(x)-1; -} -#endif - -#ifndef OVERRIDE_CELT_MAXABS16 -static inline opus_val16 celt_maxabs16(opus_val16 *x, int len) -{ - int i; - opus_val16 maxval = 0; - for (i=0;i14) - return 0x7f000000; - else if (integer < -15) - return 0; - frac = SHL16(x-SHL16(integer,10),4); - frac = ADD16(D0, MULT16_16_Q15(frac, ADD16(D1, MULT16_16_Q15(frac, ADD16(D2 , MULT16_16_Q15(D3,frac)))))); - return VSHR32(EXTEND32(frac), -integer-2); -} - -opus_val32 celt_rcp(opus_val32 x); - -#define celt_div(a,b) MULT32_32_Q31((opus_val32)(a),celt_rcp(b)) - -opus_val32 frac_div32(opus_val32 a, opus_val32 b); - -#define M1 32767 -#define M2 -21 -#define M3 -11943 -#define M4 4936 - -/* Atan approximation using a 4th order polynomial. Input is in Q15 format - and normalized by pi/4. Output is in Q15 format */ -static inline opus_val16 celt_atan01(opus_val16 x) -{ - return MULT16_16_P15(x, ADD32(M1, MULT16_16_P15(x, ADD32(M2, MULT16_16_P15(x, ADD32(M3, MULT16_16_P15(M4, x))))))); -} - -#undef M1 -#undef M2 -#undef M3 -#undef M4 - -/* atan2() approximation valid for positive input values */ -static inline opus_val16 celt_atan2p(opus_val16 y, opus_val16 x) -{ - if (y < x) - { - opus_val32 arg; - arg = celt_div(SHL32(EXTEND32(y),15),x); - if (arg >= 32767) - arg = 32767; - return SHR16(celt_atan01(EXTRACT16(arg)),1); - } else { - opus_val32 arg; - arg = celt_div(SHL32(EXTEND32(x),15),y); - if (arg >= 32767) - arg = 32767; - return 25736-SHR16(celt_atan01(EXTRACT16(arg)),1); - } -} - -#endif /* FIXED_POINT */ -#endif /* MATHOPS_H */ diff --git a/src/opus-1.0.2/celt/mdct.c b/src/opus-1.0.2/celt/mdct.c deleted file mode 100644 index 16a36c69..00000000 --- a/src/opus-1.0.2/celt/mdct.c +++ /dev/null @@ -1,332 +0,0 @@ -/* Copyright (c) 2007-2008 CSIRO - Copyright (c) 2007-2008 Xiph.Org Foundation - Written by Jean-Marc Valin */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* This is a simple MDCT implementation that uses a N/4 complex FFT - to do most of the work. It should be relatively straightforward to - plug in pretty much and FFT here. - - This replaces the Vorbis FFT (and uses the exact same API), which - was a bit too messy and that was ending up duplicating code - (might as well use the same FFT everywhere). - - The algorithm is similar to (and inspired from) Fabrice Bellard's - MDCT implementation in FFMPEG, but has differences in signs, ordering - and scaling in many places. -*/ - -#ifndef SKIP_CONFIG_H -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#endif - -#include "mdct.h" -#include "kiss_fft.h" -#include "_kiss_fft_guts.h" -#include -#include "os_support.h" -#include "mathops.h" -#include "stack_alloc.h" - -#ifdef CUSTOM_MODES - -int clt_mdct_init(mdct_lookup *l,int N, int maxshift) -{ - int i; - int N4; - kiss_twiddle_scalar *trig; -#if defined(FIXED_POINT) - int N2=N>>1; -#endif - l->n = N; - N4 = N>>2; - l->maxshift = maxshift; - for (i=0;i<=maxshift;i++) - { - if (i==0) - l->kfft[i] = opus_fft_alloc(N>>2>>i, 0, 0); - else - l->kfft[i] = opus_fft_alloc_twiddles(N>>2>>i, 0, 0, l->kfft[0]); -#ifndef ENABLE_TI_DSPLIB55 - if (l->kfft[i]==NULL) - return 0; -#endif - } - l->trig = trig = (kiss_twiddle_scalar*)opus_alloc((N4+1)*sizeof(kiss_twiddle_scalar)); - if (l->trig==NULL) - return 0; - /* We have enough points that sine isn't necessary */ -#if defined(FIXED_POINT) - for (i=0;i<=N4;i++) - trig[i] = TRIG_UPSCALE*celt_cos_norm(DIV32(ADD32(SHL32(EXTEND32(i),17),N2),N)); -#else - for (i=0;i<=N4;i++) - trig[i] = (kiss_twiddle_scalar)cos(2*PI*i/N); -#endif - return 1; -} - -void clt_mdct_clear(mdct_lookup *l) -{ - int i; - for (i=0;i<=l->maxshift;i++) - opus_fft_free(l->kfft[i]); - opus_free((kiss_twiddle_scalar*)l->trig); -} - -#endif /* CUSTOM_MODES */ - -/* Forward MDCT trashes the input array */ -void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out, - const opus_val16 *window, int overlap, int shift, int stride) -{ - int i; - int N, N2, N4; - kiss_twiddle_scalar sine; - VARDECL(kiss_fft_scalar, f); - SAVE_STACK; - N = l->n; - N >>= shift; - N2 = N>>1; - N4 = N>>2; - ALLOC(f, N2, kiss_fft_scalar); - /* sin(x) ~= x here */ -#ifdef FIXED_POINT - sine = TRIG_UPSCALE*(QCONST16(0.7853981f, 15)+N2)/N; -#else - sine = (kiss_twiddle_scalar)2*PI*(.125f)/N; -#endif - - /* Consider the input to be composed of four blocks: [a, b, c, d] */ - /* Window, shuffle, fold */ - { - /* Temp pointers to make it really clear to the compiler what we're doing */ - const kiss_fft_scalar * OPUS_RESTRICT xp1 = in+(overlap>>1); - const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+N2-1+(overlap>>1); - kiss_fft_scalar * OPUS_RESTRICT yp = f; - const opus_val16 * OPUS_RESTRICT wp1 = window+(overlap>>1); - const opus_val16 * OPUS_RESTRICT wp2 = window+(overlap>>1)-1; - for(i=0;i<(overlap>>2);i++) - { - /* Real part arranged as -d-cR, Imag part arranged as -b+aR*/ - *yp++ = MULT16_32_Q15(*wp2, xp1[N2]) + MULT16_32_Q15(*wp1,*xp2); - *yp++ = MULT16_32_Q15(*wp1, *xp1) - MULT16_32_Q15(*wp2, xp2[-N2]); - xp1+=2; - xp2-=2; - wp1+=2; - wp2-=2; - } - wp1 = window; - wp2 = window+overlap-1; - for(;i>2);i++) - { - /* Real part arranged as a-bR, Imag part arranged as -c-dR */ - *yp++ = *xp2; - *yp++ = *xp1; - xp1+=2; - xp2-=2; - } - for(;itrig[0]; - for(i=0;ikfft[shift], (kiss_fft_cpx *)f, (kiss_fft_cpx *)in); - - /* Post-rotate */ - { - /* Temp pointers to make it really clear to the compiler what we're doing */ - const kiss_fft_scalar * OPUS_RESTRICT fp = in; - kiss_fft_scalar * OPUS_RESTRICT yp1 = out; - kiss_fft_scalar * OPUS_RESTRICT yp2 = out+stride*(N2-1); - const kiss_twiddle_scalar *t = &l->trig[0]; - /* Temp pointers to make it really clear to the compiler what we're doing */ - for(i=0;in; - N >>= shift; - N2 = N>>1; - N4 = N>>2; - ALLOC(f, N2, kiss_fft_scalar); - ALLOC(f2, N2, kiss_fft_scalar); - /* sin(x) ~= x here */ -#ifdef FIXED_POINT - sine = TRIG_UPSCALE*(QCONST16(0.7853981f, 15)+N2)/N; -#else - sine = (kiss_twiddle_scalar)2*PI*(.125f)/N; -#endif - - /* Pre-rotate */ - { - /* Temp pointers to make it really clear to the compiler what we're doing */ - const kiss_fft_scalar * OPUS_RESTRICT xp1 = in; - const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+stride*(N2-1); - kiss_fft_scalar * OPUS_RESTRICT yp = f2; - const kiss_twiddle_scalar *t = &l->trig[0]; - for(i=0;ikfft[shift], (kiss_fft_cpx *)f2, (kiss_fft_cpx *)f); - - /* Post-rotate */ - { - kiss_fft_scalar * OPUS_RESTRICT fp = f; - const kiss_twiddle_scalar *t = &l->trig[0]; - - for(i=0;i>1; - /* Mirror on both sides for TDAC */ - { - kiss_fft_scalar * OPUS_RESTRICT fp1 = f2+N4-1; - kiss_fft_scalar * OPUS_RESTRICT xp1 = out+N2-1; - kiss_fft_scalar * OPUS_RESTRICT yp1 = out+N4-overlap/2; - const opus_val16 * OPUS_RESTRICT wp1 = window; - const opus_val16 * OPUS_RESTRICT wp2 = window+overlap-1; - for(i = 0; i< N4-overlap/2; i++) - { - *xp1 = *fp1; - xp1--; - fp1--; - } - for(; i < N4; i++) - { - kiss_fft_scalar x1; - x1 = *fp1--; - *yp1++ +=-MULT16_32_Q15(*wp1, x1); - *xp1-- += MULT16_32_Q15(*wp2, x1); - wp1++; - wp2--; - } - } - { - kiss_fft_scalar * OPUS_RESTRICT fp2 = f2+N4; - kiss_fft_scalar * OPUS_RESTRICT xp2 = out+N2; - kiss_fft_scalar * OPUS_RESTRICT yp2 = out+N-1-(N4-overlap/2); - const opus_val16 * OPUS_RESTRICT wp1 = window; - const opus_val16 * OPUS_RESTRICT wp2 = window+overlap-1; - for(i = 0; i< N4-overlap/2; i++) - { - *xp2 = *fp2; - xp2++; - fp2++; - } - for(; i < N4; i++) - { - kiss_fft_scalar x2; - x2 = *fp2++; - *yp2-- = MULT16_32_Q15(*wp1, x2); - *xp2++ = MULT16_32_Q15(*wp2, x2); - wp1++; - wp2--; - } - } - RESTORE_STACK; -} diff --git a/src/opus-1.0.2/celt/mdct.h b/src/opus-1.0.2/celt/mdct.h deleted file mode 100644 index d7218213..00000000 --- a/src/opus-1.0.2/celt/mdct.h +++ /dev/null @@ -1,70 +0,0 @@ -/* Copyright (c) 2007-2008 CSIRO - Copyright (c) 2007-2008 Xiph.Org Foundation - Written by Jean-Marc Valin */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* This is a simple MDCT implementation that uses a N/4 complex FFT - to do most of the work. It should be relatively straightforward to - plug in pretty much and FFT here. - - This replaces the Vorbis FFT (and uses the exact same API), which - was a bit too messy and that was ending up duplicating code - (might as well use the same FFT everywhere). - - The algorithm is similar to (and inspired from) Fabrice Bellard's - MDCT implementation in FFMPEG, but has differences in signs, ordering - and scaling in many places. -*/ - -#ifndef MDCT_H -#define MDCT_H - -#include "opus_defines.h" -#include "kiss_fft.h" -#include "arch.h" - -typedef struct { - int n; - int maxshift; - const kiss_fft_state *kfft[4]; - const kiss_twiddle_scalar * OPUS_RESTRICT trig; -} mdct_lookup; - -int clt_mdct_init(mdct_lookup *l,int N, int maxshift); -void clt_mdct_clear(mdct_lookup *l); - -/** Compute a forward MDCT and scale by 4/N, trashes the input array */ -void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, - kiss_fft_scalar * OPUS_RESTRICT out, - const opus_val16 *window, int overlap, int shift, int stride); - -/** Compute a backward MDCT (no scaling) and performs weighted overlap-add - (scales implicitly by 1/2) */ -void clt_mdct_backward(const mdct_lookup *l, kiss_fft_scalar *in, - kiss_fft_scalar * OPUS_RESTRICT out, - const opus_val16 * OPUS_RESTRICT window, int overlap, int shift, int stride); - -#endif diff --git a/src/opus-1.0.2/celt/mfrngcod.h b/src/opus-1.0.2/celt/mfrngcod.h deleted file mode 100644 index 809152a5..00000000 --- a/src/opus-1.0.2/celt/mfrngcod.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (c) 2001-2008 Timothy B. Terriberry - Copyright (c) 2008-2009 Xiph.Org Foundation */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#if !defined(_mfrngcode_H) -# define _mfrngcode_H (1) -# include "entcode.h" - -/*Constants used by the entropy encoder/decoder.*/ - -/*The number of bits to output at a time.*/ -# define EC_SYM_BITS (8) -/*The total number of bits in each of the state registers.*/ -# define EC_CODE_BITS (32) -/*The maximum symbol value.*/ -# define EC_SYM_MAX ((1U<>EC_SYM_BITS) -/*The number of bits available for the last, partial symbol in the code field.*/ -# define EC_CODE_EXTRA ((EC_CODE_BITS-2)%EC_SYM_BITS+1) -#endif diff --git a/src/opus-1.0.2/celt/modes.c b/src/opus-1.0.2/celt/modes.c deleted file mode 100644 index ed204d7d..00000000 --- a/src/opus-1.0.2/celt/modes.c +++ /dev/null @@ -1,430 +0,0 @@ -/* Copyright (c) 2007-2008 CSIRO - Copyright (c) 2007-2009 Xiph.Org Foundation - Copyright (c) 2008 Gregory Maxwell - Written by Jean-Marc Valin and Gregory Maxwell */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "celt.h" -#include "modes.h" -#include "rate.h" -#include "os_support.h" -#include "stack_alloc.h" -#include "quant_bands.h" - -static const opus_int16 eband5ms[] = { -/*0 200 400 600 800 1k 1.2 1.4 1.6 2k 2.4 2.8 3.2 4k 4.8 5.6 6.8 8k 9.6 12k 15.6 */ - 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 34, 40, 48, 60, 78, 100 -}; - -/* Alternate tuning (partially derived from Vorbis) */ -#define BITALLOC_SIZE 11 -/* Bit allocation table in units of 1/32 bit/sample (0.1875 dB SNR) */ -static const unsigned char band_allocation[] = { -/*0 200 400 600 800 1k 1.2 1.4 1.6 2k 2.4 2.8 3.2 4k 4.8 5.6 6.8 8k 9.6 12k 15.6 */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 90, 80, 75, 69, 63, 56, 49, 40, 34, 29, 20, 18, 10, 0, 0, 0, 0, 0, 0, 0, 0, -110,100, 90, 84, 78, 71, 65, 58, 51, 45, 39, 32, 26, 20, 12, 0, 0, 0, 0, 0, 0, -118,110,103, 93, 86, 80, 75, 70, 65, 59, 53, 47, 40, 31, 23, 15, 4, 0, 0, 0, 0, -126,119,112,104, 95, 89, 83, 78, 72, 66, 60, 54, 47, 39, 32, 25, 17, 12, 1, 0, 0, -134,127,120,114,103, 97, 91, 85, 78, 72, 66, 60, 54, 47, 41, 35, 29, 23, 16, 10, 1, -144,137,130,124,113,107,101, 95, 88, 82, 76, 70, 64, 57, 51, 45, 39, 33, 26, 15, 1, -152,145,138,132,123,117,111,105, 98, 92, 86, 80, 74, 67, 61, 55, 49, 43, 36, 20, 1, -162,155,148,142,133,127,121,115,108,102, 96, 90, 84, 77, 71, 65, 59, 53, 46, 30, 1, -172,165,158,152,143,137,131,125,118,112,106,100, 94, 87, 81, 75, 69, 63, 56, 45, 20, -200,200,200,200,200,200,200,200,198,193,188,183,178,173,168,163,158,153,148,129,104, -}; - -#ifndef CUSTOM_MODES_ONLY - #ifdef FIXED_POINT - #include "static_modes_fixed.h" - #else - #include "static_modes_float.h" - #endif -#endif /* CUSTOM_MODES_ONLY */ - -#ifndef M_PI -#define M_PI 3.141592653 -#endif - -#ifdef CUSTOM_MODES - -/* Defining 25 critical bands for the full 0-20 kHz audio bandwidth - Taken from http://ccrma.stanford.edu/~jos/bbt/Bark_Frequency_Scale.html */ -#define BARK_BANDS 25 -static const opus_int16 bark_freq[BARK_BANDS+1] = { - 0, 100, 200, 300, 400, - 510, 630, 770, 920, 1080, - 1270, 1480, 1720, 2000, 2320, - 2700, 3150, 3700, 4400, 5300, - 6400, 7700, 9500, 12000, 15500, - 20000}; - -static opus_int16 *compute_ebands(opus_int32 Fs, int frame_size, int res, int *nbEBands) -{ - opus_int16 *eBands; - int i, j, lin, low, high, nBark, offset=0; - - /* All modes that have 2.5 ms short blocks use the same definition */ - if (Fs == 400*(opus_int32)frame_size) - { - *nbEBands = sizeof(eband5ms)/sizeof(eband5ms[0])-1; - eBands = opus_alloc(sizeof(opus_int16)*(*nbEBands+1)); - for (i=0;i<*nbEBands+1;i++) - eBands[i] = eband5ms[i]; - return eBands; - } - /* Find the number of critical bands supported by our sampling rate */ - for (nBark=1;nBark= Fs) - break; - - /* Find where the linear part ends (i.e. where the spacing is more than min_width */ - for (lin=0;lin= res) - break; - - low = (bark_freq[lin]+res/2)/res; - high = nBark-lin; - *nbEBands = low+high; - eBands = opus_alloc(sizeof(opus_int16)*(*nbEBands+2)); - - if (eBands==NULL) - return NULL; - - /* Linear spacing (min_width) */ - for (i=0;i0) - offset = eBands[low-1]*res - bark_freq[lin-1]; - /* Spacing follows critical bands */ - for (i=0;i frame_size) - eBands[*nbEBands] = frame_size; - for (i=1;i<*nbEBands-1;i++) - { - if (eBands[i+1]-eBands[i] < eBands[i]-eBands[i-1]) - { - eBands[i] -= (2*eBands[i]-eBands[i-1]-eBands[i+1])/2; - } - } - /* Remove any empty bands. */ - for (i=j=0;i<*nbEBands;i++) - if(eBands[i+1]>eBands[j]) - eBands[++j]=eBands[i+1]; - *nbEBands=j; - - for (i=1;i<*nbEBands;i++) - { - /* Every band must be smaller than the last band. */ - celt_assert(eBands[i]-eBands[i-1]<=eBands[*nbEBands]-eBands[*nbEBands-1]); - /* Each band must be no larger than twice the size of the previous one. */ - celt_assert(eBands[i+1]-eBands[i]<=2*(eBands[i]-eBands[i-1])); - } - - return eBands; -} - -static void compute_allocation_table(CELTMode *mode) -{ - int i, j; - unsigned char *allocVectors; - int maxBands = sizeof(eband5ms)/sizeof(eband5ms[0])-1; - - mode->nbAllocVectors = BITALLOC_SIZE; - allocVectors = opus_alloc(sizeof(unsigned char)*(BITALLOC_SIZE*mode->nbEBands)); - if (allocVectors==NULL) - return; - - /* Check for standard mode */ - if (mode->Fs == 400*(opus_int32)mode->shortMdctSize) - { - for (i=0;inbEBands;i++) - allocVectors[i] = band_allocation[i]; - mode->allocVectors = allocVectors; - return; - } - /* If not the standard mode, interpolate */ - /* Compute per-codec-band allocation from per-critical-band matrix */ - for (i=0;inbEBands;j++) - { - int k; - for (k=0;k mode->eBands[j]*(opus_int32)mode->Fs/mode->shortMdctSize) - break; - } - if (k>maxBands-1) - allocVectors[i*mode->nbEBands+j] = band_allocation[i*maxBands + maxBands-1]; - else { - opus_int32 a0, a1; - a1 = mode->eBands[j]*(opus_int32)mode->Fs/mode->shortMdctSize - 400*(opus_int32)eband5ms[k-1]; - a0 = 400*(opus_int32)eband5ms[k] - mode->eBands[j]*(opus_int32)mode->Fs/mode->shortMdctSize; - allocVectors[i*mode->nbEBands+j] = (a0*band_allocation[i*maxBands+k-1] - + a1*band_allocation[i*maxBands+k])/(a0+a1); - } - } - } - - /*printf ("\n"); - for (i=0;inbEBands;j++) - printf ("%d ", allocVectors[i*mode->nbEBands+j]); - printf ("\n"); - } - exit(0);*/ - - mode->allocVectors = allocVectors; -} - -#endif /* CUSTOM_MODES */ - -CELTMode *opus_custom_mode_create(opus_int32 Fs, int frame_size, int *error) -{ - int i; -#ifdef CUSTOM_MODES - CELTMode *mode=NULL; - int res; - opus_val16 *window; - opus_int16 *logN; - int LM; - ALLOC_STACK; -#if !defined(VAR_ARRAYS) && !defined(USE_ALLOCA) - if (global_stack==NULL) - goto failure; -#endif -#endif - -#ifndef CUSTOM_MODES_ONLY - for (i=0;iFs && - (frame_size<shortMdctSize*static_mode_list[i]->nbShortMdcts) - { - if (error) - *error = OPUS_OK; - return (CELTMode*)static_mode_list[i]; - } - } - } -#endif /* CUSTOM_MODES_ONLY */ - -#ifndef CUSTOM_MODES - if (error) - *error = OPUS_BAD_ARG; - return NULL; -#else - - /* The good thing here is that permutation of the arguments will automatically be invalid */ - - if (Fs < 8000 || Fs > 96000) - { - if (error) - *error = OPUS_BAD_ARG; - return NULL; - } - if (frame_size < 40 || frame_size > 1024 || frame_size%2!=0) - { - if (error) - *error = OPUS_BAD_ARG; - return NULL; - } - /* Frames of less than 1ms are not supported. */ - if ((opus_int32)frame_size*1000 < Fs) - { - if (error) - *error = OPUS_BAD_ARG; - return NULL; - } - - if ((opus_int32)frame_size*75 >= Fs && (frame_size%16)==0) - { - LM = 3; - } else if ((opus_int32)frame_size*150 >= Fs && (frame_size%8)==0) - { - LM = 2; - } else if ((opus_int32)frame_size*300 >= Fs && (frame_size%4)==0) - { - LM = 1; - } else - { - LM = 0; - } - - /* Shorts longer than 3.3ms are not supported. */ - if ((opus_int32)(frame_size>>LM)*300 > Fs) - { - if (error) - *error = OPUS_BAD_ARG; - return NULL; - } - - mode = opus_alloc(sizeof(CELTMode)); - if (mode==NULL) - goto failure; - mode->Fs = Fs; - - /* Pre/de-emphasis depends on sampling rate. The "standard" pre-emphasis - is defined as A(z) = 1 - 0.85*z^-1 at 48 kHz. Other rates should - approximate that. */ - if(Fs < 12000) /* 8 kHz */ - { - mode->preemph[0] = QCONST16(0.3500061035f, 15); - mode->preemph[1] = -QCONST16(0.1799926758f, 15); - mode->preemph[2] = QCONST16(0.2719968125f, SIG_SHIFT); /* exact 1/preemph[3] */ - mode->preemph[3] = QCONST16(3.6765136719f, 13); - } else if(Fs < 24000) /* 16 kHz */ - { - mode->preemph[0] = QCONST16(0.6000061035f, 15); - mode->preemph[1] = -QCONST16(0.1799926758f, 15); - mode->preemph[2] = QCONST16(0.4424998650f, SIG_SHIFT); /* exact 1/preemph[3] */ - mode->preemph[3] = QCONST16(2.2598876953f, 13); - } else if(Fs < 40000) /* 32 kHz */ - { - mode->preemph[0] = QCONST16(0.7799987793f, 15); - mode->preemph[1] = -QCONST16(0.1000061035f, 15); - mode->preemph[2] = QCONST16(0.7499771125f, SIG_SHIFT); /* exact 1/preemph[3] */ - mode->preemph[3] = QCONST16(1.3333740234f, 13); - } else /* 48 kHz */ - { - mode->preemph[0] = QCONST16(0.8500061035f, 15); - mode->preemph[1] = QCONST16(0.0f, 15); - mode->preemph[2] = QCONST16(1.f, SIG_SHIFT); - mode->preemph[3] = QCONST16(1.f, 13); - } - - mode->maxLM = LM; - mode->nbShortMdcts = 1<shortMdctSize = frame_size/mode->nbShortMdcts; - res = (mode->Fs+mode->shortMdctSize)/(2*mode->shortMdctSize); - - mode->eBands = compute_ebands(Fs, mode->shortMdctSize, res, &mode->nbEBands); - if (mode->eBands==NULL) - goto failure; - - mode->effEBands = mode->nbEBands; - while (mode->eBands[mode->effEBands] > mode->shortMdctSize) - mode->effEBands--; - - /* Overlap must be divisible by 4 */ - mode->overlap = ((mode->shortMdctSize>>2)<<2); - - compute_allocation_table(mode); - if (mode->allocVectors==NULL) - goto failure; - - window = (opus_val16*)opus_alloc(mode->overlap*sizeof(opus_val16)); - if (window==NULL) - goto failure; - -#ifndef FIXED_POINT - for (i=0;ioverlap;i++) - window[i] = Q15ONE*sin(.5*M_PI* sin(.5*M_PI*(i+.5)/mode->overlap) * sin(.5*M_PI*(i+.5)/mode->overlap)); -#else - for (i=0;ioverlap;i++) - window[i] = MIN32(32767,floor(.5+32768.*sin(.5*M_PI* sin(.5*M_PI*(i+.5)/mode->overlap) * sin(.5*M_PI*(i+.5)/mode->overlap)))); -#endif - mode->window = window; - - logN = (opus_int16*)opus_alloc(mode->nbEBands*sizeof(opus_int16)); - if (logN==NULL) - goto failure; - - for (i=0;inbEBands;i++) - logN[i] = log2_frac(mode->eBands[i+1]-mode->eBands[i], BITRES); - mode->logN = logN; - - compute_pulse_cache(mode, mode->maxLM); - - if (clt_mdct_init(&mode->mdct, 2*mode->shortMdctSize*mode->nbShortMdcts, - mode->maxLM) == 0) - goto failure; - - if (error) - *error = OPUS_OK; - - return mode; -failure: - if (error) - *error = OPUS_ALLOC_FAIL; - if (mode!=NULL) - opus_custom_mode_destroy(mode); - return NULL; -#endif /* !CUSTOM_MODES */ -} - -#ifdef CUSTOM_MODES -void opus_custom_mode_destroy(CELTMode *mode) -{ - if (mode == NULL) - return; -#ifndef CUSTOM_MODES_ONLY - { - int i; - for (i=0;ieBands); - opus_free((opus_int16*)mode->allocVectors); - - opus_free((opus_val16*)mode->window); - opus_free((opus_int16*)mode->logN); - - opus_free((opus_int16*)mode->cache.index); - opus_free((unsigned char*)mode->cache.bits); - opus_free((unsigned char*)mode->cache.caps); - clt_mdct_clear(&mode->mdct); - - opus_free((CELTMode *)mode); -} -#endif diff --git a/src/opus-1.0.2/celt/modes.h b/src/opus-1.0.2/celt/modes.h deleted file mode 100644 index c8340f98..00000000 --- a/src/opus-1.0.2/celt/modes.h +++ /dev/null @@ -1,83 +0,0 @@ -/* Copyright (c) 2007-2008 CSIRO - Copyright (c) 2007-2009 Xiph.Org Foundation - Copyright (c) 2008 Gregory Maxwell - Written by Jean-Marc Valin and Gregory Maxwell */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef MODES_H -#define MODES_H - -#include "opus_types.h" -#include "celt.h" -#include "arch.h" -#include "mdct.h" -#include "entenc.h" -#include "entdec.h" - -#define MAX_PERIOD 1024 - -#ifndef OVERLAP -#define OVERLAP(mode) ((mode)->overlap) -#endif - -#ifndef FRAMESIZE -#define FRAMESIZE(mode) ((mode)->mdctSize) -#endif - -typedef struct { - int size; - const opus_int16 *index; - const unsigned char *bits; - const unsigned char *caps; -} PulseCache; - -/** Mode definition (opaque) - @brief Mode definition - */ -struct OpusCustomMode { - opus_int32 Fs; - int overlap; - - int nbEBands; - int effEBands; - opus_val16 preemph[4]; - const opus_int16 *eBands; /**< Definition for each "pseudo-critical band" */ - - int maxLM; - int nbShortMdcts; - int shortMdctSize; - - int nbAllocVectors; /**< Number of lines in the matrix below */ - const unsigned char *allocVectors; /**< Number of bits in each band for several rates */ - const opus_int16 *logN; - - const opus_val16 *window; - mdct_lookup mdct; - PulseCache cache; -}; - - -#endif diff --git a/src/opus-1.0.2/celt/opus_custom_demo.c b/src/opus-1.0.2/celt/opus_custom_demo.c deleted file mode 100644 index ae41c0de..00000000 --- a/src/opus-1.0.2/celt/opus_custom_demo.c +++ /dev/null @@ -1,210 +0,0 @@ -/* Copyright (c) 2007-2008 CSIRO - Copyright (c) 2007-2009 Xiph.Org Foundation - Written by Jean-Marc Valin */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "opus_custom.h" -#include "arch.h" -#include -#include -#include -#include - -#define MAX_PACKET 1275 - -int main(int argc, char *argv[]) -{ - int err; - char *inFile, *outFile; - FILE *fin, *fout; - OpusCustomMode *mode=NULL; - OpusCustomEncoder *enc; - OpusCustomDecoder *dec; - int len; - opus_int32 frame_size, channels, rate; - int bytes_per_packet; - unsigned char data[MAX_PACKET]; - int complexity; -#if !(defined (FIXED_POINT) && !defined(CUSTOM_MODES)) && defined(RESYNTH) - int i; - double rmsd = 0; -#endif - int count = 0; - opus_int32 skip; - opus_int16 *in, *out; - if (argc != 9 && argc != 8 && argc != 7) - { - fprintf (stderr, "Usage: test_opus_custom " - " [ [packet loss rate]] " - " \n"); - return 1; - } - - rate = (opus_int32)atol(argv[1]); - channels = atoi(argv[2]); - frame_size = atoi(argv[3]); - mode = opus_custom_mode_create(rate, frame_size, NULL); - if (mode == NULL) - { - fprintf(stderr, "failed to create a mode\n"); - return 1; - } - - bytes_per_packet = atoi(argv[4]); - if (bytes_per_packet < 0 || bytes_per_packet > MAX_PACKET) - { - fprintf (stderr, "bytes per packet must be between 0 and %d\n", - MAX_PACKET); - return 1; - } - - inFile = argv[argc-2]; - fin = fopen(inFile, "rb"); - if (!fin) - { - fprintf (stderr, "Could not open input file %s\n", argv[argc-2]); - return 1; - } - outFile = argv[argc-1]; - fout = fopen(outFile, "wb+"); - if (!fout) - { - fprintf (stderr, "Could not open output file %s\n", argv[argc-1]); - fclose(fin); - return 1; - } - - enc = opus_custom_encoder_create(mode, channels, &err); - if (err != 0) - { - fprintf(stderr, "Failed to create the encoder: %s\n", opus_strerror(err)); - fclose(fin); - fclose(fout); - return 1; - } - dec = opus_custom_decoder_create(mode, channels, &err); - if (err != 0) - { - fprintf(stderr, "Failed to create the decoder: %s\n", opus_strerror(err)); - fclose(fin); - fclose(fout); - return 1; - } - opus_custom_decoder_ctl(dec, OPUS_GET_LOOKAHEAD(&skip)); - - if (argc>7) - { - complexity=atoi(argv[5]); - opus_custom_encoder_ctl(enc,OPUS_SET_COMPLEXITY(complexity)); - } - - in = (opus_int16*)malloc(frame_size*channels*sizeof(opus_int16)); - out = (opus_int16*)malloc(frame_size*channels*sizeof(opus_int16)); - - while (!feof(fin)) - { - int ret; - err = fread(in, sizeof(short), frame_size*channels, fin); - if (feof(fin)) - break; - len = opus_custom_encode(enc, in, frame_size, data, bytes_per_packet); - if (len <= 0) - fprintf (stderr, "opus_custom_encode() failed: %s\n", opus_strerror(len)); - - /* This is for simulating bit errors */ -#if 0 - int errors = 0; - int eid = 0; - /* This simulates random bit error */ - for (i=0;i 0) - { - rmsd = sqrt(rmsd/(1.0*frame_size*channels*count)); - fprintf (stderr, "Error: encoder doesn't match decoder\n"); - fprintf (stderr, "RMS mismatch is %f\n", rmsd); - return 1; - } else { - fprintf (stderr, "Encoder matches decoder!!\n"); - } -#endif - return 0; -} - diff --git a/src/opus-1.0.2/celt/os_support.h b/src/opus-1.0.2/celt/os_support.h deleted file mode 100644 index 2484f0b2..00000000 --- a/src/opus-1.0.2/celt/os_support.h +++ /dev/null @@ -1,89 +0,0 @@ -/* Copyright (C) 2007 Jean-Marc Valin - - File: os_support.h - This is the (tiny) OS abstraction layer. Aside from math.h, this is the - only place where system headers are allowed. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are - met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef OS_SUPPORT_H -#define OS_SUPPORT_H - -#ifdef CUSTOM_SUPPORT -# include "custom_support.h" -#endif - -#include -#include -#include - -/** Opus wrapper for malloc(). To do your own dynamic allocation, all you need to do is replace this function and opus_free */ -#ifndef OVERRIDE_OPUS_ALLOC -static inline void *opus_alloc (size_t size) -{ - return malloc(size); -} -#endif - -/** Same as celt_alloc(), except that the area is only needed inside a CELT call (might cause problem with wideband though) */ -#ifndef OVERRIDE_OPUS_ALLOC_SCRATCH -static inline void *opus_alloc_scratch (size_t size) -{ - /* Scratch space doesn't need to be cleared */ - return opus_alloc(size); -} -#endif - -/** Opus wrapper for free(). To do your own dynamic allocation, all you need to do is replace this function and opus_alloc */ -#ifndef OVERRIDE_OPUS_FREE -static inline void opus_free (void *ptr) -{ - free(ptr); -} -#endif - -/** Copy n bytes of memory from src to dst. The 0* term provides compile-time type checking */ -#ifndef OVERRIDE_OPUS_COPY -#define OPUS_COPY(dst, src, n) (memcpy((dst), (src), (n)*sizeof(*(dst)) + 0*((dst)-(src)) )) -#endif - -/** Copy n bytes of memory from src to dst, allowing overlapping regions. The 0* term - provides compile-time type checking */ -#ifndef OVERRIDE_OPUS_MOVE -#define OPUS_MOVE(dst, src, n) (memmove((dst), (src), (n)*sizeof(*(dst)) + 0*((dst)-(src)) )) -#endif - -/** Set n elements of dst to zero, starting at address s */ -#ifndef OVERRIDE_OPUS_CLEAR -#define OPUS_CLEAR(dst, n) (memset((dst), 0, (n)*sizeof(*(dst)))) -#endif - -/*#ifdef __GNUC__ -#pragma GCC poison printf sprintf -#pragma GCC poison malloc free realloc calloc -#endif*/ - -#endif /* OS_SUPPORT_H */ - diff --git a/src/opus-1.0.2/celt/pitch.c b/src/opus-1.0.2/celt/pitch.c deleted file mode 100644 index ca0f523e..00000000 --- a/src/opus-1.0.2/celt/pitch.c +++ /dev/null @@ -1,410 +0,0 @@ -/* Copyright (c) 2007-2008 CSIRO - Copyright (c) 2007-2009 Xiph.Org Foundation - Written by Jean-Marc Valin */ -/** - @file pitch.c - @brief Pitch analysis - */ - -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "pitch.h" -#include "os_support.h" -#include "modes.h" -#include "stack_alloc.h" -#include "mathops.h" -#include "celt_lpc.h" - -static void find_best_pitch(opus_val32 *xcorr, opus_val16 *y, int len, - int max_pitch, int *best_pitch -#ifdef FIXED_POINT - , int yshift, opus_val32 maxcorr -#endif - ) -{ - int i, j; - opus_val32 Syy=1; - opus_val16 best_num[2]; - opus_val32 best_den[2]; -#ifdef FIXED_POINT - int xshift; - - xshift = celt_ilog2(maxcorr)-14; -#endif - - best_num[0] = -1; - best_num[1] = -1; - best_den[0] = 0; - best_den[1] = 0; - best_pitch[0] = 0; - best_pitch[1] = 1; - for (j=0;j0) - { - opus_val16 num; - opus_val32 xcorr16; - xcorr16 = EXTRACT16(VSHR32(xcorr[i], xshift)); -#ifndef FIXED_POINT - /* Considering the range of xcorr16, this should avoid both underflows - and overflows (inf) when squaring xcorr16 */ - xcorr16 *= 1e-12f; -#endif - num = MULT16_16_Q15(xcorr16,xcorr16); - if (MULT16_32_Q15(num,best_den[1]) > MULT16_32_Q15(best_num[1],Syy)) - { - if (MULT16_32_Q15(num,best_den[0]) > MULT16_32_Q15(best_num[0],Syy)) - { - best_num[1] = best_num[0]; - best_den[1] = best_den[0]; - best_pitch[1] = best_pitch[0]; - best_num[0] = num; - best_den[0] = Syy; - best_pitch[0] = i; - } else { - best_num[1] = num; - best_den[1] = Syy; - best_pitch[1] = i; - } - } - } - Syy += SHR32(MULT16_16(y[i+len],y[i+len]),yshift) - SHR32(MULT16_16(y[i],y[i]),yshift); - Syy = MAX32(1, Syy); - } -} - -void pitch_downsample(celt_sig * OPUS_RESTRICT x[], opus_val16 * OPUS_RESTRICT x_lp, - int len, int C) -{ - int i; - opus_val32 ac[5]; - opus_val16 tmp=Q15ONE; - opus_val16 lpc[4], mem[4]={0,0,0,0}; -#ifdef FIXED_POINT - int shift; - opus_val32 maxabs = celt_maxabs32(x[0], len); - if (C==2) - { - opus_val32 maxabs_1 = celt_maxabs32(x[1], len); - maxabs = MAX32(maxabs, maxabs_1); - } - if (maxabs<1) - maxabs=1; - shift = celt_ilog2(maxabs)-10; - if (shift<0) - shift=0; - if (C==2) - shift++; -#endif - for (i=1;i>1;i++) - x_lp[i] = SHR32(HALF32(HALF32(x[0][(2*i-1)]+x[0][(2*i+1)])+x[0][2*i]), shift); - x_lp[0] = SHR32(HALF32(HALF32(x[0][1])+x[0][0]), shift); - if (C==2) - { - for (i=1;i>1;i++) - x_lp[i] += SHR32(HALF32(HALF32(x[1][(2*i-1)]+x[1][(2*i+1)])+x[1][2*i]), shift); - x_lp[0] += SHR32(HALF32(HALF32(x[1][1])+x[1][0]), shift); - } - - _celt_autocorr(x_lp, ac, NULL, 0, - 4, len>>1); - - /* Noise floor -40 dB */ -#ifdef FIXED_POINT - ac[0] += SHR32(ac[0],13); -#else - ac[0] *= 1.0001f; -#endif - /* Lag windowing */ - for (i=1;i<=4;i++) - { - /*ac[i] *= exp(-.5*(2*M_PI*.002*i)*(2*M_PI*.002*i));*/ -#ifdef FIXED_POINT - ac[i] -= MULT16_32_Q15(2*i*i, ac[i]); -#else - ac[i] -= ac[i]*(.008f*i)*(.008f*i); -#endif - } - - _celt_lpc(lpc, ac, 4); - for (i=0;i<4;i++) - { - tmp = MULT16_16_Q15(QCONST16(.9f,15), tmp); - lpc[i] = MULT16_16_Q15(lpc[i], tmp); - } - celt_fir(x_lp, lpc, x_lp, len>>1, 4, mem); - - mem[0]=0; - lpc[0]=QCONST16(.8f,12); - celt_fir(x_lp, lpc, x_lp, len>>1, 1, mem); - -} - -void pitch_search(const opus_val16 * OPUS_RESTRICT x_lp, opus_val16 * OPUS_RESTRICT y, - int len, int max_pitch, int *pitch) -{ - int i, j; - int lag; - int best_pitch[2]={0,0}; - VARDECL(opus_val16, x_lp4); - VARDECL(opus_val16, y_lp4); - VARDECL(opus_val32, xcorr); -#ifdef FIXED_POINT - opus_val32 maxcorr=1; - opus_val16 xmax, ymax; - int shift=0; -#endif - int offset; - - SAVE_STACK; - - celt_assert(len>0); - celt_assert(max_pitch>0); - lag = len+max_pitch; - - ALLOC(x_lp4, len>>2, opus_val16); - ALLOC(y_lp4, lag>>2, opus_val16); - ALLOC(xcorr, max_pitch>>1, opus_val32); - - /* Downsample by 2 again */ - for (j=0;j>2;j++) - x_lp4[j] = x_lp[2*j]; - for (j=0;j>2;j++) - y_lp4[j] = y[2*j]; - -#ifdef FIXED_POINT - xmax = celt_maxabs16(x_lp4, len>>2); - ymax = celt_maxabs16(y_lp4, lag>>2); - shift = celt_ilog2(MAX16(1, MAX16(xmax, ymax)))-11; - if (shift>0) - { - for (j=0;j>2;j++) - x_lp4[j] = SHR16(x_lp4[j], shift); - for (j=0;j>2;j++) - y_lp4[j] = SHR16(y_lp4[j], shift); - /* Use double the shift for a MAC */ - shift *= 2; - } else { - shift = 0; - } -#endif - - /* Coarse search with 4x decimation */ - - for (i=0;i>2;i++) - { - opus_val32 sum = 0; - for (j=0;j>2;j++) - sum = MAC16_16(sum, x_lp4[j],y_lp4[i+j]); - xcorr[i] = MAX32(-1, sum); -#ifdef FIXED_POINT - maxcorr = MAX32(maxcorr, sum); -#endif - } - find_best_pitch(xcorr, y_lp4, len>>2, max_pitch>>2, best_pitch -#ifdef FIXED_POINT - , 0, maxcorr -#endif - ); - - /* Finer search with 2x decimation */ -#ifdef FIXED_POINT - maxcorr=1; -#endif - for (i=0;i>1;i++) - { - opus_val32 sum=0; - xcorr[i] = 0; - if (abs(i-2*best_pitch[0])>2 && abs(i-2*best_pitch[1])>2) - continue; - for (j=0;j>1;j++) - sum += SHR32(MULT16_16(x_lp[j],y[i+j]), shift); - xcorr[i] = MAX32(-1, sum); -#ifdef FIXED_POINT - maxcorr = MAX32(maxcorr, sum); -#endif - } - find_best_pitch(xcorr, y, len>>1, max_pitch>>1, best_pitch -#ifdef FIXED_POINT - , shift+1, maxcorr -#endif - ); - - /* Refine by pseudo-interpolation */ - if (best_pitch[0]>0 && best_pitch[0]<(max_pitch>>1)-1) - { - opus_val32 a, b, c; - a = xcorr[best_pitch[0]-1]; - b = xcorr[best_pitch[0]]; - c = xcorr[best_pitch[0]+1]; - if ((c-a) > MULT16_32_Q15(QCONST16(.7f,15),b-a)) - offset = 1; - else if ((a-c) > MULT16_32_Q15(QCONST16(.7f,15),b-c)) - offset = -1; - else - offset = 0; - } else { - offset = 0; - } - *pitch = 2*best_pitch[0]-offset; - - RESTORE_STACK; -} - -static const int second_check[16] = {0, 0, 3, 2, 3, 2, 5, 2, 3, 2, 3, 2, 5, 2, 3, 2}; -opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod, - int N, int *T0_, int prev_period, opus_val16 prev_gain) -{ - int k, i, T, T0; - opus_val16 g, g0; - opus_val16 pg; - opus_val32 xy,xx,yy; - opus_val32 xcorr[3]; - opus_val32 best_xy, best_yy; - int offset; - int minperiod0; - - minperiod0 = minperiod; - maxperiod /= 2; - minperiod /= 2; - *T0_ /= 2; - prev_period /= 2; - N /= 2; - x += maxperiod; - if (*T0_>=maxperiod) - *T0_=maxperiod-1; - - T = T0 = *T0_; - xx=xy=yy=0; - for (i=0;i>1; - t = VSHR32(x2y2, 2*(sh-7)); - g = g0 = VSHR32(MULT16_32_Q15(celt_rsqrt_norm(t), xy),sh+1); - } -#else - g = g0 = xy/celt_sqrt(1+xx*yy); -#endif - /* Look for any pitch at T/k */ - for (k=2;k<=15;k++) - { - int T1, T1b; - opus_val16 g1; - opus_val16 cont=0; - T1 = (2*T0+k)/(2*k); - if (T1 < minperiod) - break; - /* Look for another strong correlation at T1b */ - if (k==2) - { - if (T1+T0>maxperiod) - T1b = T0; - else - T1b = T0+T1; - } else - { - T1b = (2*second_check[k]*T0+k)/(2*k); - } - xy=yy=0; - for (i=0;i>1; - t = VSHR32(x2y2, 2*(sh-7)); - g1 = VSHR32(MULT16_32_Q15(celt_rsqrt_norm(t), xy),sh+1); - } -#else - g1 = xy/celt_sqrt(1+2.f*xx*1.f*yy); -#endif - if (abs(T1-prev_period)<=1) - cont = prev_gain; - else if (abs(T1-prev_period)<=2 && 5*k*k < T0) - cont = HALF32(prev_gain); - else - cont = 0; - if (g1 > QCONST16(.3f,15) + MULT16_16_Q15(QCONST16(.4f,15),g0)-cont) - { - best_xy = xy; - best_yy = yy; - T = T1; - g = g1; - } - } - best_xy = MAX32(0, best_xy); - if (best_yy <= best_xy) - pg = Q15ONE; - else - pg = SHR32(frac_div32(best_xy,best_yy+1),16); - - for (k=0;k<3;k++) - { - int T1 = T+k-1; - xy = 0; - for (i=0;i MULT16_32_Q15(QCONST16(.7f,15),xcorr[1]-xcorr[0])) - offset = 1; - else if ((xcorr[0]-xcorr[2]) > MULT16_32_Q15(QCONST16(.7f,15),xcorr[1]-xcorr[2])) - offset = -1; - else - offset = 0; - if (pg > g) - pg = g; - *T0_ = 2*T+offset; - - if (*T0_ -#include "os_support.h" -#include "arch.h" -#include "mathops.h" -#include "stack_alloc.h" -#include "rate.h" - -#ifdef FIXED_POINT -/* Mean energy in each band quantized in Q6 */ -static const signed char eMeans[25] = { - 103,100, 92, 85, 81, - 77, 72, 70, 78, 75, - 73, 71, 78, 74, 69, - 72, 70, 74, 76, 71, - 60, 60, 60, 60, 60 -}; -#else -/* Mean energy in each band quantized in Q6 and converted back to float */ -static const opus_val16 eMeans[25] = { - 6.437500f, 6.250000f, 5.750000f, 5.312500f, 5.062500f, - 4.812500f, 4.500000f, 4.375000f, 4.875000f, 4.687500f, - 4.562500f, 4.437500f, 4.875000f, 4.625000f, 4.312500f, - 4.500000f, 4.375000f, 4.625000f, 4.750000f, 4.437500f, - 3.750000f, 3.750000f, 3.750000f, 3.750000f, 3.750000f -}; -#endif -/* prediction coefficients: 0.9, 0.8, 0.65, 0.5 */ -#ifdef FIXED_POINT -static const opus_val16 pred_coef[4] = {29440, 26112, 21248, 16384}; -static const opus_val16 beta_coef[4] = {30147, 22282, 12124, 6554}; -static const opus_val16 beta_intra = 4915; -#else -static const opus_val16 pred_coef[4] = {29440/32768., 26112/32768., 21248/32768., 16384/32768.}; -static const opus_val16 beta_coef[4] = {30147/32768., 22282/32768., 12124/32768., 6554/32768.}; -static const opus_val16 beta_intra = 4915/32768.; -#endif - -/*Parameters of the Laplace-like probability models used for the coarse energy. - There is one pair of parameters for each frame size, prediction type - (inter/intra), and band number. - The first number of each pair is the probability of 0, and the second is the - decay rate, both in Q8 precision.*/ -static const unsigned char e_prob_model[4][2][42] = { - /*120 sample frames.*/ - { - /*Inter*/ - { - 72, 127, 65, 129, 66, 128, 65, 128, 64, 128, 62, 128, 64, 128, - 64, 128, 92, 78, 92, 79, 92, 78, 90, 79, 116, 41, 115, 40, - 114, 40, 132, 26, 132, 26, 145, 17, 161, 12, 176, 10, 177, 11 - }, - /*Intra*/ - { - 24, 179, 48, 138, 54, 135, 54, 132, 53, 134, 56, 133, 55, 132, - 55, 132, 61, 114, 70, 96, 74, 88, 75, 88, 87, 74, 89, 66, - 91, 67, 100, 59, 108, 50, 120, 40, 122, 37, 97, 43, 78, 50 - } - }, - /*240 sample frames.*/ - { - /*Inter*/ - { - 83, 78, 84, 81, 88, 75, 86, 74, 87, 71, 90, 73, 93, 74, - 93, 74, 109, 40, 114, 36, 117, 34, 117, 34, 143, 17, 145, 18, - 146, 19, 162, 12, 165, 10, 178, 7, 189, 6, 190, 8, 177, 9 - }, - /*Intra*/ - { - 23, 178, 54, 115, 63, 102, 66, 98, 69, 99, 74, 89, 71, 91, - 73, 91, 78, 89, 86, 80, 92, 66, 93, 64, 102, 59, 103, 60, - 104, 60, 117, 52, 123, 44, 138, 35, 133, 31, 97, 38, 77, 45 - } - }, - /*480 sample frames.*/ - { - /*Inter*/ - { - 61, 90, 93, 60, 105, 42, 107, 41, 110, 45, 116, 38, 113, 38, - 112, 38, 124, 26, 132, 27, 136, 19, 140, 20, 155, 14, 159, 16, - 158, 18, 170, 13, 177, 10, 187, 8, 192, 6, 175, 9, 159, 10 - }, - /*Intra*/ - { - 21, 178, 59, 110, 71, 86, 75, 85, 84, 83, 91, 66, 88, 73, - 87, 72, 92, 75, 98, 72, 105, 58, 107, 54, 115, 52, 114, 55, - 112, 56, 129, 51, 132, 40, 150, 33, 140, 29, 98, 35, 77, 42 - } - }, - /*960 sample frames.*/ - { - /*Inter*/ - { - 42, 121, 96, 66, 108, 43, 111, 40, 117, 44, 123, 32, 120, 36, - 119, 33, 127, 33, 134, 34, 139, 21, 147, 23, 152, 20, 158, 25, - 154, 26, 166, 21, 173, 16, 184, 13, 184, 10, 150, 13, 139, 15 - }, - /*Intra*/ - { - 22, 178, 63, 114, 74, 82, 84, 83, 92, 82, 103, 62, 96, 72, - 96, 67, 101, 73, 107, 72, 113, 55, 118, 52, 125, 52, 118, 52, - 117, 55, 135, 49, 137, 39, 157, 32, 145, 29, 97, 33, 77, 40 - } - } -}; - -static const unsigned char small_energy_icdf[3]={2,1,0}; - -static opus_val32 loss_distortion(const opus_val16 *eBands, opus_val16 *oldEBands, int start, int end, int len, int C) -{ - int c, i; - opus_val32 dist = 0; - c=0; do { - for (i=start;inbEBands]; - oldE = MAX16(-QCONST16(9.f,DB_SHIFT), oldEBands[i+c*m->nbEBands]); -#ifdef FIXED_POINT - f = SHL32(EXTEND32(x),7) - PSHR32(MULT16_16(coef,oldE), 8) - prev[c]; - /* Rounding to nearest integer here is really important! */ - qi = (f+QCONST32(.5f,DB_SHIFT+7))>>(DB_SHIFT+7); - decay_bound = EXTRACT16(MAX32(-QCONST16(28.f,DB_SHIFT), - SUB32((opus_val32)oldEBands[i+c*m->nbEBands],max_decay))); -#else - f = x-coef*oldE-prev[c]; - /* Rounding to nearest integer here is really important! */ - qi = (int)floor(.5f+f); - decay_bound = MAX16(-QCONST16(28.f,DB_SHIFT), oldEBands[i+c*m->nbEBands]) - max_decay; -#endif - /* Prevent the energy from going down too quickly (e.g. for bands - that have just one bin) */ - if (qi < 0 && x < decay_bound) - { - qi += (int)SHR16(SUB16(decay_bound,x), DB_SHIFT); - if (qi > 0) - qi = 0; - } - qi0 = qi; - /* If we don't have enough bits to encode all the energy, just assume - something safe. */ - tell = ec_tell(enc); - bits_left = budget-tell-3*C*(end-i); - if (i!=start && bits_left < 30) - { - if (bits_left < 24) - qi = IMIN(1, qi); - if (bits_left < 16) - qi = IMAX(-1, qi); - } - if (budget-tell >= 15) - { - int pi; - pi = 2*IMIN(i,20); - ec_laplace_encode(enc, &qi, - prob_model[pi]<<7, prob_model[pi+1]<<6); - } - else if(budget-tell >= 2) - { - qi = IMAX(-1, IMIN(qi, 1)); - ec_enc_icdf(enc, 2*qi^-(qi<0), small_energy_icdf, 2); - } - else if(budget-tell >= 1) - { - qi = IMIN(0, qi); - ec_enc_bit_logp(enc, -qi, 1); - } - else - qi = -1; - error[i+c*m->nbEBands] = PSHR32(f,7) - SHL16(qi,DB_SHIFT); - badness += abs(qi0-qi); - q = (opus_val32)SHL32(EXTEND32(qi),DB_SHIFT); - - tmp = PSHR32(MULT16_16(coef,oldE),8) + prev[c] + SHL32(q,7); -#ifdef FIXED_POINT - tmp = MAX32(-QCONST32(28.f, DB_SHIFT+7), tmp); -#endif - oldEBands[i+c*m->nbEBands] = PSHR32(tmp, 7); - prev[c] = prev[c] + SHL32(q,7) - MULT16_16(beta,PSHR32(q,8)); - } while (++c < C); - } - return badness; -} - -void quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd, - const opus_val16 *eBands, opus_val16 *oldEBands, opus_uint32 budget, - opus_val16 *error, ec_enc *enc, int C, int LM, int nbAvailableBytes, - int force_intra, opus_val32 *delayedIntra, int two_pass, int loss_rate) -{ - int intra; - opus_val16 max_decay; - VARDECL(opus_val16, oldEBands_intra); - VARDECL(opus_val16, error_intra); - ec_enc enc_start_state; - opus_uint32 tell; - int badness1=0; - opus_int32 intra_bias; - opus_val32 new_distortion; - SAVE_STACK; - - intra = force_intra || (!two_pass && *delayedIntra>2*C*(end-start) && nbAvailableBytes > (end-start)*C); - intra_bias = (opus_int32)((budget**delayedIntra*loss_rate)/(C*512)); - new_distortion = loss_distortion(eBands, oldEBands, start, effEnd, m->nbEBands, C); - - tell = ec_tell(enc); - if (tell+3 > budget) - two_pass = intra = 0; - - /* Encode the global flags using a simple probability model - (first symbols in the stream) */ - - max_decay = QCONST16(16.f,DB_SHIFT); - if (end-start>10) - { -#ifdef FIXED_POINT - max_decay = MIN32(max_decay, SHL32(EXTEND32(nbAvailableBytes),DB_SHIFT-3)); -#else - max_decay = MIN32(max_decay, .125f*nbAvailableBytes); -#endif - } - enc_start_state = *enc; - - ALLOC(oldEBands_intra, C*m->nbEBands, opus_val16); - ALLOC(error_intra, C*m->nbEBands, opus_val16); - OPUS_COPY(oldEBands_intra, oldEBands, C*m->nbEBands); - - if (two_pass || intra) - { - badness1 = quant_coarse_energy_impl(m, start, end, eBands, oldEBands_intra, budget, - tell, e_prob_model[LM][1], error_intra, enc, C, LM, 1, max_decay); - } - - if (!intra) - { - unsigned char *intra_buf; - ec_enc enc_intra_state; - opus_int32 tell_intra; - opus_uint32 nstart_bytes; - opus_uint32 nintra_bytes; - int badness2; - VARDECL(unsigned char, intra_bits); - - tell_intra = ec_tell_frac(enc); - - enc_intra_state = *enc; - - nstart_bytes = ec_range_bytes(&enc_start_state); - nintra_bytes = ec_range_bytes(&enc_intra_state); - intra_buf = ec_get_buffer(&enc_intra_state) + nstart_bytes; - ALLOC(intra_bits, nintra_bytes-nstart_bytes, unsigned char); - /* Copy bits from intra bit-stream */ - OPUS_COPY(intra_bits, intra_buf, nintra_bytes - nstart_bytes); - - *enc = enc_start_state; - - badness2 = quant_coarse_energy_impl(m, start, end, eBands, oldEBands, budget, - tell, e_prob_model[LM][intra], error, enc, C, LM, 0, max_decay); - - if (two_pass && (badness1 < badness2 || (badness1 == badness2 && ((opus_int32)ec_tell_frac(enc))+intra_bias > tell_intra))) - { - *enc = enc_intra_state; - /* Copy intra bits to bit-stream */ - OPUS_COPY(intra_buf, intra_bits, nintra_bytes - nstart_bytes); - OPUS_COPY(oldEBands, oldEBands_intra, C*m->nbEBands); - OPUS_COPY(error, error_intra, C*m->nbEBands); - intra = 1; - } - } else { - OPUS_COPY(oldEBands, oldEBands_intra, C*m->nbEBands); - OPUS_COPY(error, error_intra, C*m->nbEBands); - } - - if (intra) - *delayedIntra = new_distortion; - else - *delayedIntra = ADD32(MULT16_32_Q15(MULT16_16_Q15(pred_coef[LM], pred_coef[LM]),*delayedIntra), - new_distortion); - - RESTORE_STACK; -} - -void quant_fine_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, opus_val16 *error, int *fine_quant, ec_enc *enc, int C) -{ - int i, c; - - /* Encode finer resolution */ - for (i=start;inbEBands]+QCONST16(.5f,DB_SHIFT))>>(DB_SHIFT-fine_quant[i]); -#else - q2 = (int)floor((error[i+c*m->nbEBands]+.5f)*frac); -#endif - if (q2 > frac-1) - q2 = frac-1; - if (q2<0) - q2 = 0; - ec_enc_bits(enc, q2, fine_quant[i]); -#ifdef FIXED_POINT - offset = SUB16(SHR32(SHL32(EXTEND32(q2),DB_SHIFT)+QCONST16(.5f,DB_SHIFT),fine_quant[i]),QCONST16(.5f,DB_SHIFT)); -#else - offset = (q2+.5f)*(1<<(14-fine_quant[i]))*(1.f/16384) - .5f; -#endif - oldEBands[i+c*m->nbEBands] += offset; - error[i+c*m->nbEBands] -= offset; - /*printf ("%f ", error[i] - offset);*/ - } while (++c < C); - } -} - -void quant_energy_finalise(const CELTMode *m, int start, int end, opus_val16 *oldEBands, opus_val16 *error, int *fine_quant, int *fine_priority, int bits_left, ec_enc *enc, int C) -{ - int i, prio, c; - - /* Use up the remaining bits */ - for (prio=0;prio<2;prio++) - { - for (i=start;i=C ;i++) - { - if (fine_quant[i] >= MAX_FINE_BITS || fine_priority[i]!=prio) - continue; - c=0; - do { - int q2; - opus_val16 offset; - q2 = error[i+c*m->nbEBands]<0 ? 0 : 1; - ec_enc_bits(enc, q2, 1); -#ifdef FIXED_POINT - offset = SHR16(SHL16(q2,DB_SHIFT)-QCONST16(.5f,DB_SHIFT),fine_quant[i]+1); -#else - offset = (q2-.5f)*(1<<(14-fine_quant[i]-1))*(1.f/16384); -#endif - oldEBands[i+c*m->nbEBands] += offset; - bits_left--; - } while (++c < C); - } - } -} - -void unquant_coarse_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int intra, ec_dec *dec, int C, int LM) -{ - const unsigned char *prob_model = e_prob_model[LM][intra]; - int i, c; - opus_val32 prev[2] = {0, 0}; - opus_val16 coef; - opus_val16 beta; - opus_int32 budget; - opus_int32 tell; - - if (intra) - { - coef = 0; - beta = beta_intra; - } else { - beta = beta_coef[LM]; - coef = pred_coef[LM]; - } - - budget = dec->storage*8; - - /* Decode at a fixed coarse resolution */ - for (i=start;i=15) - { - int pi; - pi = 2*IMIN(i,20); - qi = ec_laplace_decode(dec, - prob_model[pi]<<7, prob_model[pi+1]<<6); - } - else if(budget-tell>=2) - { - qi = ec_dec_icdf(dec, small_energy_icdf, 2); - qi = (qi>>1)^-(qi&1); - } - else if(budget-tell>=1) - { - qi = -ec_dec_bit_logp(dec, 1); - } - else - qi = -1; - q = (opus_val32)SHL32(EXTEND32(qi),DB_SHIFT); - - oldEBands[i+c*m->nbEBands] = MAX16(-QCONST16(9.f,DB_SHIFT), oldEBands[i+c*m->nbEBands]); - tmp = PSHR32(MULT16_16(coef,oldEBands[i+c*m->nbEBands]),8) + prev[c] + SHL32(q,7); -#ifdef FIXED_POINT - tmp = MAX32(-QCONST32(28.f, DB_SHIFT+7), tmp); -#endif - oldEBands[i+c*m->nbEBands] = PSHR32(tmp, 7); - prev[c] = prev[c] + SHL32(q,7) - MULT16_16(beta,PSHR32(q,8)); - } while (++c < C); - } -} - -void unquant_fine_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int *fine_quant, ec_dec *dec, int C) -{ - int i, c; - /* Decode finer resolution */ - for (i=start;inbEBands] += offset; - } while (++c < C); - } -} - -void unquant_energy_finalise(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int *fine_quant, int *fine_priority, int bits_left, ec_dec *dec, int C) -{ - int i, prio, c; - - /* Use up the remaining bits */ - for (prio=0;prio<2;prio++) - { - for (i=start;i=C ;i++) - { - if (fine_quant[i] >= MAX_FINE_BITS || fine_priority[i]!=prio) - continue; - c=0; - do { - int q2; - opus_val16 offset; - q2 = ec_dec_bits(dec, 1); -#ifdef FIXED_POINT - offset = SHR16(SHL16(q2,DB_SHIFT)-QCONST16(.5f,DB_SHIFT),fine_quant[i]+1); -#else - offset = (q2-.5f)*(1<<(14-fine_quant[i]-1))*(1.f/16384); -#endif - oldEBands[i+c*m->nbEBands] += offset; - bits_left--; - } while (++c < C); - } - } -} - -void log2Amp(const CELTMode *m, int start, int end, - celt_ener *eBands, const opus_val16 *oldEBands, int C) -{ - int c, i; - c=0; - do { - for (i=0;inbEBands] = 0; - for (;inbEBands], - SHL16((opus_val16)eMeans[i],6)); - eBands[i+c*m->nbEBands] = PSHR32(celt_exp2(lg),4); - } - for (;inbEBands;i++) - eBands[i+c*m->nbEBands] = 0; - } while (++c < C); -} - -void amp2Log2(const CELTMode *m, int effEnd, int end, - celt_ener *bandE, opus_val16 *bandLogE, int C) -{ - int c, i; - c=0; - do { - for (i=0;inbEBands] = - celt_log2(SHL32(bandE[i+c*m->nbEBands],2)) - - SHL16((opus_val16)eMeans[i],6); - for (i=effEnd;inbEBands+i] = -QCONST16(14.f,DB_SHIFT); - } while (++c < C); -} diff --git a/src/opus-1.0.2/celt/quant_bands.h b/src/opus-1.0.2/celt/quant_bands.h deleted file mode 100644 index bec2855c..00000000 --- a/src/opus-1.0.2/celt/quant_bands.h +++ /dev/null @@ -1,60 +0,0 @@ -/* Copyright (c) 2007-2008 CSIRO - Copyright (c) 2007-2009 Xiph.Org Foundation - Written by Jean-Marc Valin */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef QUANT_BANDS -#define QUANT_BANDS - -#include "arch.h" -#include "modes.h" -#include "entenc.h" -#include "entdec.h" -#include "mathops.h" - -void amp2Log2(const CELTMode *m, int effEnd, int end, - celt_ener *bandE, opus_val16 *bandLogE, int C); - -void log2Amp(const CELTMode *m, int start, int end, - celt_ener *eBands, const opus_val16 *oldEBands, int C); - -void quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd, - const opus_val16 *eBands, opus_val16 *oldEBands, opus_uint32 budget, - opus_val16 *error, ec_enc *enc, int C, int LM, - int nbAvailableBytes, int force_intra, opus_val32 *delayedIntra, - int two_pass, int loss_rate); - -void quant_fine_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, opus_val16 *error, int *fine_quant, ec_enc *enc, int C); - -void quant_energy_finalise(const CELTMode *m, int start, int end, opus_val16 *oldEBands, opus_val16 *error, int *fine_quant, int *fine_priority, int bits_left, ec_enc *enc, int C); - -void unquant_coarse_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int intra, ec_dec *dec, int C, int LM); - -void unquant_fine_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int *fine_quant, ec_dec *dec, int C); - -void unquant_energy_finalise(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int *fine_quant, int *fine_priority, int bits_left, ec_dec *dec, int C); - -#endif /* QUANT_BANDS */ diff --git a/src/opus-1.0.2/celt/rate.c b/src/opus-1.0.2/celt/rate.c deleted file mode 100644 index 4e96787f..00000000 --- a/src/opus-1.0.2/celt/rate.c +++ /dev/null @@ -1,638 +0,0 @@ -/* Copyright (c) 2007-2008 CSIRO - Copyright (c) 2007-2009 Xiph.Org Foundation - Written by Jean-Marc Valin */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "modes.h" -#include "cwrs.h" -#include "arch.h" -#include "os_support.h" - -#include "entcode.h" -#include "rate.h" - -static const unsigned char LOG2_FRAC_TABLE[24]={ - 0, - 8,13, - 16,19,21,23, - 24,26,27,28,29,30,31,32, - 32,33,34,34,35,36,36,37,37 -}; - -#ifdef CUSTOM_MODES - -/*Determines if V(N,K) fits in a 32-bit unsigned integer. - N and K are themselves limited to 15 bits.*/ -static int fits_in32(int _n, int _k) -{ - static const opus_int16 maxN[15] = { - 32767, 32767, 32767, 1476, 283, 109, 60, 40, - 29, 24, 20, 18, 16, 14, 13}; - static const opus_int16 maxK[15] = { - 32767, 32767, 32767, 32767, 1172, 238, 95, 53, - 36, 27, 22, 18, 16, 15, 13}; - if (_n>=14) - { - if (_k>=14) - return 0; - else - return _n <= maxN[_k]; - } else { - return _k <= maxK[_n]; - } -} - -void compute_pulse_cache(CELTMode *m, int LM) -{ - int C; - int i; - int j; - int curr=0; - int nbEntries=0; - int entryN[100], entryK[100], entryI[100]; - const opus_int16 *eBands = m->eBands; - PulseCache *cache = &m->cache; - opus_int16 *cindex; - unsigned char *bits; - unsigned char *cap; - - cindex = (opus_int16 *)opus_alloc(sizeof(cache->index[0])*m->nbEBands*(LM+2)); - cache->index = cindex; - - /* Scan for all unique band sizes */ - for (i=0;i<=LM+1;i++) - { - for (j=0;jnbEBands;j++) - { - int k; - int N = (eBands[j+1]-eBands[j])<>1; - cindex[i*m->nbEBands+j] = -1; - /* Find other bands that have the same size */ - for (k=0;k<=i;k++) - { - int n; - for (n=0;nnbEBands && (k!=i || n>1) - { - cindex[i*m->nbEBands+j] = cindex[k*m->nbEBands+n]; - break; - } - } - } - if (cache->index[i*m->nbEBands+j] == -1 && N!=0) - { - int K; - entryN[nbEntries] = N; - K = 0; - while (fits_in32(N,get_pulses(K+1)) && KnbEBands+j] = curr; - entryI[nbEntries] = curr; - - curr += K+1; - nbEntries++; - } - } - } - bits = (unsigned char *)opus_alloc(sizeof(unsigned char)*curr); - cache->bits = bits; - cache->size = curr; - /* Compute the cache for all unique sizes */ - for (i=0;icaps = cap = (unsigned char *)opus_alloc(sizeof(cache->caps[0])*(LM+1)*2*m->nbEBands); - for (i=0;i<=LM;i++) - { - for (C=1;C<=2;C++) - { - for (j=0;jnbEBands;j++) - { - int N0; - int max_bits; - N0 = m->eBands[j+1]-m->eBands[j]; - /* N=1 bands only have a sign bit and fine bits. */ - if (N0<1 are even, including custom modes.*/ - if (N0 > 2) - { - N0>>=1; - LM0--; - } - /* N0=1 bands can't be split down to N<2. */ - else if (N0 <= 1) - { - LM0=IMIN(i,1); - N0<<=LM0; - } - /* Compute the cost for the lowest-level PVQ of a fully split - band. */ - pcache = bits + cindex[(LM0+1)*m->nbEBands+j]; - max_bits = pcache[pcache[0]]+1; - /* Add in the cost of coding regular splits. */ - N = N0; - for(k=0;klogN[j]+((LM0+k)<>1)-QTHETA_OFFSET; - /* The number of qtheta bits we'll allocate if the remainder - is to be max_bits. - The average measured cost for theta is 0.89701 times qb, - approximated here as 459/512. */ - num=459*(opus_int32)((2*N-1)*offset+max_bits); - den=((opus_int32)(2*N-1)<<9)-459; - qb = IMIN((num+(den>>1))/den, 57); - celt_assert(qb >= 0); - max_bits += qb; - N <<= 1; - } - /* Add in the cost of a stereo split, if necessary. */ - if (C==2) - { - max_bits <<= 1; - offset = ((m->logN[j]+(i<>1)-(N==2?QTHETA_OFFSET_TWOPHASE:QTHETA_OFFSET); - ndof = 2*N-1-(N==2); - /* The average measured cost for theta with the step PDF is - 0.95164 times qb, approximated here as 487/512. */ - num = (N==2?512:487)*(opus_int32)(max_bits+ndof*offset); - den = ((opus_int32)ndof<<9)-(N==2?512:487); - qb = IMIN((num+(den>>1))/den, (N==2?64:61)); - celt_assert(qb >= 0); - max_bits += qb; - } - /* Add the fine bits we'll use. */ - /* Compensate for the extra DoF in stereo */ - ndof = C*N + ((C==2 && N>2) ? 1 : 0); - /* Offset the number of fine bits by log2(N)/2 + FINE_OFFSET - compared to their "fair share" of total/N */ - offset = ((m->logN[j] + (i<>1)-FINE_OFFSET; - /* N=2 is the only point that doesn't match the curve */ - if (N==2) - offset += 1<>2; - /* The number of fine bits we'll allocate if the remainder is - to be max_bits. */ - num = max_bits+ndof*offset; - den = (ndof-1)<>1))/den, MAX_FINE_BITS); - celt_assert(qb >= 0); - max_bits += C*qb<eBands[j+1]-m->eBands[j])<= 0); - celt_assert(max_bits < 256); - *cap++ = (unsigned char)max_bits; - } - } - } -} - -#endif /* CUSTOM_MODES */ - -#define ALLOC_STEPS 6 - -static inline int interp_bits2pulses(const CELTMode *m, int start, int end, int skip_start, - const int *bits1, const int *bits2, const int *thresh, const int *cap, opus_int32 total, opus_int32 *_balance, - int skip_rsv, int *intensity, int intensity_rsv, int *dual_stereo, int dual_stereo_rsv, int *bits, - int *ebits, int *fine_priority, int C, int LM, ec_ctx *ec, int encode, int prev) -{ - opus_int32 psum; - int lo, hi; - int i, j; - int logM; - int stereo; - int codedBands=-1; - int alloc_floor; - opus_int32 left, percoeff; - int done; - opus_int32 balance; - SAVE_STACK; - - alloc_floor = C<1; - - logM = LM<>1; - psum = 0; - done = 0; - for (j=end;j-->start;) - { - int tmp = bits1[j] + (mid*(opus_int32)bits2[j]>>ALLOC_STEPS); - if (tmp >= thresh[j] || done) - { - done = 1; - /* Don't allocate more than we can actually use */ - psum += IMIN(tmp, cap[j]); - } else { - if (tmp >= alloc_floor) - psum += alloc_floor; - } - } - if (psum > total) - hi = mid; - else - lo = mid; - } - psum = 0; - /*printf ("interp bisection gave %d\n", lo);*/ - done = 0; - for (j=end;j-->start;) - { - int tmp = bits1[j] + (lo*bits2[j]>>ALLOC_STEPS); - if (tmp < thresh[j] && !done) - { - if (tmp >= alloc_floor) - tmp = alloc_floor; - else - tmp = 0; - } else - done = 1; - /* Don't allocate more than we can actually use */ - tmp = IMIN(tmp, cap[j]); - bits[j] = tmp; - psum += tmp; - } - - /* Decide which bands to skip, working backwards from the end. */ - for (codedBands=end;;codedBands--) - { - int band_width; - int band_bits; - int rem; - j = codedBands-1; - /* Never skip the first band, nor a band that has been boosted by - dynalloc. - In the first case, we'd be coding a bit to signal we're going to waste - all the other bits. - In the second case, we'd be coding a bit to redistribute all the bits - we just signaled should be cocentrated in this band. */ - if (j<=skip_start) - { - /* Give the bit we reserved to end skipping back. */ - total += skip_rsv; - break; - } - /*Figure out how many left-over bits we would be adding to this band. - This can include bits we've stolen back from higher, skipped bands.*/ - left = total-psum; - percoeff = left/(m->eBands[codedBands]-m->eBands[start]); - left -= (m->eBands[codedBands]-m->eBands[start])*percoeff; - rem = IMAX(left-(m->eBands[j]-m->eBands[start]),0); - band_width = m->eBands[codedBands]-m->eBands[j]; - band_bits = (int)(bits[j] + percoeff*band_width + rem); - /*Only code a skip decision if we're above the threshold for this band. - Otherwise it is force-skipped. - This ensures that we have enough bits to code the skip flag.*/ - if (band_bits >= IMAX(thresh[j], alloc_floor+(1< ((j>4) -#endif - { - ec_enc_bit_logp(ec, 1, 1); - break; - } - ec_enc_bit_logp(ec, 0, 1); - } else if (ec_dec_bit_logp(ec, 1)) { - break; - } - /*We used a bit to skip this band.*/ - psum += 1< 0) - intensity_rsv = LOG2_FRAC_TABLE[j-start]; - psum += intensity_rsv; - if (band_bits >= alloc_floor) - { - /*If we have enough for a fine energy bit per channel, use it.*/ - psum += alloc_floor; - bits[j] = alloc_floor; - } else { - /*Otherwise this band gets nothing at all.*/ - bits[j] = 0; - } - } - - celt_assert(codedBands > start); - /* Code the intensity and dual stereo parameters. */ - if (intensity_rsv > 0) - { - if (encode) - { - *intensity = IMIN(*intensity, codedBands); - ec_enc_uint(ec, *intensity-start, codedBands+1-start); - } - else - *intensity = start+ec_dec_uint(ec, codedBands+1-start); - } - else - *intensity = 0; - if (*intensity <= start) - { - total += dual_stereo_rsv; - dual_stereo_rsv = 0; - } - if (dual_stereo_rsv > 0) - { - if (encode) - ec_enc_bit_logp(ec, *dual_stereo, 1); - else - *dual_stereo = ec_dec_bit_logp(ec, 1); - } - else - *dual_stereo = 0; - - /* Allocate the remaining bits */ - left = total-psum; - percoeff = left/(m->eBands[codedBands]-m->eBands[start]); - left -= (m->eBands[codedBands]-m->eBands[start])*percoeff; - for (j=start;jeBands[j+1]-m->eBands[j])); - for (j=start;jeBands[j+1]-m->eBands[j]); - bits[j] += tmp; - left -= tmp; - } - /*for (j=0;j= 0); - N0 = m->eBands[j+1]-m->eBands[j]; - N=N0<1) - { - excess = MAX32(bit-cap[j],0); - bits[j] = bit-excess; - - /* Compensate for the extra DoF in stereo */ - den=(C*N+ ((C==2 && N>2 && !*dual_stereo && j<*intensity) ? 1 : 0)); - - NClogN = den*(m->logN[j] + logM); - - /* Offset for the number of fine bits by log2(N)/2 + FINE_OFFSET - compared to their "fair share" of total/N */ - offset = (NClogN>>1)-den*FINE_OFFSET; - - /* N=2 is the only point that doesn't match the curve */ - if (N==2) - offset += den<>2; - - /* Changing the offset for allocating the second and third - fine energy bit */ - if (bits[j] + offset < den*2<>2; - else if (bits[j] + offset < den*3<>3; - - /* Divide with rounding */ - ebits[j] = IMAX(0, (bits[j] + offset + (den<<(BITRES-1))) / (den< (bits[j]>>BITRES)) - ebits[j] = bits[j] >> stereo >> BITRES; - - /* More than that is useless because that's about as far as PVQ can go */ - ebits[j] = IMIN(ebits[j], MAX_FINE_BITS); - - /* If we rounded down or capped this band, make it a candidate for the - final fine energy pass */ - fine_priority[j] = ebits[j]*(den<= bits[j]+offset; - - /* Remove the allocated fine bits; the rest are assigned to PVQ */ - bits[j] -= C*ebits[j]< 0) - { - int extra_fine; - int extra_bits; - extra_fine = IMIN(excess>>(stereo+BITRES),MAX_FINE_BITS-ebits[j]); - ebits[j] += extra_fine; - extra_bits = extra_fine*C<= excess-balance; - excess -= extra_bits; - } - balance = excess; - - celt_assert(bits[j] >= 0); - celt_assert(ebits[j] >= 0); - } - /* Save any remaining bits over the cap for the rebalancing in - quant_all_bands(). */ - *_balance = balance; - - /* The skipped bands use all their bits for fine energy. */ - for (;j> stereo >> BITRES; - celt_assert(C*ebits[j]<nbEBands; - skip_start = start; - /* Reserve a bit to signal the end of manually skipped bands. */ - skip_rsv = total >= 1<total) - intensity_rsv = 0; - else - { - total -= intensity_rsv; - dual_stereo_rsv = total>=1<eBands[j+1]-m->eBands[j])<>4); - /* Tilt of the allocation curve */ - trim_offset[j] = C*(m->eBands[j+1]-m->eBands[j])*(alloc_trim-5-LM)*(end-j-1) - *(1<<(LM+BITRES))>>6; - /* Giving less resolution to single-coefficient bands because they get - more benefit from having one coarse value per coefficient*/ - if ((m->eBands[j+1]-m->eBands[j])<nbAllocVectors - 1; - do - { - int done = 0; - int psum = 0; - int mid = (lo+hi) >> 1; - for (j=end;j-->start;) - { - int bitsj; - int N = m->eBands[j+1]-m->eBands[j]; - bitsj = C*N*m->allocVectors[mid*len+j]<>2; - if (bitsj > 0) - bitsj = IMAX(0, bitsj + trim_offset[j]); - bitsj += offsets[j]; - if (bitsj >= thresh[j] || done) - { - done = 1; - /* Don't allocate more than we can actually use */ - psum += IMIN(bitsj, cap[j]); - } else { - if (bitsj >= C< total) - hi = mid - 1; - else - lo = mid + 1; - /*printf ("lo = %d, hi = %d\n", lo, hi);*/ - } - while (lo <= hi); - hi = lo--; - /*printf ("interp between %d and %d\n", lo, hi);*/ - for (j=start;jeBands[j+1]-m->eBands[j]; - bits1j = C*N*m->allocVectors[lo*len+j]<>2; - bits2j = hi>=m->nbAllocVectors ? - cap[j] : C*N*m->allocVectors[hi*len+j]<>2; - if (bits1j > 0) - bits1j = IMAX(0, bits1j + trim_offset[j]); - if (bits2j > 0) - bits2j = IMAX(0, bits2j + trim_offset[j]); - if (lo > 0) - bits1j += offsets[j]; - bits2j += offsets[j]; - if (offsets[j]>0) - skip_start = j; - bits2j = IMAX(0,bits2j-bits1j); - bits1[j] = bits1j; - bits2[j] = bits2j; - } - codedBands = interp_bits2pulses(m, start, end, skip_start, bits1, bits2, thresh, cap, - total, balance, skip_rsv, intensity, intensity_rsv, dual_stereo, dual_stereo_rsv, - pulses, ebits, fine_priority, C, LM, ec, encode, prev); - RESTORE_STACK; - return codedBands; -} - diff --git a/src/opus-1.0.2/celt/rate.h b/src/opus-1.0.2/celt/rate.h deleted file mode 100644 index e0d50223..00000000 --- a/src/opus-1.0.2/celt/rate.h +++ /dev/null @@ -1,101 +0,0 @@ -/* Copyright (c) 2007-2008 CSIRO - Copyright (c) 2007-2009 Xiph.Org Foundation - Written by Jean-Marc Valin */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef RATE_H -#define RATE_H - -#define MAX_PSEUDO 40 -#define LOG_MAX_PSEUDO 6 - -#define MAX_PULSES 128 - -#define MAX_FINE_BITS 8 - -#define FINE_OFFSET 21 -#define QTHETA_OFFSET 4 -#define QTHETA_OFFSET_TWOPHASE 16 - -#include "cwrs.h" -#include "modes.h" - -void compute_pulse_cache(CELTMode *m, int LM); - -static inline int get_pulses(int i) -{ - return i<8 ? i : (8 + (i&7)) << ((i>>3)-1); -} - -static inline int bits2pulses(const CELTMode *m, int band, int LM, int bits) -{ - int i; - int lo, hi; - const unsigned char *cache; - - LM++; - cache = m->cache.bits + m->cache.index[LM*m->nbEBands+band]; - - lo = 0; - hi = cache[0]; - bits--; - for (i=0;i>1; - /* OPT: Make sure this is implemented with a conditional move */ - if ((int)cache[mid] >= bits) - hi = mid; - else - lo = mid; - } - if (bits- (lo == 0 ? -1 : (int)cache[lo]) <= (int)cache[hi]-bits) - return lo; - else - return hi; -} - -static inline int pulses2bits(const CELTMode *m, int band, int LM, int pulses) -{ - const unsigned char *cache; - - LM++; - cache = m->cache.bits + m->cache.index[LM*m->nbEBands+band]; - return pulses == 0 ? 0 : cache[pulses]+1; -} - -/** Compute the pulse allocation, i.e. how many pulses will go in each - * band. - @param m mode - @param offsets Requested increase or decrease in the number of bits for - each band - @param total Number of bands - @param pulses Number of pulses per band (returned) - @return Total number of bits allocated -*/ -int compute_allocation(const CELTMode *m, int start, int end, const int *offsets, const int *cap, int alloc_trim, int *intensity, int *dual_stero, - opus_int32 total, opus_int32 *balance, int *pulses, int *ebits, int *fine_priority, int C, int LM, ec_ctx *ec, int encode, int prev); - -#endif diff --git a/src/opus-1.0.2/celt/stack_alloc.h b/src/opus-1.0.2/celt/stack_alloc.h deleted file mode 100644 index a6f06d22..00000000 --- a/src/opus-1.0.2/celt/stack_alloc.h +++ /dev/null @@ -1,149 +0,0 @@ -/* Copyright (C) 2002-2003 Jean-Marc Valin - Copyright (C) 2007-2009 Xiph.Org Foundation */ -/** - @file stack_alloc.h - @brief Temporary memory allocation on stack -*/ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef STACK_ALLOC_H -#define STACK_ALLOC_H - -#if (!defined (VAR_ARRAYS) && !defined (USE_ALLOCA) && !defined (NONTHREADSAFE_PSEUDOSTACK)) -#error "Opus requires one of VAR_ARRAYS, USE_ALLOCA, or NONTHREADSAFE_PSEUDOSTACK be defined to select the temporary allocation mode." -#endif - -#ifdef USE_ALLOCA -# ifdef WIN32 -# include -# else -# ifdef HAVE_ALLOCA_H -# include -# else -# include -# endif -# endif -#endif - -/** - * @def ALIGN(stack, size) - * - * Aligns the stack to a 'size' boundary - * - * @param stack Stack - * @param size New size boundary - */ - -/** - * @def PUSH(stack, size, type) - * - * Allocates 'size' elements of type 'type' on the stack - * - * @param stack Stack - * @param size Number of elements - * @param type Type of element - */ - -/** - * @def VARDECL(var) - * - * Declare variable on stack - * - * @param var Variable to declare - */ - -/** - * @def ALLOC(var, size, type) - * - * Allocate 'size' elements of 'type' on stack - * - * @param var Name of variable to allocate - * @param size Number of elements - * @param type Type of element - */ - -#if defined(VAR_ARRAYS) - -#define VARDECL(type, var) -#define ALLOC(var, size, type) type var[size] -#define SAVE_STACK -#define RESTORE_STACK -#define ALLOC_STACK - -#elif defined(USE_ALLOCA) - -#define VARDECL(type, var) type *var - -# ifdef WIN32 -# define ALLOC(var, size, type) var = ((type*)_alloca(sizeof(type)*(size))) -# else -# define ALLOC(var, size, type) var = ((type*)alloca(sizeof(type)*(size))) -# endif - -#define SAVE_STACK -#define RESTORE_STACK -#define ALLOC_STACK - -#else - -#ifdef CELT_C -char *global_stack=0; -#else -extern char *global_stack; -#endif /* CELT_C */ - -#ifdef ENABLE_VALGRIND - -#include - -#ifdef CELT_C -char *global_stack_top=0; -#else -extern char *global_stack_top; -#endif /* CELT_C */ - -#define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1)) -#define PUSH(stack, size, type) (VALGRIND_MAKE_MEM_NOACCESS(stack, global_stack_top-stack),ALIGN((stack),sizeof(type)/sizeof(char)),VALGRIND_MAKE_MEM_UNDEFINED(stack, ((size)*sizeof(type)/sizeof(char))),(stack)+=(2*(size)*sizeof(type)/sizeof(char)),(type*)((stack)-(2*(size)*sizeof(type)/sizeof(char)))) -#define RESTORE_STACK ((global_stack = _saved_stack),VALGRIND_MAKE_MEM_NOACCESS(global_stack, global_stack_top-global_stack)) -#define ALLOC_STACK char *_saved_stack; ((global_stack = (global_stack==0) ? ((global_stack_top=opus_alloc_scratch(GLOBAL_STACK_SIZE*2)+(GLOBAL_STACK_SIZE*2))-(GLOBAL_STACK_SIZE*2)) : global_stack),VALGRIND_MAKE_MEM_NOACCESS(global_stack, global_stack_top-global_stack)); _saved_stack = global_stack; - -#else - -#define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1)) -#define PUSH(stack, size, type) (ALIGN((stack),sizeof(type)/sizeof(char)),(stack)+=(size)*(sizeof(type)/sizeof(char)),(type*)((stack)-(size)*(sizeof(type)/sizeof(char)))) -#define RESTORE_STACK (global_stack = _saved_stack) -#define ALLOC_STACK char *_saved_stack; (global_stack = (global_stack==0) ? opus_alloc_scratch(GLOBAL_STACK_SIZE) : global_stack); _saved_stack = global_stack; - -#endif /* ENABLE_VALGRIND */ - -#include "os_support.h" -#define VARDECL(type, var) type *var -#define ALLOC(var, size, type) var = PUSH(global_stack, size, type) -#define SAVE_STACK char *_saved_stack = global_stack; - -#endif /* VAR_ARRAYS */ - -#endif /* STACK_ALLOC_H */ diff --git a/src/opus-1.0.2/celt/static_modes_fixed.h b/src/opus-1.0.2/celt/static_modes_fixed.h deleted file mode 100644 index 216df9e6..00000000 --- a/src/opus-1.0.2/celt/static_modes_fixed.h +++ /dev/null @@ -1,595 +0,0 @@ -/* The contents of this file was automatically generated by dump_modes.c - with arguments: 48000 960 - It contains static definitions for some pre-defined modes. */ -#include "modes.h" -#include "rate.h" - -#ifndef DEF_WINDOW120 -#define DEF_WINDOW120 -static const opus_val16 window120[120] = { -2, 20, 55, 108, 178, -266, 372, 494, 635, 792, -966, 1157, 1365, 1590, 1831, -2089, 2362, 2651, 2956, 3276, -3611, 3961, 4325, 4703, 5094, -5499, 5916, 6346, 6788, 7241, -7705, 8179, 8663, 9156, 9657, -10167, 10684, 11207, 11736, 12271, -12810, 13353, 13899, 14447, 14997, -15547, 16098, 16648, 17197, 17744, -18287, 18827, 19363, 19893, 20418, -20936, 21447, 21950, 22445, 22931, -23407, 23874, 24330, 24774, 25208, -25629, 26039, 26435, 26819, 27190, -27548, 27893, 28224, 28541, 28845, -29135, 29411, 29674, 29924, 30160, -30384, 30594, 30792, 30977, 31151, -31313, 31463, 31602, 31731, 31849, -31958, 32057, 32148, 32229, 32303, -32370, 32429, 32481, 32528, 32568, -32604, 32634, 32661, 32683, 32701, -32717, 32729, 32740, 32748, 32754, -32758, 32762, 32764, 32766, 32767, -32767, 32767, 32767, 32767, 32767, -}; -#endif - -#ifndef DEF_LOGN400 -#define DEF_LOGN400 -static const opus_int16 logN400[21] = { -0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 16, 16, 16, 21, 21, 24, 29, 34, 36, }; -#endif - -#ifndef DEF_PULSE_CACHE50 -#define DEF_PULSE_CACHE50 -static const opus_int16 cache_index50[105] = { --1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 41, 41, 41, -82, 82, 123, 164, 200, 222, 0, 0, 0, 0, 0, 0, 0, 0, 41, -41, 41, 41, 123, 123, 123, 164, 164, 240, 266, 283, 295, 41, 41, 41, -41, 41, 41, 41, 41, 123, 123, 123, 123, 240, 240, 240, 266, 266, 305, -318, 328, 336, 123, 123, 123, 123, 123, 123, 123, 123, 240, 240, 240, 240, -305, 305, 305, 318, 318, 343, 351, 358, 364, 240, 240, 240, 240, 240, 240, -240, 240, 305, 305, 305, 305, 343, 343, 343, 351, 351, 370, 376, 382, 387, -}; -static const unsigned char cache_bits50[392] = { -40, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 40, 15, 23, 28, -31, 34, 36, 38, 39, 41, 42, 43, 44, 45, 46, 47, 47, 49, 50, -51, 52, 53, 54, 55, 55, 57, 58, 59, 60, 61, 62, 63, 63, 65, -66, 67, 68, 69, 70, 71, 71, 40, 20, 33, 41, 48, 53, 57, 61, -64, 66, 69, 71, 73, 75, 76, 78, 80, 82, 85, 87, 89, 91, 92, -94, 96, 98, 101, 103, 105, 107, 108, 110, 112, 114, 117, 119, 121, 123, -124, 126, 128, 40, 23, 39, 51, 60, 67, 73, 79, 83, 87, 91, 94, -97, 100, 102, 105, 107, 111, 115, 118, 121, 124, 126, 129, 131, 135, 139, -142, 145, 148, 150, 153, 155, 159, 163, 166, 169, 172, 174, 177, 179, 35, -28, 49, 65, 78, 89, 99, 107, 114, 120, 126, 132, 136, 141, 145, 149, -153, 159, 165, 171, 176, 180, 185, 189, 192, 199, 205, 211, 216, 220, 225, -229, 232, 239, 245, 251, 21, 33, 58, 79, 97, 112, 125, 137, 148, 157, -166, 174, 182, 189, 195, 201, 207, 217, 227, 235, 243, 251, 17, 35, 63, -86, 106, 123, 139, 152, 165, 177, 187, 197, 206, 214, 222, 230, 237, 250, -25, 31, 55, 75, 91, 105, 117, 128, 138, 146, 154, 161, 168, 174, 180, -185, 190, 200, 208, 215, 222, 229, 235, 240, 245, 255, 16, 36, 65, 89, -110, 128, 144, 159, 173, 185, 196, 207, 217, 226, 234, 242, 250, 11, 41, -74, 103, 128, 151, 172, 191, 209, 225, 241, 255, 9, 43, 79, 110, 138, -163, 186, 207, 227, 246, 12, 39, 71, 99, 123, 144, 164, 182, 198, 214, -228, 241, 253, 9, 44, 81, 113, 142, 168, 192, 214, 235, 255, 7, 49, -90, 127, 160, 191, 220, 247, 6, 51, 95, 134, 170, 203, 234, 7, 47, -87, 123, 155, 184, 212, 237, 6, 52, 97, 137, 174, 208, 240, 5, 57, -106, 151, 192, 231, 5, 59, 111, 158, 202, 243, 5, 55, 103, 147, 187, -224, 5, 60, 113, 161, 206, 248, 4, 65, 122, 175, 224, 4, 67, 127, -182, 234, }; -static const unsigned char cache_caps50[168] = { -224, 224, 224, 224, 224, 224, 224, 224, 160, 160, 160, 160, 185, 185, 185, -178, 178, 168, 134, 61, 37, 224, 224, 224, 224, 224, 224, 224, 224, 240, -240, 240, 240, 207, 207, 207, 198, 198, 183, 144, 66, 40, 160, 160, 160, -160, 160, 160, 160, 160, 185, 185, 185, 185, 193, 193, 193, 183, 183, 172, -138, 64, 38, 240, 240, 240, 240, 240, 240, 240, 240, 207, 207, 207, 207, -204, 204, 204, 193, 193, 180, 143, 66, 40, 185, 185, 185, 185, 185, 185, -185, 185, 193, 193, 193, 193, 193, 193, 193, 183, 183, 172, 138, 65, 39, -207, 207, 207, 207, 207, 207, 207, 207, 204, 204, 204, 204, 201, 201, 201, -188, 188, 176, 141, 66, 40, 193, 193, 193, 193, 193, 193, 193, 193, 193, -193, 193, 193, 194, 194, 194, 184, 184, 173, 139, 65, 39, 204, 204, 204, -204, 204, 204, 204, 204, 201, 201, 201, 201, 198, 198, 198, 187, 187, 175, -140, 66, 40, }; -#endif - -#ifndef FFT_TWIDDLES48000_960 -#define FFT_TWIDDLES48000_960 -static const kiss_twiddle_cpx fft_twiddles48000_960[480] = { -{32767, 0}, {32766, -429}, -{32757, -858}, {32743, -1287}, -{32724, -1715}, {32698, -2143}, -{32667, -2570}, {32631, -2998}, -{32588, -3425}, {32541, -3851}, -{32488, -4277}, {32429, -4701}, -{32364, -5125}, {32295, -5548}, -{32219, -5971}, {32138, -6393}, -{32051, -6813}, {31960, -7231}, -{31863, -7650}, {31760, -8067}, -{31652, -8481}, {31539, -8895}, -{31419, -9306}, {31294, -9716}, -{31165, -10126}, {31030, -10532}, -{30889, -10937}, {30743, -11340}, -{30592, -11741}, {30436, -12141}, -{30274, -12540}, {30107, -12935}, -{29936, -13328}, {29758, -13718}, -{29577, -14107}, {29390, -14493}, -{29197, -14875}, {29000, -15257}, -{28797, -15635}, {28590, -16010}, -{28379, -16384}, {28162, -16753}, -{27940, -17119}, {27714, -17484}, -{27482, -17845}, {27246, -18205}, -{27006, -18560}, {26760, -18911}, -{26510, -19260}, {26257, -19606}, -{25997, -19947}, {25734, -20286}, -{25466, -20621}, {25194, -20952}, -{24918, -21281}, {24637, -21605}, -{24353, -21926}, {24063, -22242}, -{23770, -22555}, {23473, -22865}, -{23171, -23171}, {22866, -23472}, -{22557, -23769}, {22244, -24063}, -{21927, -24352}, {21606, -24636}, -{21282, -24917}, {20954, -25194}, -{20622, -25465}, {20288, -25733}, -{19949, -25997}, {19607, -26255}, -{19261, -26509}, {18914, -26760}, -{18561, -27004}, {18205, -27246}, -{17846, -27481}, {17485, -27713}, -{17122, -27940}, {16755, -28162}, -{16385, -28378}, {16012, -28590}, -{15636, -28797}, {15258, -28999}, -{14878, -29197}, {14494, -29389}, -{14108, -29576}, {13720, -29757}, -{13329, -29934}, {12937, -30107}, -{12540, -30274}, {12142, -30435}, -{11744, -30592}, {11342, -30743}, -{10939, -30889}, {10534, -31030}, -{10127, -31164}, {9718, -31294}, -{9307, -31418}, {8895, -31537}, -{8482, -31652}, {8067, -31759}, -{7650, -31862}, {7233, -31960}, -{6815, -32051}, {6393, -32138}, -{5973, -32219}, {5549, -32294}, -{5127, -32364}, {4703, -32429}, -{4278, -32487}, {3852, -32541}, -{3426, -32588}, {2999, -32630}, -{2572, -32667}, {2144, -32698}, -{1716, -32724}, {1287, -32742}, -{860, -32757}, {430, -32766}, -{0, -32767}, {-429, -32766}, -{-858, -32757}, {-1287, -32743}, -{-1715, -32724}, {-2143, -32698}, -{-2570, -32667}, {-2998, -32631}, -{-3425, -32588}, {-3851, -32541}, -{-4277, -32488}, {-4701, -32429}, -{-5125, -32364}, {-5548, -32295}, -{-5971, -32219}, {-6393, -32138}, -{-6813, -32051}, {-7231, -31960}, -{-7650, -31863}, {-8067, -31760}, -{-8481, -31652}, {-8895, -31539}, -{-9306, -31419}, {-9716, -31294}, -{-10126, -31165}, {-10532, -31030}, -{-10937, -30889}, {-11340, -30743}, -{-11741, -30592}, {-12141, -30436}, -{-12540, -30274}, {-12935, -30107}, -{-13328, -29936}, {-13718, -29758}, -{-14107, -29577}, {-14493, -29390}, -{-14875, -29197}, {-15257, -29000}, -{-15635, -28797}, {-16010, -28590}, -{-16384, -28379}, {-16753, -28162}, -{-17119, -27940}, {-17484, -27714}, -{-17845, -27482}, {-18205, -27246}, -{-18560, -27006}, {-18911, -26760}, -{-19260, -26510}, {-19606, -26257}, -{-19947, -25997}, {-20286, -25734}, -{-20621, -25466}, {-20952, -25194}, -{-21281, -24918}, {-21605, -24637}, -{-21926, -24353}, {-22242, -24063}, -{-22555, -23770}, {-22865, -23473}, -{-23171, -23171}, {-23472, -22866}, -{-23769, -22557}, {-24063, -22244}, -{-24352, -21927}, {-24636, -21606}, -{-24917, -21282}, {-25194, -20954}, -{-25465, -20622}, {-25733, -20288}, -{-25997, -19949}, {-26255, -19607}, -{-26509, -19261}, {-26760, -18914}, -{-27004, -18561}, {-27246, -18205}, -{-27481, -17846}, {-27713, -17485}, -{-27940, -17122}, {-28162, -16755}, -{-28378, -16385}, {-28590, -16012}, -{-28797, -15636}, {-28999, -15258}, -{-29197, -14878}, {-29389, -14494}, -{-29576, -14108}, {-29757, -13720}, -{-29934, -13329}, {-30107, -12937}, -{-30274, -12540}, {-30435, -12142}, -{-30592, -11744}, {-30743, -11342}, -{-30889, -10939}, {-31030, -10534}, -{-31164, -10127}, {-31294, -9718}, -{-31418, -9307}, {-31537, -8895}, -{-31652, -8482}, {-31759, -8067}, -{-31862, -7650}, {-31960, -7233}, -{-32051, -6815}, {-32138, -6393}, -{-32219, -5973}, {-32294, -5549}, -{-32364, -5127}, {-32429, -4703}, -{-32487, -4278}, {-32541, -3852}, -{-32588, -3426}, {-32630, -2999}, -{-32667, -2572}, {-32698, -2144}, -{-32724, -1716}, {-32742, -1287}, -{-32757, -860}, {-32766, -430}, -{-32767, 0}, {-32766, 429}, -{-32757, 858}, {-32743, 1287}, -{-32724, 1715}, {-32698, 2143}, -{-32667, 2570}, {-32631, 2998}, -{-32588, 3425}, {-32541, 3851}, -{-32488, 4277}, {-32429, 4701}, -{-32364, 5125}, {-32295, 5548}, -{-32219, 5971}, {-32138, 6393}, -{-32051, 6813}, {-31960, 7231}, -{-31863, 7650}, {-31760, 8067}, -{-31652, 8481}, {-31539, 8895}, -{-31419, 9306}, {-31294, 9716}, -{-31165, 10126}, {-31030, 10532}, -{-30889, 10937}, {-30743, 11340}, -{-30592, 11741}, {-30436, 12141}, -{-30274, 12540}, {-30107, 12935}, -{-29936, 13328}, {-29758, 13718}, -{-29577, 14107}, {-29390, 14493}, -{-29197, 14875}, {-29000, 15257}, -{-28797, 15635}, {-28590, 16010}, -{-28379, 16384}, {-28162, 16753}, -{-27940, 17119}, {-27714, 17484}, -{-27482, 17845}, {-27246, 18205}, -{-27006, 18560}, {-26760, 18911}, -{-26510, 19260}, {-26257, 19606}, -{-25997, 19947}, {-25734, 20286}, -{-25466, 20621}, {-25194, 20952}, -{-24918, 21281}, {-24637, 21605}, -{-24353, 21926}, {-24063, 22242}, -{-23770, 22555}, {-23473, 22865}, -{-23171, 23171}, {-22866, 23472}, -{-22557, 23769}, {-22244, 24063}, -{-21927, 24352}, {-21606, 24636}, -{-21282, 24917}, {-20954, 25194}, -{-20622, 25465}, {-20288, 25733}, -{-19949, 25997}, {-19607, 26255}, -{-19261, 26509}, {-18914, 26760}, -{-18561, 27004}, {-18205, 27246}, -{-17846, 27481}, {-17485, 27713}, -{-17122, 27940}, {-16755, 28162}, -{-16385, 28378}, {-16012, 28590}, -{-15636, 28797}, {-15258, 28999}, -{-14878, 29197}, {-14494, 29389}, -{-14108, 29576}, {-13720, 29757}, -{-13329, 29934}, {-12937, 30107}, -{-12540, 30274}, {-12142, 30435}, -{-11744, 30592}, {-11342, 30743}, -{-10939, 30889}, {-10534, 31030}, -{-10127, 31164}, {-9718, 31294}, -{-9307, 31418}, {-8895, 31537}, -{-8482, 31652}, {-8067, 31759}, -{-7650, 31862}, {-7233, 31960}, -{-6815, 32051}, {-6393, 32138}, -{-5973, 32219}, {-5549, 32294}, -{-5127, 32364}, {-4703, 32429}, -{-4278, 32487}, {-3852, 32541}, -{-3426, 32588}, {-2999, 32630}, -{-2572, 32667}, {-2144, 32698}, -{-1716, 32724}, {-1287, 32742}, -{-860, 32757}, {-430, 32766}, -{0, 32767}, {429, 32766}, -{858, 32757}, {1287, 32743}, -{1715, 32724}, {2143, 32698}, -{2570, 32667}, {2998, 32631}, -{3425, 32588}, {3851, 32541}, -{4277, 32488}, {4701, 32429}, -{5125, 32364}, {5548, 32295}, -{5971, 32219}, {6393, 32138}, -{6813, 32051}, {7231, 31960}, -{7650, 31863}, {8067, 31760}, -{8481, 31652}, {8895, 31539}, -{9306, 31419}, {9716, 31294}, -{10126, 31165}, {10532, 31030}, -{10937, 30889}, {11340, 30743}, -{11741, 30592}, {12141, 30436}, -{12540, 30274}, {12935, 30107}, -{13328, 29936}, {13718, 29758}, -{14107, 29577}, {14493, 29390}, -{14875, 29197}, {15257, 29000}, -{15635, 28797}, {16010, 28590}, -{16384, 28379}, {16753, 28162}, -{17119, 27940}, {17484, 27714}, -{17845, 27482}, {18205, 27246}, -{18560, 27006}, {18911, 26760}, -{19260, 26510}, {19606, 26257}, -{19947, 25997}, {20286, 25734}, -{20621, 25466}, {20952, 25194}, -{21281, 24918}, {21605, 24637}, -{21926, 24353}, {22242, 24063}, -{22555, 23770}, {22865, 23473}, -{23171, 23171}, {23472, 22866}, -{23769, 22557}, {24063, 22244}, -{24352, 21927}, {24636, 21606}, -{24917, 21282}, {25194, 20954}, -{25465, 20622}, {25733, 20288}, -{25997, 19949}, {26255, 19607}, -{26509, 19261}, {26760, 18914}, -{27004, 18561}, {27246, 18205}, -{27481, 17846}, {27713, 17485}, -{27940, 17122}, {28162, 16755}, -{28378, 16385}, {28590, 16012}, -{28797, 15636}, {28999, 15258}, -{29197, 14878}, {29389, 14494}, -{29576, 14108}, {29757, 13720}, -{29934, 13329}, {30107, 12937}, -{30274, 12540}, {30435, 12142}, -{30592, 11744}, {30743, 11342}, -{30889, 10939}, {31030, 10534}, -{31164, 10127}, {31294, 9718}, -{31418, 9307}, {31537, 8895}, -{31652, 8482}, {31759, 8067}, -{31862, 7650}, {31960, 7233}, -{32051, 6815}, {32138, 6393}, -{32219, 5973}, {32294, 5549}, -{32364, 5127}, {32429, 4703}, -{32487, 4278}, {32541, 3852}, -{32588, 3426}, {32630, 2999}, -{32667, 2572}, {32698, 2144}, -{32724, 1716}, {32742, 1287}, -{32757, 860}, {32766, 430}, -}; -#ifndef FFT_BITREV480 -#define FFT_BITREV480 -static const opus_int16 fft_bitrev480[480] = { -0, 120, 240, 360, 30, 150, 270, 390, 60, 180, 300, 420, 90, 210, 330, -450, 15, 135, 255, 375, 45, 165, 285, 405, 75, 195, 315, 435, 105, 225, -345, 465, 5, 125, 245, 365, 35, 155, 275, 395, 65, 185, 305, 425, 95, -215, 335, 455, 20, 140, 260, 380, 50, 170, 290, 410, 80, 200, 320, 440, -110, 230, 350, 470, 10, 130, 250, 370, 40, 160, 280, 400, 70, 190, 310, -430, 100, 220, 340, 460, 25, 145, 265, 385, 55, 175, 295, 415, 85, 205, -325, 445, 115, 235, 355, 475, 1, 121, 241, 361, 31, 151, 271, 391, 61, -181, 301, 421, 91, 211, 331, 451, 16, 136, 256, 376, 46, 166, 286, 406, -76, 196, 316, 436, 106, 226, 346, 466, 6, 126, 246, 366, 36, 156, 276, -396, 66, 186, 306, 426, 96, 216, 336, 456, 21, 141, 261, 381, 51, 171, -291, 411, 81, 201, 321, 441, 111, 231, 351, 471, 11, 131, 251, 371, 41, -161, 281, 401, 71, 191, 311, 431, 101, 221, 341, 461, 26, 146, 266, 386, -56, 176, 296, 416, 86, 206, 326, 446, 116, 236, 356, 476, 2, 122, 242, -362, 32, 152, 272, 392, 62, 182, 302, 422, 92, 212, 332, 452, 17, 137, -257, 377, 47, 167, 287, 407, 77, 197, 317, 437, 107, 227, 347, 467, 7, -127, 247, 367, 37, 157, 277, 397, 67, 187, 307, 427, 97, 217, 337, 457, -22, 142, 262, 382, 52, 172, 292, 412, 82, 202, 322, 442, 112, 232, 352, -472, 12, 132, 252, 372, 42, 162, 282, 402, 72, 192, 312, 432, 102, 222, -342, 462, 27, 147, 267, 387, 57, 177, 297, 417, 87, 207, 327, 447, 117, -237, 357, 477, 3, 123, 243, 363, 33, 153, 273, 393, 63, 183, 303, 423, -93, 213, 333, 453, 18, 138, 258, 378, 48, 168, 288, 408, 78, 198, 318, -438, 108, 228, 348, 468, 8, 128, 248, 368, 38, 158, 278, 398, 68, 188, -308, 428, 98, 218, 338, 458, 23, 143, 263, 383, 53, 173, 293, 413, 83, -203, 323, 443, 113, 233, 353, 473, 13, 133, 253, 373, 43, 163, 283, 403, -73, 193, 313, 433, 103, 223, 343, 463, 28, 148, 268, 388, 58, 178, 298, -418, 88, 208, 328, 448, 118, 238, 358, 478, 4, 124, 244, 364, 34, 154, -274, 394, 64, 184, 304, 424, 94, 214, 334, 454, 19, 139, 259, 379, 49, -169, 289, 409, 79, 199, 319, 439, 109, 229, 349, 469, 9, 129, 249, 369, -39, 159, 279, 399, 69, 189, 309, 429, 99, 219, 339, 459, 24, 144, 264, -384, 54, 174, 294, 414, 84, 204, 324, 444, 114, 234, 354, 474, 14, 134, -254, 374, 44, 164, 284, 404, 74, 194, 314, 434, 104, 224, 344, 464, 29, -149, 269, 389, 59, 179, 299, 419, 89, 209, 329, 449, 119, 239, 359, 479, -}; -#endif - -#ifndef FFT_BITREV240 -#define FFT_BITREV240 -static const opus_int16 fft_bitrev240[240] = { -0, 60, 120, 180, 15, 75, 135, 195, 30, 90, 150, 210, 45, 105, 165, -225, 5, 65, 125, 185, 20, 80, 140, 200, 35, 95, 155, 215, 50, 110, -170, 230, 10, 70, 130, 190, 25, 85, 145, 205, 40, 100, 160, 220, 55, -115, 175, 235, 1, 61, 121, 181, 16, 76, 136, 196, 31, 91, 151, 211, -46, 106, 166, 226, 6, 66, 126, 186, 21, 81, 141, 201, 36, 96, 156, -216, 51, 111, 171, 231, 11, 71, 131, 191, 26, 86, 146, 206, 41, 101, -161, 221, 56, 116, 176, 236, 2, 62, 122, 182, 17, 77, 137, 197, 32, -92, 152, 212, 47, 107, 167, 227, 7, 67, 127, 187, 22, 82, 142, 202, -37, 97, 157, 217, 52, 112, 172, 232, 12, 72, 132, 192, 27, 87, 147, -207, 42, 102, 162, 222, 57, 117, 177, 237, 3, 63, 123, 183, 18, 78, -138, 198, 33, 93, 153, 213, 48, 108, 168, 228, 8, 68, 128, 188, 23, -83, 143, 203, 38, 98, 158, 218, 53, 113, 173, 233, 13, 73, 133, 193, -28, 88, 148, 208, 43, 103, 163, 223, 58, 118, 178, 238, 4, 64, 124, -184, 19, 79, 139, 199, 34, 94, 154, 214, 49, 109, 169, 229, 9, 69, -129, 189, 24, 84, 144, 204, 39, 99, 159, 219, 54, 114, 174, 234, 14, -74, 134, 194, 29, 89, 149, 209, 44, 104, 164, 224, 59, 119, 179, 239, -}; -#endif - -#ifndef FFT_BITREV120 -#define FFT_BITREV120 -static const opus_int16 fft_bitrev120[120] = { -0, 30, 60, 90, 15, 45, 75, 105, 5, 35, 65, 95, 20, 50, 80, -110, 10, 40, 70, 100, 25, 55, 85, 115, 1, 31, 61, 91, 16, 46, -76, 106, 6, 36, 66, 96, 21, 51, 81, 111, 11, 41, 71, 101, 26, -56, 86, 116, 2, 32, 62, 92, 17, 47, 77, 107, 7, 37, 67, 97, -22, 52, 82, 112, 12, 42, 72, 102, 27, 57, 87, 117, 3, 33, 63, -93, 18, 48, 78, 108, 8, 38, 68, 98, 23, 53, 83, 113, 13, 43, -73, 103, 28, 58, 88, 118, 4, 34, 64, 94, 19, 49, 79, 109, 9, -39, 69, 99, 24, 54, 84, 114, 14, 44, 74, 104, 29, 59, 89, 119, -}; -#endif - -#ifndef FFT_BITREV60 -#define FFT_BITREV60 -static const opus_int16 fft_bitrev60[60] = { -0, 15, 30, 45, 5, 20, 35, 50, 10, 25, 40, 55, 1, 16, 31, -46, 6, 21, 36, 51, 11, 26, 41, 56, 2, 17, 32, 47, 7, 22, -37, 52, 12, 27, 42, 57, 3, 18, 33, 48, 8, 23, 38, 53, 13, -28, 43, 58, 4, 19, 34, 49, 9, 24, 39, 54, 14, 29, 44, 59, -}; -#endif - -#ifndef FFT_STATE48000_960_0 -#define FFT_STATE48000_960_0 -static const kiss_fft_state fft_state48000_960_0 = { -480, /* nfft */ --1, /* shift */ -{4, 120, 4, 30, 2, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, }, /* factors */ -fft_bitrev480, /* bitrev */ -fft_twiddles48000_960, /* bitrev */ -}; -#endif - -#ifndef FFT_STATE48000_960_1 -#define FFT_STATE48000_960_1 -static const kiss_fft_state fft_state48000_960_1 = { -240, /* nfft */ -1, /* shift */ -{4, 60, 4, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */ -fft_bitrev240, /* bitrev */ -fft_twiddles48000_960, /* bitrev */ -}; -#endif - -#ifndef FFT_STATE48000_960_2 -#define FFT_STATE48000_960_2 -static const kiss_fft_state fft_state48000_960_2 = { -120, /* nfft */ -2, /* shift */ -{4, 30, 2, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */ -fft_bitrev120, /* bitrev */ -fft_twiddles48000_960, /* bitrev */ -}; -#endif - -#ifndef FFT_STATE48000_960_3 -#define FFT_STATE48000_960_3 -static const kiss_fft_state fft_state48000_960_3 = { -60, /* nfft */ -3, /* shift */ -{4, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */ -fft_bitrev60, /* bitrev */ -fft_twiddles48000_960, /* bitrev */ -}; -#endif - -#endif - -#ifndef MDCT_TWIDDLES960 -#define MDCT_TWIDDLES960 -static const opus_val16 mdct_twiddles960[481] = { -32767, 32767, 32767, 32767, 32766, -32763, 32762, 32759, 32757, 32753, -32751, 32747, 32743, 32738, 32733, -32729, 32724, 32717, 32711, 32705, -32698, 32690, 32683, 32676, 32667, -32658, 32650, 32640, 32631, 32620, -32610, 32599, 32588, 32577, 32566, -32554, 32541, 32528, 32515, 32502, -32487, 32474, 32459, 32444, 32429, -32413, 32397, 32381, 32364, 32348, -32331, 32313, 32294, 32277, 32257, -32239, 32219, 32200, 32180, 32159, -32138, 32118, 32096, 32074, 32051, -32029, 32006, 31984, 31960, 31936, -31912, 31888, 31863, 31837, 31812, -31786, 31760, 31734, 31707, 31679, -31652, 31624, 31596, 31567, 31539, -31508, 31479, 31450, 31419, 31388, -31357, 31326, 31294, 31262, 31230, -31198, 31164, 31131, 31097, 31063, -31030, 30994, 30959, 30924, 30889, -30853, 30816, 30779, 30743, 30705, -30668, 30629, 30592, 30553, 30515, -30475, 30435, 30396, 30356, 30315, -30274, 30233, 30191, 30149, 30107, -30065, 30022, 29979, 29936, 29891, -29847, 29803, 29758, 29713, 29668, -29622, 29577, 29529, 29483, 29436, -29390, 29341, 29293, 29246, 29197, -29148, 29098, 29050, 29000, 28949, -28899, 28848, 28797, 28746, 28694, -28642, 28590, 28537, 28485, 28432, -28378, 28324, 28271, 28217, 28162, -28106, 28051, 27995, 27940, 27884, -27827, 27770, 27713, 27657, 27598, -27540, 27481, 27423, 27365, 27305, -27246, 27187, 27126, 27066, 27006, -26945, 26883, 26822, 26760, 26698, -26636, 26574, 26510, 26448, 26383, -26320, 26257, 26191, 26127, 26062, -25997, 25931, 25866, 25800, 25734, -25667, 25601, 25533, 25466, 25398, -25330, 25262, 25194, 25125, 25056, -24987, 24917, 24848, 24778, 24707, -24636, 24566, 24495, 24424, 24352, -24280, 24208, 24135, 24063, 23990, -23917, 23842, 23769, 23695, 23622, -23546, 23472, 23398, 23322, 23246, -23171, 23095, 23018, 22942, 22866, -22788, 22711, 22634, 22557, 22478, -22400, 22322, 22244, 22165, 22085, -22006, 21927, 21846, 21766, 21687, -21606, 21524, 21443, 21363, 21282, -21199, 21118, 21035, 20954, 20870, -20788, 20705, 20621, 20538, 20455, -20371, 20286, 20202, 20118, 20034, -19947, 19863, 19777, 19692, 19606, -19520, 19434, 19347, 19260, 19174, -19088, 18999, 18911, 18825, 18737, -18648, 18560, 18472, 18384, 18294, -18205, 18116, 18025, 17936, 17846, -17757, 17666, 17576, 17485, 17395, -17303, 17212, 17122, 17030, 16937, -16846, 16755, 16662, 16569, 16477, -16385, 16291, 16198, 16105, 16012, -15917, 15824, 15730, 15636, 15541, -15447, 15352, 15257, 15162, 15067, -14973, 14875, 14781, 14685, 14589, -14493, 14396, 14300, 14204, 14107, -14010, 13914, 13815, 13718, 13621, -13524, 13425, 13328, 13230, 13133, -13033, 12935, 12836, 12738, 12638, -12540, 12441, 12341, 12241, 12142, -12044, 11943, 11843, 11744, 11643, -11542, 11442, 11342, 11241, 11139, -11039, 10939, 10836, 10736, 10635, -10534, 10431, 10330, 10228, 10127, -10024, 9921, 9820, 9718, 9614, -9512, 9410, 9306, 9204, 9101, -8998, 8895, 8791, 8689, 8585, -8481, 8377, 8274, 8171, 8067, -7962, 7858, 7753, 7650, 7545, -7441, 7336, 7231, 7129, 7023, -6917, 6813, 6709, 6604, 6498, -6393, 6288, 6182, 6077, 5973, -5867, 5760, 5656, 5549, 5445, -5339, 5232, 5127, 5022, 4914, -4809, 4703, 4596, 4490, 4384, -4278, 4171, 4065, 3958, 3852, -3745, 3640, 3532, 3426, 3318, -3212, 3106, 2998, 2891, 2786, -2679, 2570, 2465, 2358, 2251, -2143, 2037, 1929, 1823, 1715, -1609, 1501, 1393, 1287, 1180, -1073, 964, 858, 751, 644, -535, 429, 322, 214, 107, -0, }; -#endif - -static const CELTMode mode48000_960_120 = { -48000, /* Fs */ -120, /* overlap */ -21, /* nbEBands */ -21, /* effEBands */ -{27853, 0, 4096, 8192, }, /* preemph */ -eband5ms, /* eBands */ -3, /* maxLM */ -8, /* nbShortMdcts */ -120, /* shortMdctSize */ -11, /* nbAllocVectors */ -band_allocation, /* allocVectors */ -logN400, /* logN */ -window120, /* window */ -{1920, 3, {&fft_state48000_960_0, &fft_state48000_960_1, &fft_state48000_960_2, &fft_state48000_960_3, }, mdct_twiddles960}, /* mdct */ -{392, cache_index50, cache_bits50, cache_caps50}, /* cache */ -}; - -/* List of all the available modes */ -#define TOTAL_MODES 1 -static const CELTMode * const static_mode_list[TOTAL_MODES] = { -&mode48000_960_120, -}; diff --git a/src/opus-1.0.2/celt/static_modes_float.h b/src/opus-1.0.2/celt/static_modes_float.h deleted file mode 100644 index 5d7e7b8e..00000000 --- a/src/opus-1.0.2/celt/static_modes_float.h +++ /dev/null @@ -1,599 +0,0 @@ -/* The contents of this file was automatically generated by dump_modes.c - with arguments: 48000 960 - It contains static definitions for some pre-defined modes. */ -#include "modes.h" -#include "rate.h" - -#ifndef DEF_WINDOW120 -#define DEF_WINDOW120 -static const opus_val16 window120[120] = { -6.7286966e-05f, 0.00060551348f, 0.0016815970f, 0.0032947962f, 0.0054439943f, -0.0081276923f, 0.011344001f, 0.015090633f, 0.019364886f, 0.024163635f, -0.029483315f, 0.035319905f, 0.041668911f, 0.048525347f, 0.055883718f, -0.063737999f, 0.072081616f, 0.080907428f, 0.090207705f, 0.099974111f, -0.11019769f, 0.12086883f, 0.13197729f, 0.14351214f, 0.15546177f, -0.16781389f, 0.18055550f, 0.19367290f, 0.20715171f, 0.22097682f, -0.23513243f, 0.24960208f, 0.26436860f, 0.27941419f, 0.29472040f, -0.31026818f, 0.32603788f, 0.34200931f, 0.35816177f, 0.37447407f, -0.39092462f, 0.40749142f, 0.42415215f, 0.44088423f, 0.45766484f, -0.47447104f, 0.49127978f, 0.50806798f, 0.52481261f, 0.54149077f, -0.55807973f, 0.57455701f, 0.59090049f, 0.60708841f, 0.62309951f, -0.63891306f, 0.65450896f, 0.66986776f, 0.68497077f, 0.69980010f, -0.71433873f, 0.72857055f, 0.74248043f, 0.75605424f, 0.76927895f, -0.78214257f, 0.79463430f, 0.80674445f, 0.81846456f, 0.82978733f, -0.84070669f, 0.85121779f, 0.86131698f, 0.87100183f, 0.88027111f, -0.88912479f, 0.89756398f, 0.90559094f, 0.91320904f, 0.92042270f, -0.92723738f, 0.93365955f, 0.93969656f, 0.94535671f, 0.95064907f, -0.95558353f, 0.96017067f, 0.96442171f, 0.96834849f, 0.97196334f, -0.97527906f, 0.97830883f, 0.98106616f, 0.98356480f, 0.98581869f, -0.98784191f, 0.98964856f, 0.99125274f, 0.99266849f, 0.99390969f, -0.99499004f, 0.99592297f, 0.99672162f, 0.99739874f, 0.99796667f, -0.99843728f, 0.99882195f, 0.99913147f, 0.99937606f, 0.99956527f, -0.99970802f, 0.99981248f, 0.99988613f, 0.99993565f, 0.99996697f, -0.99998518f, 0.99999457f, 0.99999859f, 0.99999982f, 1.0000000f, -}; -#endif - -#ifndef DEF_LOGN400 -#define DEF_LOGN400 -static const opus_int16 logN400[21] = { -0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 16, 16, 16, 21, 21, 24, 29, 34, 36, }; -#endif - -#ifndef DEF_PULSE_CACHE50 -#define DEF_PULSE_CACHE50 -static const opus_int16 cache_index50[105] = { --1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 41, 41, 41, -82, 82, 123, 164, 200, 222, 0, 0, 0, 0, 0, 0, 0, 0, 41, -41, 41, 41, 123, 123, 123, 164, 164, 240, 266, 283, 295, 41, 41, 41, -41, 41, 41, 41, 41, 123, 123, 123, 123, 240, 240, 240, 266, 266, 305, -318, 328, 336, 123, 123, 123, 123, 123, 123, 123, 123, 240, 240, 240, 240, -305, 305, 305, 318, 318, 343, 351, 358, 364, 240, 240, 240, 240, 240, 240, -240, 240, 305, 305, 305, 305, 343, 343, 343, 351, 351, 370, 376, 382, 387, -}; -static const unsigned char cache_bits50[392] = { -40, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 40, 15, 23, 28, -31, 34, 36, 38, 39, 41, 42, 43, 44, 45, 46, 47, 47, 49, 50, -51, 52, 53, 54, 55, 55, 57, 58, 59, 60, 61, 62, 63, 63, 65, -66, 67, 68, 69, 70, 71, 71, 40, 20, 33, 41, 48, 53, 57, 61, -64, 66, 69, 71, 73, 75, 76, 78, 80, 82, 85, 87, 89, 91, 92, -94, 96, 98, 101, 103, 105, 107, 108, 110, 112, 114, 117, 119, 121, 123, -124, 126, 128, 40, 23, 39, 51, 60, 67, 73, 79, 83, 87, 91, 94, -97, 100, 102, 105, 107, 111, 115, 118, 121, 124, 126, 129, 131, 135, 139, -142, 145, 148, 150, 153, 155, 159, 163, 166, 169, 172, 174, 177, 179, 35, -28, 49, 65, 78, 89, 99, 107, 114, 120, 126, 132, 136, 141, 145, 149, -153, 159, 165, 171, 176, 180, 185, 189, 192, 199, 205, 211, 216, 220, 225, -229, 232, 239, 245, 251, 21, 33, 58, 79, 97, 112, 125, 137, 148, 157, -166, 174, 182, 189, 195, 201, 207, 217, 227, 235, 243, 251, 17, 35, 63, -86, 106, 123, 139, 152, 165, 177, 187, 197, 206, 214, 222, 230, 237, 250, -25, 31, 55, 75, 91, 105, 117, 128, 138, 146, 154, 161, 168, 174, 180, -185, 190, 200, 208, 215, 222, 229, 235, 240, 245, 255, 16, 36, 65, 89, -110, 128, 144, 159, 173, 185, 196, 207, 217, 226, 234, 242, 250, 11, 41, -74, 103, 128, 151, 172, 191, 209, 225, 241, 255, 9, 43, 79, 110, 138, -163, 186, 207, 227, 246, 12, 39, 71, 99, 123, 144, 164, 182, 198, 214, -228, 241, 253, 9, 44, 81, 113, 142, 168, 192, 214, 235, 255, 7, 49, -90, 127, 160, 191, 220, 247, 6, 51, 95, 134, 170, 203, 234, 7, 47, -87, 123, 155, 184, 212, 237, 6, 52, 97, 137, 174, 208, 240, 5, 57, -106, 151, 192, 231, 5, 59, 111, 158, 202, 243, 5, 55, 103, 147, 187, -224, 5, 60, 113, 161, 206, 248, 4, 65, 122, 175, 224, 4, 67, 127, -182, 234, }; -static const unsigned char cache_caps50[168] = { -224, 224, 224, 224, 224, 224, 224, 224, 160, 160, 160, 160, 185, 185, 185, -178, 178, 168, 134, 61, 37, 224, 224, 224, 224, 224, 224, 224, 224, 240, -240, 240, 240, 207, 207, 207, 198, 198, 183, 144, 66, 40, 160, 160, 160, -160, 160, 160, 160, 160, 185, 185, 185, 185, 193, 193, 193, 183, 183, 172, -138, 64, 38, 240, 240, 240, 240, 240, 240, 240, 240, 207, 207, 207, 207, -204, 204, 204, 193, 193, 180, 143, 66, 40, 185, 185, 185, 185, 185, 185, -185, 185, 193, 193, 193, 193, 193, 193, 193, 183, 183, 172, 138, 65, 39, -207, 207, 207, 207, 207, 207, 207, 207, 204, 204, 204, 204, 201, 201, 201, -188, 188, 176, 141, 66, 40, 193, 193, 193, 193, 193, 193, 193, 193, 193, -193, 193, 193, 194, 194, 194, 184, 184, 173, 139, 65, 39, 204, 204, 204, -204, 204, 204, 204, 204, 201, 201, 201, 201, 198, 198, 198, 187, 187, 175, -140, 66, 40, }; -#endif - -#ifndef FFT_TWIDDLES48000_960 -#define FFT_TWIDDLES48000_960 -static const kiss_twiddle_cpx fft_twiddles48000_960[480] = { -{1.0000000f, -0.0000000f}, {0.99991433f, -0.013089596f}, -{0.99965732f, -0.026176948f}, {0.99922904f, -0.039259816f}, -{0.99862953f, -0.052335956f}, {0.99785892f, -0.065403129f}, -{0.99691733f, -0.078459096f}, {0.99580493f, -0.091501619f}, -{0.99452190f, -0.10452846f}, {0.99306846f, -0.11753740f}, -{0.99144486f, -0.13052619f}, {0.98965139f, -0.14349262f}, -{0.98768834f, -0.15643447f}, {0.98555606f, -0.16934950f}, -{0.98325491f, -0.18223553f}, {0.98078528f, -0.19509032f}, -{0.97814760f, -0.20791169f}, {0.97534232f, -0.22069744f}, -{0.97236992f, -0.23344536f}, {0.96923091f, -0.24615329f}, -{0.96592583f, -0.25881905f}, {0.96245524f, -0.27144045f}, -{0.95881973f, -0.28401534f}, {0.95501994f, -0.29654157f}, -{0.95105652f, -0.30901699f}, {0.94693013f, -0.32143947f}, -{0.94264149f, -0.33380686f}, {0.93819134f, -0.34611706f}, -{0.93358043f, -0.35836795f}, {0.92880955f, -0.37055744f}, -{0.92387953f, -0.38268343f}, {0.91879121f, -0.39474386f}, -{0.91354546f, -0.40673664f}, {0.90814317f, -0.41865974f}, -{0.90258528f, -0.43051110f}, {0.89687274f, -0.44228869f}, -{0.89100652f, -0.45399050f}, {0.88498764f, -0.46561452f}, -{0.87881711f, -0.47715876f}, {0.87249601f, -0.48862124f}, -{0.86602540f, -0.50000000f}, {0.85940641f, -0.51129309f}, -{0.85264016f, -0.52249856f}, {0.84572782f, -0.53361452f}, -{0.83867057f, -0.54463904f}, {0.83146961f, -0.55557023f}, -{0.82412619f, -0.56640624f}, {0.81664156f, -0.57714519f}, -{0.80901699f, -0.58778525f}, {0.80125381f, -0.59832460f}, -{0.79335334f, -0.60876143f}, {0.78531693f, -0.61909395f}, -{0.77714596f, -0.62932039f}, {0.76884183f, -0.63943900f}, -{0.76040597f, -0.64944805f}, {0.75183981f, -0.65934582f}, -{0.74314483f, -0.66913061f}, {0.73432251f, -0.67880075f}, -{0.72537437f, -0.68835458f}, {0.71630194f, -0.69779046f}, -{0.70710678f, -0.70710678f}, {0.69779046f, -0.71630194f}, -{0.68835458f, -0.72537437f}, {0.67880075f, -0.73432251f}, -{0.66913061f, -0.74314483f}, {0.65934582f, -0.75183981f}, -{0.64944805f, -0.76040597f}, {0.63943900f, -0.76884183f}, -{0.62932039f, -0.77714596f}, {0.61909395f, -0.78531693f}, -{0.60876143f, -0.79335334f}, {0.59832460f, -0.80125381f}, -{0.58778525f, -0.80901699f}, {0.57714519f, -0.81664156f}, -{0.56640624f, -0.82412619f}, {0.55557023f, -0.83146961f}, -{0.54463904f, -0.83867057f}, {0.53361452f, -0.84572782f}, -{0.52249856f, -0.85264016f}, {0.51129309f, -0.85940641f}, -{0.50000000f, -0.86602540f}, {0.48862124f, -0.87249601f}, -{0.47715876f, -0.87881711f}, {0.46561452f, -0.88498764f}, -{0.45399050f, -0.89100652f}, {0.44228869f, -0.89687274f}, -{0.43051110f, -0.90258528f}, {0.41865974f, -0.90814317f}, -{0.40673664f, -0.91354546f}, {0.39474386f, -0.91879121f}, -{0.38268343f, -0.92387953f}, {0.37055744f, -0.92880955f}, -{0.35836795f, -0.93358043f}, {0.34611706f, -0.93819134f}, -{0.33380686f, -0.94264149f}, {0.32143947f, -0.94693013f}, -{0.30901699f, -0.95105652f}, {0.29654157f, -0.95501994f}, -{0.28401534f, -0.95881973f}, {0.27144045f, -0.96245524f}, -{0.25881905f, -0.96592583f}, {0.24615329f, -0.96923091f}, -{0.23344536f, -0.97236992f}, {0.22069744f, -0.97534232f}, -{0.20791169f, -0.97814760f}, {0.19509032f, -0.98078528f}, -{0.18223553f, -0.98325491f}, {0.16934950f, -0.98555606f}, -{0.15643447f, -0.98768834f}, {0.14349262f, -0.98965139f}, -{0.13052619f, -0.99144486f}, {0.11753740f, -0.99306846f}, -{0.10452846f, -0.99452190f}, {0.091501619f, -0.99580493f}, -{0.078459096f, -0.99691733f}, {0.065403129f, -0.99785892f}, -{0.052335956f, -0.99862953f}, {0.039259816f, -0.99922904f}, -{0.026176948f, -0.99965732f}, {0.013089596f, -0.99991433f}, -{6.1230318e-17f, -1.0000000f}, {-0.013089596f, -0.99991433f}, -{-0.026176948f, -0.99965732f}, {-0.039259816f, -0.99922904f}, -{-0.052335956f, -0.99862953f}, {-0.065403129f, -0.99785892f}, -{-0.078459096f, -0.99691733f}, {-0.091501619f, -0.99580493f}, -{-0.10452846f, -0.99452190f}, {-0.11753740f, -0.99306846f}, -{-0.13052619f, -0.99144486f}, {-0.14349262f, -0.98965139f}, -{-0.15643447f, -0.98768834f}, {-0.16934950f, -0.98555606f}, -{-0.18223553f, -0.98325491f}, {-0.19509032f, -0.98078528f}, -{-0.20791169f, -0.97814760f}, {-0.22069744f, -0.97534232f}, -{-0.23344536f, -0.97236992f}, {-0.24615329f, -0.96923091f}, -{-0.25881905f, -0.96592583f}, {-0.27144045f, -0.96245524f}, -{-0.28401534f, -0.95881973f}, {-0.29654157f, -0.95501994f}, -{-0.30901699f, -0.95105652f}, {-0.32143947f, -0.94693013f}, -{-0.33380686f, -0.94264149f}, {-0.34611706f, -0.93819134f}, -{-0.35836795f, -0.93358043f}, {-0.37055744f, -0.92880955f}, -{-0.38268343f, -0.92387953f}, {-0.39474386f, -0.91879121f}, -{-0.40673664f, -0.91354546f}, {-0.41865974f, -0.90814317f}, -{-0.43051110f, -0.90258528f}, {-0.44228869f, -0.89687274f}, -{-0.45399050f, -0.89100652f}, {-0.46561452f, -0.88498764f}, -{-0.47715876f, -0.87881711f}, {-0.48862124f, -0.87249601f}, -{-0.50000000f, -0.86602540f}, {-0.51129309f, -0.85940641f}, -{-0.52249856f, -0.85264016f}, {-0.53361452f, -0.84572782f}, -{-0.54463904f, -0.83867057f}, {-0.55557023f, -0.83146961f}, -{-0.56640624f, -0.82412619f}, {-0.57714519f, -0.81664156f}, -{-0.58778525f, -0.80901699f}, {-0.59832460f, -0.80125381f}, -{-0.60876143f, -0.79335334f}, {-0.61909395f, -0.78531693f}, -{-0.62932039f, -0.77714596f}, {-0.63943900f, -0.76884183f}, -{-0.64944805f, -0.76040597f}, {-0.65934582f, -0.75183981f}, -{-0.66913061f, -0.74314483f}, {-0.67880075f, -0.73432251f}, -{-0.68835458f, -0.72537437f}, {-0.69779046f, -0.71630194f}, -{-0.70710678f, -0.70710678f}, {-0.71630194f, -0.69779046f}, -{-0.72537437f, -0.68835458f}, {-0.73432251f, -0.67880075f}, -{-0.74314483f, -0.66913061f}, {-0.75183981f, -0.65934582f}, -{-0.76040597f, -0.64944805f}, {-0.76884183f, -0.63943900f}, -{-0.77714596f, -0.62932039f}, {-0.78531693f, -0.61909395f}, -{-0.79335334f, -0.60876143f}, {-0.80125381f, -0.59832460f}, -{-0.80901699f, -0.58778525f}, {-0.81664156f, -0.57714519f}, -{-0.82412619f, -0.56640624f}, {-0.83146961f, -0.55557023f}, -{-0.83867057f, -0.54463904f}, {-0.84572782f, -0.53361452f}, -{-0.85264016f, -0.52249856f}, {-0.85940641f, -0.51129309f}, -{-0.86602540f, -0.50000000f}, {-0.87249601f, -0.48862124f}, -{-0.87881711f, -0.47715876f}, {-0.88498764f, -0.46561452f}, -{-0.89100652f, -0.45399050f}, {-0.89687274f, -0.44228869f}, -{-0.90258528f, -0.43051110f}, {-0.90814317f, -0.41865974f}, -{-0.91354546f, -0.40673664f}, {-0.91879121f, -0.39474386f}, -{-0.92387953f, -0.38268343f}, {-0.92880955f, -0.37055744f}, -{-0.93358043f, -0.35836795f}, {-0.93819134f, -0.34611706f}, -{-0.94264149f, -0.33380686f}, {-0.94693013f, -0.32143947f}, -{-0.95105652f, -0.30901699f}, {-0.95501994f, -0.29654157f}, -{-0.95881973f, -0.28401534f}, {-0.96245524f, -0.27144045f}, -{-0.96592583f, -0.25881905f}, {-0.96923091f, -0.24615329f}, -{-0.97236992f, -0.23344536f}, {-0.97534232f, -0.22069744f}, -{-0.97814760f, -0.20791169f}, {-0.98078528f, -0.19509032f}, -{-0.98325491f, -0.18223553f}, {-0.98555606f, -0.16934950f}, -{-0.98768834f, -0.15643447f}, {-0.98965139f, -0.14349262f}, -{-0.99144486f, -0.13052619f}, {-0.99306846f, -0.11753740f}, -{-0.99452190f, -0.10452846f}, {-0.99580493f, -0.091501619f}, -{-0.99691733f, -0.078459096f}, {-0.99785892f, -0.065403129f}, -{-0.99862953f, -0.052335956f}, {-0.99922904f, -0.039259816f}, -{-0.99965732f, -0.026176948f}, {-0.99991433f, -0.013089596f}, -{-1.0000000f, -1.2246064e-16f}, {-0.99991433f, 0.013089596f}, -{-0.99965732f, 0.026176948f}, {-0.99922904f, 0.039259816f}, -{-0.99862953f, 0.052335956f}, {-0.99785892f, 0.065403129f}, -{-0.99691733f, 0.078459096f}, {-0.99580493f, 0.091501619f}, -{-0.99452190f, 0.10452846f}, {-0.99306846f, 0.11753740f}, -{-0.99144486f, 0.13052619f}, {-0.98965139f, 0.14349262f}, -{-0.98768834f, 0.15643447f}, {-0.98555606f, 0.16934950f}, -{-0.98325491f, 0.18223553f}, {-0.98078528f, 0.19509032f}, -{-0.97814760f, 0.20791169f}, {-0.97534232f, 0.22069744f}, -{-0.97236992f, 0.23344536f}, {-0.96923091f, 0.24615329f}, -{-0.96592583f, 0.25881905f}, {-0.96245524f, 0.27144045f}, -{-0.95881973f, 0.28401534f}, {-0.95501994f, 0.29654157f}, -{-0.95105652f, 0.30901699f}, {-0.94693013f, 0.32143947f}, -{-0.94264149f, 0.33380686f}, {-0.93819134f, 0.34611706f}, -{-0.93358043f, 0.35836795f}, {-0.92880955f, 0.37055744f}, -{-0.92387953f, 0.38268343f}, {-0.91879121f, 0.39474386f}, -{-0.91354546f, 0.40673664f}, {-0.90814317f, 0.41865974f}, -{-0.90258528f, 0.43051110f}, {-0.89687274f, 0.44228869f}, -{-0.89100652f, 0.45399050f}, {-0.88498764f, 0.46561452f}, -{-0.87881711f, 0.47715876f}, {-0.87249601f, 0.48862124f}, -{-0.86602540f, 0.50000000f}, {-0.85940641f, 0.51129309f}, -{-0.85264016f, 0.52249856f}, {-0.84572782f, 0.53361452f}, -{-0.83867057f, 0.54463904f}, {-0.83146961f, 0.55557023f}, -{-0.82412619f, 0.56640624f}, {-0.81664156f, 0.57714519f}, -{-0.80901699f, 0.58778525f}, {-0.80125381f, 0.59832460f}, -{-0.79335334f, 0.60876143f}, {-0.78531693f, 0.61909395f}, -{-0.77714596f, 0.62932039f}, {-0.76884183f, 0.63943900f}, -{-0.76040597f, 0.64944805f}, {-0.75183981f, 0.65934582f}, -{-0.74314483f, 0.66913061f}, {-0.73432251f, 0.67880075f}, -{-0.72537437f, 0.68835458f}, {-0.71630194f, 0.69779046f}, -{-0.70710678f, 0.70710678f}, {-0.69779046f, 0.71630194f}, -{-0.68835458f, 0.72537437f}, {-0.67880075f, 0.73432251f}, -{-0.66913061f, 0.74314483f}, {-0.65934582f, 0.75183981f}, -{-0.64944805f, 0.76040597f}, {-0.63943900f, 0.76884183f}, -{-0.62932039f, 0.77714596f}, {-0.61909395f, 0.78531693f}, -{-0.60876143f, 0.79335334f}, {-0.59832460f, 0.80125381f}, -{-0.58778525f, 0.80901699f}, {-0.57714519f, 0.81664156f}, -{-0.56640624f, 0.82412619f}, {-0.55557023f, 0.83146961f}, -{-0.54463904f, 0.83867057f}, {-0.53361452f, 0.84572782f}, -{-0.52249856f, 0.85264016f}, {-0.51129309f, 0.85940641f}, -{-0.50000000f, 0.86602540f}, {-0.48862124f, 0.87249601f}, -{-0.47715876f, 0.87881711f}, {-0.46561452f, 0.88498764f}, -{-0.45399050f, 0.89100652f}, {-0.44228869f, 0.89687274f}, -{-0.43051110f, 0.90258528f}, {-0.41865974f, 0.90814317f}, -{-0.40673664f, 0.91354546f}, {-0.39474386f, 0.91879121f}, -{-0.38268343f, 0.92387953f}, {-0.37055744f, 0.92880955f}, -{-0.35836795f, 0.93358043f}, {-0.34611706f, 0.93819134f}, -{-0.33380686f, 0.94264149f}, {-0.32143947f, 0.94693013f}, -{-0.30901699f, 0.95105652f}, {-0.29654157f, 0.95501994f}, -{-0.28401534f, 0.95881973f}, {-0.27144045f, 0.96245524f}, -{-0.25881905f, 0.96592583f}, {-0.24615329f, 0.96923091f}, -{-0.23344536f, 0.97236992f}, {-0.22069744f, 0.97534232f}, -{-0.20791169f, 0.97814760f}, {-0.19509032f, 0.98078528f}, -{-0.18223553f, 0.98325491f}, {-0.16934950f, 0.98555606f}, -{-0.15643447f, 0.98768834f}, {-0.14349262f, 0.98965139f}, -{-0.13052619f, 0.99144486f}, {-0.11753740f, 0.99306846f}, -{-0.10452846f, 0.99452190f}, {-0.091501619f, 0.99580493f}, -{-0.078459096f, 0.99691733f}, {-0.065403129f, 0.99785892f}, -{-0.052335956f, 0.99862953f}, {-0.039259816f, 0.99922904f}, -{-0.026176948f, 0.99965732f}, {-0.013089596f, 0.99991433f}, -{-1.8369095e-16f, 1.0000000f}, {0.013089596f, 0.99991433f}, -{0.026176948f, 0.99965732f}, {0.039259816f, 0.99922904f}, -{0.052335956f, 0.99862953f}, {0.065403129f, 0.99785892f}, -{0.078459096f, 0.99691733f}, {0.091501619f, 0.99580493f}, -{0.10452846f, 0.99452190f}, {0.11753740f, 0.99306846f}, -{0.13052619f, 0.99144486f}, {0.14349262f, 0.98965139f}, -{0.15643447f, 0.98768834f}, {0.16934950f, 0.98555606f}, -{0.18223553f, 0.98325491f}, {0.19509032f, 0.98078528f}, -{0.20791169f, 0.97814760f}, {0.22069744f, 0.97534232f}, -{0.23344536f, 0.97236992f}, {0.24615329f, 0.96923091f}, -{0.25881905f, 0.96592583f}, {0.27144045f, 0.96245524f}, -{0.28401534f, 0.95881973f}, {0.29654157f, 0.95501994f}, -{0.30901699f, 0.95105652f}, {0.32143947f, 0.94693013f}, -{0.33380686f, 0.94264149f}, {0.34611706f, 0.93819134f}, -{0.35836795f, 0.93358043f}, {0.37055744f, 0.92880955f}, -{0.38268343f, 0.92387953f}, {0.39474386f, 0.91879121f}, -{0.40673664f, 0.91354546f}, {0.41865974f, 0.90814317f}, -{0.43051110f, 0.90258528f}, {0.44228869f, 0.89687274f}, -{0.45399050f, 0.89100652f}, {0.46561452f, 0.88498764f}, -{0.47715876f, 0.87881711f}, {0.48862124f, 0.87249601f}, -{0.50000000f, 0.86602540f}, {0.51129309f, 0.85940641f}, -{0.52249856f, 0.85264016f}, {0.53361452f, 0.84572782f}, -{0.54463904f, 0.83867057f}, {0.55557023f, 0.83146961f}, -{0.56640624f, 0.82412619f}, {0.57714519f, 0.81664156f}, -{0.58778525f, 0.80901699f}, {0.59832460f, 0.80125381f}, -{0.60876143f, 0.79335334f}, {0.61909395f, 0.78531693f}, -{0.62932039f, 0.77714596f}, {0.63943900f, 0.76884183f}, -{0.64944805f, 0.76040597f}, {0.65934582f, 0.75183981f}, -{0.66913061f, 0.74314483f}, {0.67880075f, 0.73432251f}, -{0.68835458f, 0.72537437f}, {0.69779046f, 0.71630194f}, -{0.70710678f, 0.70710678f}, {0.71630194f, 0.69779046f}, -{0.72537437f, 0.68835458f}, {0.73432251f, 0.67880075f}, -{0.74314483f, 0.66913061f}, {0.75183981f, 0.65934582f}, -{0.76040597f, 0.64944805f}, {0.76884183f, 0.63943900f}, -{0.77714596f, 0.62932039f}, {0.78531693f, 0.61909395f}, -{0.79335334f, 0.60876143f}, {0.80125381f, 0.59832460f}, -{0.80901699f, 0.58778525f}, {0.81664156f, 0.57714519f}, -{0.82412619f, 0.56640624f}, {0.83146961f, 0.55557023f}, -{0.83867057f, 0.54463904f}, {0.84572782f, 0.53361452f}, -{0.85264016f, 0.52249856f}, {0.85940641f, 0.51129309f}, -{0.86602540f, 0.50000000f}, {0.87249601f, 0.48862124f}, -{0.87881711f, 0.47715876f}, {0.88498764f, 0.46561452f}, -{0.89100652f, 0.45399050f}, {0.89687274f, 0.44228869f}, -{0.90258528f, 0.43051110f}, {0.90814317f, 0.41865974f}, -{0.91354546f, 0.40673664f}, {0.91879121f, 0.39474386f}, -{0.92387953f, 0.38268343f}, {0.92880955f, 0.37055744f}, -{0.93358043f, 0.35836795f}, {0.93819134f, 0.34611706f}, -{0.94264149f, 0.33380686f}, {0.94693013f, 0.32143947f}, -{0.95105652f, 0.30901699f}, {0.95501994f, 0.29654157f}, -{0.95881973f, 0.28401534f}, {0.96245524f, 0.27144045f}, -{0.96592583f, 0.25881905f}, {0.96923091f, 0.24615329f}, -{0.97236992f, 0.23344536f}, {0.97534232f, 0.22069744f}, -{0.97814760f, 0.20791169f}, {0.98078528f, 0.19509032f}, -{0.98325491f, 0.18223553f}, {0.98555606f, 0.16934950f}, -{0.98768834f, 0.15643447f}, {0.98965139f, 0.14349262f}, -{0.99144486f, 0.13052619f}, {0.99306846f, 0.11753740f}, -{0.99452190f, 0.10452846f}, {0.99580493f, 0.091501619f}, -{0.99691733f, 0.078459096f}, {0.99785892f, 0.065403129f}, -{0.99862953f, 0.052335956f}, {0.99922904f, 0.039259816f}, -{0.99965732f, 0.026176948f}, {0.99991433f, 0.013089596f}, -}; -#ifndef FFT_BITREV480 -#define FFT_BITREV480 -static const opus_int16 fft_bitrev480[480] = { -0, 120, 240, 360, 30, 150, 270, 390, 60, 180, 300, 420, 90, 210, 330, -450, 15, 135, 255, 375, 45, 165, 285, 405, 75, 195, 315, 435, 105, 225, -345, 465, 5, 125, 245, 365, 35, 155, 275, 395, 65, 185, 305, 425, 95, -215, 335, 455, 20, 140, 260, 380, 50, 170, 290, 410, 80, 200, 320, 440, -110, 230, 350, 470, 10, 130, 250, 370, 40, 160, 280, 400, 70, 190, 310, -430, 100, 220, 340, 460, 25, 145, 265, 385, 55, 175, 295, 415, 85, 205, -325, 445, 115, 235, 355, 475, 1, 121, 241, 361, 31, 151, 271, 391, 61, -181, 301, 421, 91, 211, 331, 451, 16, 136, 256, 376, 46, 166, 286, 406, -76, 196, 316, 436, 106, 226, 346, 466, 6, 126, 246, 366, 36, 156, 276, -396, 66, 186, 306, 426, 96, 216, 336, 456, 21, 141, 261, 381, 51, 171, -291, 411, 81, 201, 321, 441, 111, 231, 351, 471, 11, 131, 251, 371, 41, -161, 281, 401, 71, 191, 311, 431, 101, 221, 341, 461, 26, 146, 266, 386, -56, 176, 296, 416, 86, 206, 326, 446, 116, 236, 356, 476, 2, 122, 242, -362, 32, 152, 272, 392, 62, 182, 302, 422, 92, 212, 332, 452, 17, 137, -257, 377, 47, 167, 287, 407, 77, 197, 317, 437, 107, 227, 347, 467, 7, -127, 247, 367, 37, 157, 277, 397, 67, 187, 307, 427, 97, 217, 337, 457, -22, 142, 262, 382, 52, 172, 292, 412, 82, 202, 322, 442, 112, 232, 352, -472, 12, 132, 252, 372, 42, 162, 282, 402, 72, 192, 312, 432, 102, 222, -342, 462, 27, 147, 267, 387, 57, 177, 297, 417, 87, 207, 327, 447, 117, -237, 357, 477, 3, 123, 243, 363, 33, 153, 273, 393, 63, 183, 303, 423, -93, 213, 333, 453, 18, 138, 258, 378, 48, 168, 288, 408, 78, 198, 318, -438, 108, 228, 348, 468, 8, 128, 248, 368, 38, 158, 278, 398, 68, 188, -308, 428, 98, 218, 338, 458, 23, 143, 263, 383, 53, 173, 293, 413, 83, -203, 323, 443, 113, 233, 353, 473, 13, 133, 253, 373, 43, 163, 283, 403, -73, 193, 313, 433, 103, 223, 343, 463, 28, 148, 268, 388, 58, 178, 298, -418, 88, 208, 328, 448, 118, 238, 358, 478, 4, 124, 244, 364, 34, 154, -274, 394, 64, 184, 304, 424, 94, 214, 334, 454, 19, 139, 259, 379, 49, -169, 289, 409, 79, 199, 319, 439, 109, 229, 349, 469, 9, 129, 249, 369, -39, 159, 279, 399, 69, 189, 309, 429, 99, 219, 339, 459, 24, 144, 264, -384, 54, 174, 294, 414, 84, 204, 324, 444, 114, 234, 354, 474, 14, 134, -254, 374, 44, 164, 284, 404, 74, 194, 314, 434, 104, 224, 344, 464, 29, -149, 269, 389, 59, 179, 299, 419, 89, 209, 329, 449, 119, 239, 359, 479, -}; -#endif - -#ifndef FFT_BITREV240 -#define FFT_BITREV240 -static const opus_int16 fft_bitrev240[240] = { -0, 60, 120, 180, 15, 75, 135, 195, 30, 90, 150, 210, 45, 105, 165, -225, 5, 65, 125, 185, 20, 80, 140, 200, 35, 95, 155, 215, 50, 110, -170, 230, 10, 70, 130, 190, 25, 85, 145, 205, 40, 100, 160, 220, 55, -115, 175, 235, 1, 61, 121, 181, 16, 76, 136, 196, 31, 91, 151, 211, -46, 106, 166, 226, 6, 66, 126, 186, 21, 81, 141, 201, 36, 96, 156, -216, 51, 111, 171, 231, 11, 71, 131, 191, 26, 86, 146, 206, 41, 101, -161, 221, 56, 116, 176, 236, 2, 62, 122, 182, 17, 77, 137, 197, 32, -92, 152, 212, 47, 107, 167, 227, 7, 67, 127, 187, 22, 82, 142, 202, -37, 97, 157, 217, 52, 112, 172, 232, 12, 72, 132, 192, 27, 87, 147, -207, 42, 102, 162, 222, 57, 117, 177, 237, 3, 63, 123, 183, 18, 78, -138, 198, 33, 93, 153, 213, 48, 108, 168, 228, 8, 68, 128, 188, 23, -83, 143, 203, 38, 98, 158, 218, 53, 113, 173, 233, 13, 73, 133, 193, -28, 88, 148, 208, 43, 103, 163, 223, 58, 118, 178, 238, 4, 64, 124, -184, 19, 79, 139, 199, 34, 94, 154, 214, 49, 109, 169, 229, 9, 69, -129, 189, 24, 84, 144, 204, 39, 99, 159, 219, 54, 114, 174, 234, 14, -74, 134, 194, 29, 89, 149, 209, 44, 104, 164, 224, 59, 119, 179, 239, -}; -#endif - -#ifndef FFT_BITREV120 -#define FFT_BITREV120 -static const opus_int16 fft_bitrev120[120] = { -0, 30, 60, 90, 15, 45, 75, 105, 5, 35, 65, 95, 20, 50, 80, -110, 10, 40, 70, 100, 25, 55, 85, 115, 1, 31, 61, 91, 16, 46, -76, 106, 6, 36, 66, 96, 21, 51, 81, 111, 11, 41, 71, 101, 26, -56, 86, 116, 2, 32, 62, 92, 17, 47, 77, 107, 7, 37, 67, 97, -22, 52, 82, 112, 12, 42, 72, 102, 27, 57, 87, 117, 3, 33, 63, -93, 18, 48, 78, 108, 8, 38, 68, 98, 23, 53, 83, 113, 13, 43, -73, 103, 28, 58, 88, 118, 4, 34, 64, 94, 19, 49, 79, 109, 9, -39, 69, 99, 24, 54, 84, 114, 14, 44, 74, 104, 29, 59, 89, 119, -}; -#endif - -#ifndef FFT_BITREV60 -#define FFT_BITREV60 -static const opus_int16 fft_bitrev60[60] = { -0, 15, 30, 45, 5, 20, 35, 50, 10, 25, 40, 55, 1, 16, 31, -46, 6, 21, 36, 51, 11, 26, 41, 56, 2, 17, 32, 47, 7, 22, -37, 52, 12, 27, 42, 57, 3, 18, 33, 48, 8, 23, 38, 53, 13, -28, 43, 58, 4, 19, 34, 49, 9, 24, 39, 54, 14, 29, 44, 59, -}; -#endif - -#ifndef FFT_STATE48000_960_0 -#define FFT_STATE48000_960_0 -static const kiss_fft_state fft_state48000_960_0 = { -480, /* nfft */ -0.002083333f, /* scale */ --1, /* shift */ -{4, 120, 4, 30, 2, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, }, /* factors */ -fft_bitrev480, /* bitrev */ -fft_twiddles48000_960, /* bitrev */ -}; -#endif - -#ifndef FFT_STATE48000_960_1 -#define FFT_STATE48000_960_1 -static const kiss_fft_state fft_state48000_960_1 = { -240, /* nfft */ -0.004166667f, /* scale */ -1, /* shift */ -{4, 60, 4, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */ -fft_bitrev240, /* bitrev */ -fft_twiddles48000_960, /* bitrev */ -}; -#endif - -#ifndef FFT_STATE48000_960_2 -#define FFT_STATE48000_960_2 -static const kiss_fft_state fft_state48000_960_2 = { -120, /* nfft */ -0.008333333f, /* scale */ -2, /* shift */ -{4, 30, 2, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */ -fft_bitrev120, /* bitrev */ -fft_twiddles48000_960, /* bitrev */ -}; -#endif - -#ifndef FFT_STATE48000_960_3 -#define FFT_STATE48000_960_3 -static const kiss_fft_state fft_state48000_960_3 = { -60, /* nfft */ -0.016666667f, /* scale */ -3, /* shift */ -{4, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */ -fft_bitrev60, /* bitrev */ -fft_twiddles48000_960, /* bitrev */ -}; -#endif - -#endif - -#ifndef MDCT_TWIDDLES960 -#define MDCT_TWIDDLES960 -static const opus_val16 mdct_twiddles960[481] = { -1.0000000f, 0.99999465f, 0.99997858f, 0.99995181f, 0.99991433f, -0.99986614f, 0.99980724f, 0.99973764f, 0.99965732f, 0.99956631f, -0.99946459f, 0.99935216f, 0.99922904f, 0.99909521f, 0.99895068f, -0.99879546f, 0.99862953f, 0.99845292f, 0.99826561f, 0.99806761f, -0.99785892f, 0.99763955f, 0.99740949f, 0.99716875f, 0.99691733f, -0.99665524f, 0.99638247f, 0.99609903f, 0.99580493f, 0.99550016f, -0.99518473f, 0.99485864f, 0.99452190f, 0.99417450f, 0.99381646f, -0.99344778f, 0.99306846f, 0.99267850f, 0.99227791f, 0.99186670f, -0.99144486f, 0.99101241f, 0.99056934f, 0.99011566f, 0.98965139f, -0.98917651f, 0.98869104f, 0.98819498f, 0.98768834f, 0.98717112f, -0.98664333f, 0.98610497f, 0.98555606f, 0.98499659f, 0.98442657f, -0.98384600f, 0.98325491f, 0.98265328f, 0.98204113f, 0.98141846f, -0.98078528f, 0.98014159f, 0.97948742f, 0.97882275f, 0.97814760f, -0.97746197f, 0.97676588f, 0.97605933f, 0.97534232f, 0.97461487f, -0.97387698f, 0.97312866f, 0.97236992f, 0.97160077f, 0.97082121f, -0.97003125f, 0.96923091f, 0.96842019f, 0.96759909f, 0.96676764f, -0.96592582f, 0.96507367f, 0.96421118f, 0.96333837f, 0.96245523f, -0.96156180f, 0.96065806f, 0.95974403f, 0.95881973f, 0.95788517f, -0.95694034f, 0.95598526f, 0.95501995f, 0.95404440f, 0.95305864f, -0.95206267f, 0.95105651f, 0.95004016f, 0.94901364f, 0.94797697f, -0.94693013f, 0.94587315f, 0.94480604f, 0.94372882f, 0.94264149f, -0.94154406f, 0.94043656f, 0.93931897f, 0.93819133f, 0.93705365f, -0.93590592f, 0.93474818f, 0.93358042f, 0.93240268f, 0.93121493f, -0.93001722f, 0.92880955f, 0.92759193f, 0.92636438f, 0.92512690f, -0.92387953f, 0.92262225f, 0.92135509f, 0.92007809f, 0.91879121f, -0.91749449f, 0.91618795f, 0.91487161f, 0.91354545f, 0.91220952f, -0.91086382f, 0.90950836f, 0.90814316f, 0.90676824f, 0.90538363f, -0.90398929f, 0.90258528f, 0.90117161f, 0.89974828f, 0.89831532f, -0.89687273f, 0.89542055f, 0.89395877f, 0.89248742f, 0.89100652f, -0.88951606f, 0.88801610f, 0.88650661f, 0.88498764f, 0.88345918f, -0.88192125f, 0.88037390f, 0.87881711f, 0.87725090f, 0.87567531f, -0.87409035f, 0.87249599f, 0.87089232f, 0.86927933f, 0.86765699f, -0.86602540f, 0.86438453f, 0.86273437f, 0.86107503f, 0.85940641f, -0.85772862f, 0.85604161f, 0.85434547f, 0.85264014f, 0.85092572f, -0.84920218f, 0.84746955f, 0.84572781f, 0.84397704f, 0.84221721f, -0.84044838f, 0.83867056f, 0.83688375f, 0.83508799f, 0.83328325f, -0.83146961f, 0.82964704f, 0.82781562f, 0.82597530f, 0.82412620f, -0.82226820f, 0.82040144f, 0.81852589f, 0.81664154f, 0.81474847f, -0.81284665f, 0.81093620f, 0.80901698f, 0.80708914f, 0.80515262f, -0.80320752f, 0.80125378f, 0.79929149f, 0.79732067f, 0.79534125f, -0.79335335f, 0.79135691f, 0.78935204f, 0.78733867f, 0.78531691f, -0.78328674f, 0.78124818f, 0.77920122f, 0.77714595f, 0.77508232f, -0.77301043f, 0.77093026f, 0.76884183f, 0.76674517f, 0.76464026f, -0.76252720f, 0.76040593f, 0.75827656f, 0.75613907f, 0.75399349f, -0.75183978f, 0.74967807f, 0.74750833f, 0.74533054f, 0.74314481f, -0.74095112f, 0.73874950f, 0.73653993f, 0.73432251f, 0.73209718f, -0.72986405f, 0.72762307f, 0.72537438f, 0.72311787f, 0.72085359f, -0.71858162f, 0.71630192f, 0.71401459f, 0.71171956f, 0.70941701f, -0.70710677f, 0.70478900f, 0.70246363f, 0.70013079f, 0.69779041f, -0.69544260f, 0.69308738f, 0.69072466f, 0.68835458f, 0.68597709f, -0.68359229f, 0.68120013f, 0.67880072f, 0.67639404f, 0.67398011f, -0.67155892f, 0.66913059f, 0.66669509f, 0.66425240f, 0.66180265f, -0.65934581f, 0.65688191f, 0.65441092f, 0.65193298f, 0.64944801f, -0.64695613f, 0.64445727f, 0.64195160f, 0.63943902f, 0.63691954f, -0.63439328f, 0.63186019f, 0.62932037f, 0.62677377f, 0.62422055f, -0.62166055f, 0.61909394f, 0.61652065f, 0.61394081f, 0.61135435f, -0.60876139f, 0.60616195f, 0.60355593f, 0.60094349f, 0.59832457f, -0.59569929f, 0.59306758f, 0.59042957f, 0.58778523f, 0.58513460f, -0.58247766f, 0.57981452f, 0.57714518f, 0.57446961f, 0.57178793f, -0.56910013f, 0.56640624f, 0.56370623f, 0.56100023f, 0.55828818f, -0.55557020f, 0.55284627f, 0.55011641f, 0.54738067f, 0.54463901f, -0.54189157f, 0.53913828f, 0.53637921f, 0.53361450f, 0.53084398f, -0.52806787f, 0.52528601f, 0.52249852f, 0.51970543f, 0.51690688f, -0.51410279f, 0.51129310f, 0.50847793f, 0.50565732f, 0.50283139f, -0.49999997f, 0.49716321f, 0.49432122f, 0.49147383f, 0.48862118f, -0.48576340f, 0.48290042f, 0.48003216f, 0.47715876f, 0.47428025f, -0.47139677f, 0.46850813f, 0.46561448f, 0.46271584f, 0.45981235f, -0.45690383f, 0.45399042f, 0.45107214f, 0.44814915f, 0.44522124f, -0.44228868f, 0.43935137f, 0.43640926f, 0.43346247f, 0.43051104f, -0.42755511f, 0.42459449f, 0.42162932f, 0.41865964f, 0.41568558f, -0.41270697f, 0.40972393f, 0.40673661f, 0.40374494f, 0.40074884f, -0.39774844f, 0.39474390f, 0.39173501f, 0.38872193f, 0.38570469f, -0.38268343f, 0.37965796f, 0.37662842f, 0.37359496f, 0.37055739f, -0.36751585f, 0.36447038f, 0.36142122f, 0.35836797f, 0.35531089f, -0.35225000f, 0.34918544f, 0.34611704f, 0.34304493f, 0.33996926f, -0.33688983f, 0.33380680f, 0.33072019f, 0.32763015f, 0.32453650f, -0.32143936f, 0.31833890f, 0.31523503f, 0.31212767f, 0.30901696f, -0.30590306f, 0.30278577f, 0.29966524f, 0.29654150f, 0.29341470f, -0.29028464f, 0.28715147f, 0.28401522f, 0.28087605f, 0.27773376f, -0.27458861f, 0.27144052f, 0.26828940f, 0.26513541f, 0.26197859f, -0.25881907f, 0.25565666f, 0.25249152f, 0.24932367f, 0.24615327f, -0.24298012f, 0.23980436f, 0.23662604f, 0.23344530f, 0.23026206f, -0.22707623f, 0.22388809f, 0.22069744f, 0.21750443f, 0.21430908f, -0.21111156f, 0.20791165f, 0.20470953f, 0.20150520f, 0.19829884f, -0.19509024f, 0.19187955f, 0.18866692f, 0.18545227f, 0.18223552f, -0.17901681f, 0.17579631f, 0.17257380f, 0.16934945f, 0.16612328f, -0.16289546f, 0.15966577f, 0.15643437f, 0.15320141f, 0.14996669f, -0.14673037f, 0.14349260f, 0.14025329f, 0.13701235f, 0.13376995f, -0.13052612f, 0.12728101f, 0.12403442f, 0.12078650f, 0.11753740f, -0.11428693f, 0.11103523f, 0.10778234f, 0.10452842f, 0.10127326f, -0.098017137f, 0.094759842f, 0.091501652f, 0.088242363f, 0.084982129f, -0.081721103f, 0.078459084f, 0.075196224f, 0.071932560f, 0.068668243f, -0.065403073f, 0.062137201f, 0.058870665f, 0.055603617f, 0.052335974f, -0.049067651f, 0.045798921f, 0.042529582f, 0.039259788f, 0.035989573f, -0.032719092f, 0.029448142f, 0.026176876f, 0.022905329f, 0.019633657f, -0.016361655f, 0.013089478f, 0.0098171604f, 0.0065449764f, 0.0032724839f, --4.3711390e-08f, }; -#endif - -static const CELTMode mode48000_960_120 = { -48000, /* Fs */ -120, /* overlap */ -21, /* nbEBands */ -21, /* effEBands */ -{0.85000610f, 0.0000000f, 1.0000000f, 1.0000000f, }, /* preemph */ -eband5ms, /* eBands */ -3, /* maxLM */ -8, /* nbShortMdcts */ -120, /* shortMdctSize */ -11, /* nbAllocVectors */ -band_allocation, /* allocVectors */ -logN400, /* logN */ -window120, /* window */ -{1920, 3, {&fft_state48000_960_0, &fft_state48000_960_1, &fft_state48000_960_2, &fft_state48000_960_3, }, mdct_twiddles960}, /* mdct */ -{392, cache_index50, cache_bits50, cache_caps50}, /* cache */ -}; - -/* List of all the available modes */ -#define TOTAL_MODES 1 -static const CELTMode * const static_mode_list[TOTAL_MODES] = { -&mode48000_960_120, -}; diff --git a/src/opus-1.0.2/celt/vq.c b/src/opus-1.0.2/celt/vq.c deleted file mode 100644 index 98a0f36c..00000000 --- a/src/opus-1.0.2/celt/vq.c +++ /dev/null @@ -1,415 +0,0 @@ -/* Copyright (c) 2007-2008 CSIRO - Copyright (c) 2007-2009 Xiph.Org Foundation - Written by Jean-Marc Valin */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "mathops.h" -#include "cwrs.h" -#include "vq.h" -#include "arch.h" -#include "os_support.h" -#include "bands.h" -#include "rate.h" - -static void exp_rotation1(celt_norm *X, int len, int stride, opus_val16 c, opus_val16 s) -{ - int i; - celt_norm *Xptr; - Xptr = X; - for (i=0;i=0;i--) - { - celt_norm x1, x2; - x1 = Xptr[0]; - x2 = Xptr[stride]; - Xptr[stride] = EXTRACT16(SHR32(MULT16_16(c,x2) + MULT16_16(s,x1), 15)); - *Xptr-- = EXTRACT16(SHR32(MULT16_16(c,x1) - MULT16_16(s,x2), 15)); - } -} - -static void exp_rotation(celt_norm *X, int len, int dir, int stride, int K, int spread) -{ - static const int SPREAD_FACTOR[3]={15,10,5}; - int i; - opus_val16 c, s; - opus_val16 gain, theta; - int stride2=0; - int factor; - - if (2*K>=len || spread==SPREAD_NONE) - return; - factor = SPREAD_FACTOR[spread-1]; - - gain = celt_div((opus_val32)MULT16_16(Q15_ONE,len),(opus_val32)(len+factor*K)); - theta = HALF16(MULT16_16_Q15(gain,gain)); - - c = celt_cos_norm(EXTEND32(theta)); - s = celt_cos_norm(EXTEND32(SUB16(Q15ONE,theta))); /* sin(theta) */ - - if (len>=8*stride) - { - stride2 = 1; - /* This is just a simple (equivalent) way of computing sqrt(len/stride) with rounding. - It's basically incrementing long as (stride2+0.5)^2 < len/stride. */ - while ((stride2*stride2+stride2)*stride + (stride>>2) < len) - stride2++; - } - /*NOTE: As a minor optimization, we could be passing around log2(B), not B, for both this and for - extract_collapse_mask().*/ - len /= stride; - for (i=0;i>1; -#endif - t = VSHR32(Ryy, 2*(k-7)); - g = MULT16_16_P15(celt_rsqrt_norm(t),gain); - - i=0; - do - X[i] = EXTRACT16(PSHR32(MULT16_16(g, iy[i]), k+1)); - while (++i < N); -} - -static unsigned extract_collapse_mask(int *iy, int N, int B) -{ - unsigned collapse_mask; - int N0; - int i; - if (B<=1) - return 1; - /*NOTE: As a minor optimization, we could be passing around log2(B), not B, for both this and for - exp_rotation().*/ - N0 = N/B; - collapse_mask = 0; - i=0; do { - int j; - j=0; do { - collapse_mask |= (iy[i*N0+j]!=0)<0, "alg_quant() needs at least one pulse"); - celt_assert2(N>1, "alg_quant() needs at least two dimensions"); - - ALLOC(y, N, celt_norm); - ALLOC(iy, N, int); - ALLOC(signx, N, opus_val16); - - exp_rotation(X, N, 1, B, K, spread); - - /* Get rid of the sign */ - sum = 0; - j=0; do { - if (X[j]>0) - signx[j]=1; - else { - signx[j]=-1; - X[j]=-X[j]; - } - iy[j] = 0; - y[j] = 0; - } while (++j (N>>1)) - { - opus_val16 rcp; - j=0; do { - sum += X[j]; - } while (++j EPSILON && sum < 64)) -#endif - { - X[0] = QCONST16(1.f,14); - j=1; do - X[j]=0; - while (++j=1, "Allocated too many pulses in the quick pass"); - - /* This should never happen, but just in case it does (e.g. on silence) - we fill the first bin with pulses. */ -#ifdef FIXED_POINT_DEBUG - celt_assert2(pulsesLeft<=N+3, "Not enough pulses in the quick pass"); -#endif - if (pulsesLeft > N+3) - { - opus_val16 tmp = (opus_val16)pulsesLeft; - yy = MAC16_16(yy, tmp, tmp); - yy = MAC16_16(yy, tmp, y[0]); - iy[0] += pulsesLeft; - pulsesLeft=0; - } - - s = 1; - for (i=0;i= best_num/best_den, but that way - we can do it without any division */ - /* OPT: Make sure to use conditional moves here */ - if (MULT16_16(best_den, Rxy) > MULT16_16(Ryy, best_num)) - { - best_den = Ryy; - best_num = Rxy; - best_id = j; - } - } while (++j0, "alg_unquant() needs at least one pulse"); - celt_assert2(N>1, "alg_unquant() needs at least two dimensions"); - ALLOC(iy, N, int); - decode_pulses(iy, N, K, dec); - Ryy = 0; - i=0; - do { - Ryy = MAC16_16(Ryy, iy[i], iy[i]); - } while (++i < N); - normalise_residual(iy, X, N, Ryy, gain); - exp_rotation(X, N, -1, B, K, spread); - collapse_mask = extract_collapse_mask(iy, N, B); - RESTORE_STACK; - return collapse_mask; -} - -void renormalise_vector(celt_norm *X, int N, opus_val16 gain) -{ - int i; -#ifdef FIXED_POINT - int k; -#endif - opus_val32 E = EPSILON; - opus_val16 g; - opus_val32 t; - celt_norm *xptr = X; - for (i=0;i>1; -#endif - t = VSHR32(E, 2*(k-7)); - g = MULT16_16_P15(celt_rsqrt_norm(t),gain); - - xptr = X; - for (i=0;i - *
  • audio_frame is the audio data in opus_int16 (or float for opus_encode_float())
  • - *
  • frame_size is the duration of the frame in samples (per channel)
  • - *
  • packet is the byte array to which the compressed data is written
  • - *
  • max_packet is the maximum number of bytes that can be written in the packet (4000 bytes is recommended). - * Do not use max_packet to control VBR target bitrate, instead use the #OPUS_SET_BITRATE CTL.
  • - * - * - * opus_encode() and opus_encode_float() return the number of bytes actually written to the packet. - * The return value can be negative, which indicates that an error has occurred. If the return value - * is 1 byte, then the packet does not need to be transmitted (DTX). - * - * Once the encoder state if no longer needed, it can be destroyed with - * - * @code - * opus_encoder_destroy(enc); - * @endcode - * - * If the encoder was created with opus_encoder_init() rather than opus_encoder_create(), - * then no action is required aside from potentially freeing the memory that was manually - * allocated for it (calling free(enc) for the example above) - * - */ - -/** Opus encoder state. - * This contains the complete state of an Opus encoder. - * It is position independent and can be freely copied. - * @see opus_encoder_create,opus_encoder_init - */ -typedef struct OpusEncoder OpusEncoder; - -/** Gets the size of an OpusEncoder structure. - * @param[in] channels int: Number of channels. - * This must be 1 or 2. - * @returns The size in bytes. - */ -OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_encoder_get_size(int channels); - -/** - */ - -/** Allocates and initializes an encoder state. - * There are three coding modes: - * - * @ref OPUS_APPLICATION_VOIP gives best quality at a given bitrate for voice - * signals. It enhances the input signal by high-pass filtering and - * emphasizing formants and harmonics. Optionally it includes in-band - * forward error correction to protect against packet loss. Use this - * mode for typical VoIP applications. Because of the enhancement, - * even at high bitrates the output may sound different from the input. - * - * @ref OPUS_APPLICATION_AUDIO gives best quality at a given bitrate for most - * non-voice signals like music. Use this mode for music and mixed - * (music/voice) content, broadcast, and applications requiring less - * than 15 ms of coding delay. - * - * @ref OPUS_APPLICATION_RESTRICTED_LOWDELAY configures low-delay mode that - * disables the speech-optimized mode in exchange for slightly reduced delay. - * This mode can only be set on an newly initialized or freshly reset encoder - * because it changes the codec delay. - * - * This is useful when the caller knows that the speech-optimized modes will not be needed (use with caution). - * @param [in] Fs opus_int32: Sampling rate of input signal (Hz) - * This must be one of 8000, 12000, 16000, - * 24000, or 48000. - * @param [in] channels int: Number of channels (1 or 2) in input signal - * @param [in] application int: Coding mode (@ref OPUS_APPLICATION_VOIP/@ref OPUS_APPLICATION_AUDIO/@ref OPUS_APPLICATION_RESTRICTED_LOWDELAY) - * @param [out] error int*: @ref opus_errorcodes - * @note Regardless of the sampling rate and number channels selected, the Opus encoder - * can switch to a lower audio bandwidth or number of channels if the bitrate - * selected is too low. This also means that it is safe to always use 48 kHz stereo input - * and let the encoder optimize the encoding. - */ -OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusEncoder *opus_encoder_create( - opus_int32 Fs, - int channels, - int application, - int *error -); - -/** Initializes a previously allocated encoder state - * The memory pointed to by st must be at least the size returned by opus_encoder_get_size(). - * This is intended for applications which use their own allocator instead of malloc. - * @see opus_encoder_create(),opus_encoder_get_size() - * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. - * @param [in] st OpusEncoder*: Encoder state - * @param [in] Fs opus_int32: Sampling rate of input signal (Hz) - * This must be one of 8000, 12000, 16000, - * 24000, or 48000. - * @param [in] channels int: Number of channels (1 or 2) in input signal - * @param [in] application int: Coding mode (OPUS_APPLICATION_VOIP/OPUS_APPLICATION_AUDIO/OPUS_APPLICATION_RESTRICTED_LOWDELAY) - * @retval #OPUS_OK Success or @ref opus_errorcodes - */ -OPUS_EXPORT int opus_encoder_init( - OpusEncoder *st, - opus_int32 Fs, - int channels, - int application -) OPUS_ARG_NONNULL(1); - -/** Encodes an Opus frame. - * @param [in] st OpusEncoder*: Encoder state - * @param [in] pcm opus_int16*: Input signal (interleaved if 2 channels). length is frame_size*channels*sizeof(opus_int16) - * @param [in] frame_size int: Number of samples per channel in the - * input signal. - * This must be an Opus frame size for - * the encoder's sampling rate. - * For example, at 48 kHz the permitted - * values are 120, 240, 480, 960, 1920, - * and 2880. - * Passing in a duration of less than - * 10 ms (480 samples at 48 kHz) will - * prevent the encoder from using the LPC - * or hybrid modes. - * @param [out] data unsigned char*: Output payload. - * This must contain storage for at - * least \a max_data_bytes. - * @param [in] max_data_bytes opus_int32: Size of the allocated - * memory for the output - * payload. This may be - * used to impose an upper limit on - * the instant bitrate, but should - * not be used as the only bitrate - * control. Use #OPUS_SET_BITRATE to - * control the bitrate. - * @returns The length of the encoded packet (in bytes) on success or a - * negative error code (see @ref opus_errorcodes) on failure. - */ -OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode( - OpusEncoder *st, - const opus_int16 *pcm, - int frame_size, - unsigned char *data, - opus_int32 max_data_bytes -) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); - -/** Encodes an Opus frame from floating point input. - * @param [in] st OpusEncoder*: Encoder state - * @param [in] pcm float*: Input in float format (interleaved if 2 channels), with a normal range of +/-1.0. - * Samples with a range beyond +/-1.0 are supported but will - * be clipped by decoders using the integer API and should - * only be used if it is known that the far end supports - * extended dynamic range. - * length is frame_size*channels*sizeof(float) - * @param [in] frame_size int: Number of samples per channel in the - * input signal. - * This must be an Opus frame size for - * the encoder's sampling rate. - * For example, at 48 kHz the permitted - * values are 120, 240, 480, 960, 1920, - * and 2880. - * Passing in a duration of less than - * 10 ms (480 samples at 48 kHz) will - * prevent the encoder from using the LPC - * or hybrid modes. - * @param [out] data unsigned char*: Output payload. - * This must contain storage for at - * least \a max_data_bytes. - * @param [in] max_data_bytes opus_int32: Size of the allocated - * memory for the output - * payload. This may be - * used to impose an upper limit on - * the instant bitrate, but should - * not be used as the only bitrate - * control. Use #OPUS_SET_BITRATE to - * control the bitrate. - * @returns The length of the encoded packet (in bytes) on success or a - * negative error code (see @ref opus_errorcodes) on failure. - */ -OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode_float( - OpusEncoder *st, - const float *pcm, - int frame_size, - unsigned char *data, - opus_int32 max_data_bytes -) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); - -/** Frees an OpusEncoder allocated by opus_encoder_create(). - * @param[in] st OpusEncoder*: State to be freed. - */ -OPUS_EXPORT void opus_encoder_destroy(OpusEncoder *st); - -/** Perform a CTL function on an Opus encoder. - * - * Generally the request and subsequent arguments are generated - * by a convenience macro. - * @param st OpusEncoder*: Encoder state. - * @param request This and all remaining parameters should be replaced by one - * of the convenience macros in @ref opus_genericctls or - * @ref opus_encoderctls. - * @see opus_genericctls - * @see opus_encoderctls - */ -OPUS_EXPORT int opus_encoder_ctl(OpusEncoder *st, int request, ...) OPUS_ARG_NONNULL(1); -/**@}*/ - -/** @defgroup opus_decoder Opus Decoder - * @{ - * - * @brief This page describes the process and functions used to decode Opus. - * - * The decoding process also starts with creating a decoder - * state. This can be done with: - * @code - * int error; - * OpusDecoder *dec; - * dec = opus_decoder_create(Fs, channels, &error); - * @endcode - * where - * @li Fs is the sampling rate and must be 8000, 12000, 16000, 24000, or 48000 - * @li channels is the number of channels (1 or 2) - * @li error will hold the error code in case of failure (or #OPUS_OK on success) - * @li the return value is a newly created decoder state to be used for decoding - * - * While opus_decoder_create() allocates memory for the state, it's also possible - * to initialize pre-allocated memory: - * @code - * int size; - * int error; - * OpusDecoder *dec; - * size = opus_decoder_get_size(channels); - * dec = malloc(size); - * error = opus_decoder_init(dec, Fs, channels); - * @endcode - * where opus_decoder_get_size() returns the required size for the decoder state. Note that - * future versions of this code may change the size, so no assuptions should be made about it. - * - * The decoder state is always continuous in memory and only a shallow copy is sufficient - * to copy it (e.g. memcpy()) - * - * To decode a frame, opus_decode() or opus_decode_float() must be called with a packet of compressed audio data: - * @code - * frame_size = opus_decode(dec, packet, len, decoded, max_size, 0); - * @endcode - * where - * - * @li packet is the byte array containing the compressed data - * @li len is the exact number of bytes contained in the packet - * @li decoded is the decoded audio data in opus_int16 (or float for opus_decode_float()) - * @li max_size is the max duration of the frame in samples (per channel) that can fit into the decoded_frame array - * - * opus_decode() and opus_decode_float() return the number of samples (per channel) decoded from the packet. - * If that value is negative, then an error has occurred. This can occur if the packet is corrupted or if the audio - * buffer is too small to hold the decoded audio. - * - * Opus is a stateful codec with overlapping blocks and as a result Opus - * packets are not coded independently of each other. Packets must be - * passed into the decoder serially and in the correct order for a correct - * decode. Lost packets can be replaced with loss concealment by calling - * the decoder with a null pointer and zero length for the missing packet. - * - * A single codec state may only be accessed from a single thread at - * a time and any required locking must be performed by the caller. Separate - * streams must be decoded with separate decoder states and can be decoded - * in parallel unless the library was compiled with NONTHREADSAFE_PSEUDOSTACK - * defined. - * - */ - -/** Opus decoder state. - * This contains the complete state of an Opus decoder. - * It is position independent and can be freely copied. - * @see opus_decoder_create,opus_decoder_init - */ -typedef struct OpusDecoder OpusDecoder; - -/** Gets the size of an OpusDecoder structure. - * @param [in] channels int: Number of channels. - * This must be 1 or 2. - * @returns The size in bytes. - */ -OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decoder_get_size(int channels); - -/** Allocates and initializes a decoder state. - * @param [in] Fs opus_int32: Sample rate to decode at (Hz). - * This must be one of 8000, 12000, 16000, - * 24000, or 48000. - * @param [in] channels int: Number of channels (1 or 2) to decode - * @param [out] error int*: #OPUS_OK Success or @ref opus_errorcodes - * - * Internally Opus stores data at 48000 Hz, so that should be the default - * value for Fs. However, the decoder can efficiently decode to buffers - * at 8, 12, 16, and 24 kHz so if for some reason the caller cannot use - * data at the full sample rate, or knows the compressed data doesn't - * use the full frequency range, it can request decoding at a reduced - * rate. Likewise, the decoder is capable of filling in either mono or - * interleaved stereo pcm buffers, at the caller's request. - */ -OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusDecoder *opus_decoder_create( - opus_int32 Fs, - int channels, - int *error -); - -/** Initializes a previously allocated decoder state. - * The state must be at least the size returned by opus_decoder_get_size(). - * This is intended for applications which use their own allocator instead of malloc. @see opus_decoder_create,opus_decoder_get_size - * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. - * @param [in] st OpusDecoder*: Decoder state. - * @param [in] Fs opus_int32: Sampling rate to decode to (Hz). - * This must be one of 8000, 12000, 16000, - * 24000, or 48000. - * @param [in] channels int: Number of channels (1 or 2) to decode - * @retval #OPUS_OK Success or @ref opus_errorcodes - */ -OPUS_EXPORT int opus_decoder_init( - OpusDecoder *st, - opus_int32 Fs, - int channels -) OPUS_ARG_NONNULL(1); - -/** Decode an Opus packet. - * @param [in] st OpusDecoder*: Decoder state - * @param [in] data char*: Input payload. Use a NULL pointer to indicate packet loss - * @param [in] len opus_int32: Number of bytes in payload* - * @param [out] pcm opus_int16*: Output signal (interleaved if 2 channels). length - * is frame_size*channels*sizeof(opus_int16) - * @param [in] frame_size Number of samples per channel of available space in \a pcm. - * If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will - * not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=1), - * then frame_size needs to be exactly the duration of audio that is missing, otherwise the - * decoder will not be in the optimal state to decode the next incoming packet. For the PLC and - * FEC cases, frame_size must be a multiple of 2.5 ms. - * @param [in] decode_fec int: Flag (0 or 1) to request that any in-band forward error correction data be - * decoded. If no such data is available, the frame is decoded as if it were lost. - * @returns Number of decoded samples or @ref opus_errorcodes - */ -OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decode( - OpusDecoder *st, - const unsigned char *data, - opus_int32 len, - opus_int16 *pcm, - int frame_size, - int decode_fec -) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); - -/** Decode an Opus packet with floating point output. - * @param [in] st OpusDecoder*: Decoder state - * @param [in] data char*: Input payload. Use a NULL pointer to indicate packet loss - * @param [in] len opus_int32: Number of bytes in payload - * @param [out] pcm float*: Output signal (interleaved if 2 channels). length - * is frame_size*channels*sizeof(float) - * @param [in] frame_size Number of samples per channel of available space in \a pcm. - * If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will - * not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=1), - * then frame_size needs to be exactly the duration of audio that is missing, otherwise the - * decoder will not be in the optimal state to decode the next incoming packet. For the PLC and - * FEC cases, frame_size must be a multiple of 2.5 ms. - * @param [in] decode_fec int: Flag (0 or 1) to request that any in-band forward error correction data be - * decoded. If no such data is available the frame is decoded as if it were lost. - * @returns Number of decoded samples or @ref opus_errorcodes - */ -OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decode_float( - OpusDecoder *st, - const unsigned char *data, - opus_int32 len, - float *pcm, - int frame_size, - int decode_fec -) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); - -/** Perform a CTL function on an Opus decoder. - * - * Generally the request and subsequent arguments are generated - * by a convenience macro. - * @param st OpusDecoder*: Decoder state. - * @param request This and all remaining parameters should be replaced by one - * of the convenience macros in @ref opus_genericctls or - * @ref opus_decoderctls. - * @see opus_genericctls - * @see opus_decoderctls - */ -OPUS_EXPORT int opus_decoder_ctl(OpusDecoder *st, int request, ...) OPUS_ARG_NONNULL(1); - -/** Frees an OpusDecoder allocated by opus_decoder_create(). - * @param[in] st OpusDecoder*: State to be freed. - */ -OPUS_EXPORT void opus_decoder_destroy(OpusDecoder *st); - -/** Parse an opus packet into one or more frames. - * Opus_decode will perform this operation internally so most applications do - * not need to use this function. - * This function does not copy the frames, the returned pointers are pointers into - * the input packet. - * @param [in] data char*: Opus packet to be parsed - * @param [in] len opus_int32: size of data - * @param [out] out_toc char*: TOC pointer - * @param [out] frames char*[48] encapsulated frames - * @param [out] size short[48] sizes of the encapsulated frames - * @param [out] payload_offset int*: returns the position of the payload within the packet (in bytes) - * @returns number of frames - */ -OPUS_EXPORT int opus_packet_parse( - const unsigned char *data, - opus_int32 len, - unsigned char *out_toc, - const unsigned char *frames[48], - short size[48], - int *payload_offset -) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); - -/** Gets the bandwidth of an Opus packet. - * @param [in] data char*: Opus packet - * @retval OPUS_BANDWIDTH_NARROWBAND Narrowband (4kHz bandpass) - * @retval OPUS_BANDWIDTH_MEDIUMBAND Mediumband (6kHz bandpass) - * @retval OPUS_BANDWIDTH_WIDEBAND Wideband (8kHz bandpass) - * @retval OPUS_BANDWIDTH_SUPERWIDEBAND Superwideband (12kHz bandpass) - * @retval OPUS_BANDWIDTH_FULLBAND Fullband (20kHz bandpass) - * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type - */ -OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_bandwidth(const unsigned char *data) OPUS_ARG_NONNULL(1); - -/** Gets the number of samples per frame from an Opus packet. - * @param [in] data char*: Opus packet. - * This must contain at least one byte of - * data. - * @param [in] Fs opus_int32: Sampling rate in Hz. - * This must be a multiple of 400, or - * inaccurate results will be returned. - * @returns Number of samples per frame. - */ -OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_samples_per_frame(const unsigned char *data, opus_int32 Fs) OPUS_ARG_NONNULL(1); - -/** Gets the number of channels from an Opus packet. - * @param [in] data char*: Opus packet - * @returns Number of channels - * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type - */ -OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_channels(const unsigned char *data) OPUS_ARG_NONNULL(1); - -/** Gets the number of frames in an Opus packet. - * @param [in] packet char*: Opus packet - * @param [in] len opus_int32: Length of packet - * @returns Number of frames - * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type - */ -OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_frames(const unsigned char packet[], opus_int32 len) OPUS_ARG_NONNULL(1); - -/** Gets the number of samples of an Opus packet. - * @param [in] packet char*: Opus packet - * @param [in] len opus_int32: Length of packet - * @param [in] Fs opus_int32: Sampling rate in Hz. - * This must be a multiple of 400, or - * inaccurate results will be returned. - * @returns Number of samples - * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type - */ -OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_samples(const unsigned char packet[], opus_int32 len, opus_int32 Fs) OPUS_ARG_NONNULL(1); - -/** Gets the number of samples of an Opus packet. - * @param [in] dec OpusDecoder*: Decoder state - * @param [in] packet char*: Opus packet - * @param [in] len opus_int32: Length of packet - * @returns Number of samples - * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type - */ -OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decoder_get_nb_samples(const OpusDecoder *dec, const unsigned char packet[], opus_int32 len) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2); -/**@}*/ - -/** @defgroup opus_repacketizer Repacketizer - * @{ - * - * The repacketizer can be used to merge multiple Opus packets into a single - * packet or alternatively to split Opus packets that have previously been - * merged. Splitting valid Opus packets is always guaranteed to succeed, - * whereas merging valid packets only succeeds if all frames have the same - * mode, bandwidth, and frame size, and when the total duration of the merged - * packet is no more than 120 ms. - * The repacketizer currently only operates on elementary Opus - * streams. It will not manipualte multistream packets successfully, except in - * the degenerate case where they consist of data from a single stream. - * - * The repacketizing process starts with creating a repacketizer state, either - * by calling opus_repacketizer_create() or by allocating the memory yourself, - * e.g., - * @code - * OpusRepacketizer *rp; - * rp = (OpusRepacketizer*)malloc(opus_repacketizer_get_size()); - * if (rp != NULL) - * opus_repacketizer_init(rp); - * @endcode - * - * Then the application should submit packets with opus_repacketizer_cat(), - * extract new packets with opus_repacketizer_out() or - * opus_repacketizer_out_range(), and then reset the state for the next set of - * input packets via opus_repacketizer_init(). - * - * For example, to split a sequence of packets into individual frames: - * @code - * unsigned char *data; - * int len; - * while (get_next_packet(&data, &len)) - * { - * unsigned char out[1276]; - * opus_int32 out_len; - * int nb_frames; - * int err; - * int i; - * err = opus_repacketizer_cat(rp, data, len); - * if (err != OPUS_OK) - * { - * release_packet(data); - * return err; - * } - * nb_frames = opus_repacketizer_get_nb_frames(rp); - * for (i = 0; i < nb_frames; i++) - * { - * out_len = opus_repacketizer_out_range(rp, i, i+1, out, sizeof(out)); - * if (out_len < 0) - * { - * release_packet(data); - * return (int)out_len; - * } - * output_next_packet(out, out_len); - * } - * opus_repacketizer_init(rp); - * release_packet(data); - * } - * @endcode - * - * Alternatively, to combine a sequence of frames into packets that each - * contain up to TARGET_DURATION_MS milliseconds of data: - * @code - * // The maximum number of packets with duration TARGET_DURATION_MS occurs - * // when the frame size is 2.5 ms, for a total of (TARGET_DURATION_MS*2/5) - * // packets. - * unsigned char *data[(TARGET_DURATION_MS*2/5)+1]; - * opus_int32 len[(TARGET_DURATION_MS*2/5)+1]; - * int nb_packets; - * unsigned char out[1277*(TARGET_DURATION_MS*2/2)]; - * opus_int32 out_len; - * int prev_toc; - * nb_packets = 0; - * while (get_next_packet(data+nb_packets, len+nb_packets)) - * { - * int nb_frames; - * int err; - * nb_frames = opus_packet_get_nb_frames(data[nb_packets], len[nb_packets]); - * if (nb_frames < 1) - * { - * release_packets(data, nb_packets+1); - * return nb_frames; - * } - * nb_frames += opus_repacketizer_get_nb_frames(rp); - * // If adding the next packet would exceed our target, or it has an - * // incompatible TOC sequence, output the packets we already have before - * // submitting it. - * // N.B., The nb_packets > 0 check ensures we've submitted at least one - * // packet since the last call to opus_repacketizer_init(). Otherwise a - * // single packet longer than TARGET_DURATION_MS would cause us to try to - * // output an (invalid) empty packet. It also ensures that prev_toc has - * // been set to a valid value. Additionally, len[nb_packets] > 0 is - * // guaranteed by the call to opus_packet_get_nb_frames() above, so the - * // reference to data[nb_packets][0] should be valid. - * if (nb_packets > 0 && ( - * ((prev_toc & 0xFC) != (data[nb_packets][0] & 0xFC)) || - * opus_packet_get_samples_per_frame(data[nb_packets], 48000)*nb_frames > - * TARGET_DURATION_MS*48)) - * { - * out_len = opus_repacketizer_out(rp, out, sizeof(out)); - * if (out_len < 0) - * { - * release_packets(data, nb_packets+1); - * return (int)out_len; - * } - * output_next_packet(out, out_len); - * opus_repacketizer_init(rp); - * release_packets(data, nb_packets); - * data[0] = data[nb_packets]; - * len[0] = len[nb_packets]; - * nb_packets = 0; - * } - * err = opus_repacketizer_cat(rp, data[nb_packets], len[nb_packets]); - * if (err != OPUS_OK) - * { - * release_packets(data, nb_packets+1); - * return err; - * } - * prev_toc = data[nb_packets][0]; - * nb_packets++; - * } - * // Output the final, partial packet. - * if (nb_packets > 0) - * { - * out_len = opus_repacketizer_out(rp, out, sizeof(out)); - * release_packets(data, nb_packets); - * if (out_len < 0) - * return (int)out_len; - * output_next_packet(out, out_len); - * } - * @endcode - * - * An alternate way of merging packets is to simply call opus_repacketizer_cat() - * unconditionally until it fails. At that point, the merged packet can be - * obtained with opus_repacketizer_out() and the input packet for which - * opus_repacketizer_cat() needs to be re-added to a newly reinitialized - * repacketizer state. - */ - -typedef struct OpusRepacketizer OpusRepacketizer; - -/** Gets the size of an OpusRepacketizer structure. - * @returns The size in bytes. - */ -OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_repacketizer_get_size(void); - -/** (Re)initializes a previously allocated repacketizer state. - * The state must be at least the size returned by opus_repacketizer_get_size(). - * This can be used for applications which use their own allocator instead of - * malloc(). - * It must also be called to reset the queue of packets waiting to be - * repacketized, which is necessary if the maximum packet duration of 120 ms - * is reached or if you wish to submit packets with a different Opus - * configuration (coding mode, audio bandwidth, frame size, or channel count). - * Failure to do so will prevent a new packet from being added with - * opus_repacketizer_cat(). - * @see opus_repacketizer_create - * @see opus_repacketizer_get_size - * @see opus_repacketizer_cat - * @param rp OpusRepacketizer*: The repacketizer state to - * (re)initialize. - * @returns A pointer to the same repacketizer state that was passed in. - */ -OPUS_EXPORT OpusRepacketizer *opus_repacketizer_init(OpusRepacketizer *rp) OPUS_ARG_NONNULL(1); - -/** Allocates memory and initializes the new repacketizer with - * opus_repacketizer_init(). - */ -OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusRepacketizer *opus_repacketizer_create(void); - -/** Frees an OpusRepacketizer allocated by - * opus_repacketizer_create(). - * @param[in] rp OpusRepacketizer*: State to be freed. - */ -OPUS_EXPORT void opus_repacketizer_destroy(OpusRepacketizer *rp); - -/** Add a packet to the current repacketizer state. - * This packet must match the configuration of any packets already submitted - * for repacketization since the last call to opus_repacketizer_init(). - * This means that it must have the same coding mode, audio bandwidth, frame - * size, and channel count. - * This can be checked in advance by examining the top 6 bits of the first - * byte of the packet, and ensuring they match the top 6 bits of the first - * byte of any previously submitted packet. - * The total duration of audio in the repacketizer state also must not exceed - * 120 ms, the maximum duration of a single packet, after adding this packet. - * - * The contents of the current repacketizer state can be extracted into new - * packets using opus_repacketizer_out() or opus_repacketizer_out_range(). - * - * In order to add a packet with a different configuration or to add more - * audio beyond 120 ms, you must clear the repacketizer state by calling - * opus_repacketizer_init(). - * If a packet is too large to add to the current repacketizer state, no part - * of it is added, even if it contains multiple frames, some of which might - * fit. - * If you wish to be able to add parts of such packets, you should first use - * another repacketizer to split the packet into pieces and add them - * individually. - * @see opus_repacketizer_out_range - * @see opus_repacketizer_out - * @see opus_repacketizer_init - * @param rp OpusRepacketizer*: The repacketizer state to which to - * add the packet. - * @param[in] data const unsigned char*: The packet data. - * The application must ensure - * this pointer remains valid - * until the next call to - * opus_repacketizer_init() or - * opus_repacketizer_destroy(). - * @param len opus_int32: The number of bytes in the packet data. - * @returns An error code indicating whether or not the operation succeeded. - * @retval #OPUS_OK The packet's contents have been added to the repacketizer - * state. - * @retval #OPUS_INVALID_PACKET The packet did not have a valid TOC sequence, - * the packet's TOC sequence was not compatible - * with previously submitted packets (because - * the coding mode, audio bandwidth, frame size, - * or channel count did not match), or adding - * this packet would increase the total amount of - * audio stored in the repacketizer state to more - * than 120 ms. - */ -OPUS_EXPORT int opus_repacketizer_cat(OpusRepacketizer *rp, const unsigned char *data, opus_int32 len) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2); - - -/** Construct a new packet from data previously submitted to the repacketizer - * state via opus_repacketizer_cat(). - * @param rp OpusRepacketizer*: The repacketizer state from which to - * construct the new packet. - * @param begin int: The index of the first frame in the current - * repacketizer state to include in the output. - * @param end int: One past the index of the last frame in the - * current repacketizer state to include in the - * output. - * @param[out] data const unsigned char*: The buffer in which to - * store the output packet. - * @param maxlen opus_int32: The maximum number of bytes to store in - * the output buffer. In order to guarantee - * success, this should be at least - * 1276 for a single frame, - * or for multiple frames, - * 1277*(end-begin). - * However, 1*(end-begin) plus - * the size of all packet data submitted to - * the repacketizer since the last call to - * opus_repacketizer_init() or - * opus_repacketizer_create() is also - * sufficient, and possibly much smaller. - * @returns The total size of the output packet on success, or an error code - * on failure. - * @retval #OPUS_BAD_ARG [begin,end) was an invalid range of - * frames (begin < 0, begin >= end, or end > - * opus_repacketizer_get_nb_frames()). - * @retval #OPUS_BUFFER_TOO_SMALL \a maxlen was insufficient to contain the - * complete output packet. - */ -OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_repacketizer_out_range(OpusRepacketizer *rp, int begin, int end, unsigned char *data, opus_int32 maxlen) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); - -/** Return the total number of frames contained in packet data submitted to - * the repacketizer state so far via opus_repacketizer_cat() since the last - * call to opus_repacketizer_init() or opus_repacketizer_create(). - * This defines the valid range of packets that can be extracted with - * opus_repacketizer_out_range() or opus_repacketizer_out(). - * @param rp OpusRepacketizer*: The repacketizer state containing the - * frames. - * @returns The total number of frames contained in the packet data submitted - * to the repacketizer state. - */ -OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_repacketizer_get_nb_frames(OpusRepacketizer *rp) OPUS_ARG_NONNULL(1); - -/** Construct a new packet from data previously submitted to the repacketizer - * state via opus_repacketizer_cat(). - * This is a convenience routine that returns all the data submitted so far - * in a single packet. - * It is equivalent to calling - * @code - * opus_repacketizer_out_range(rp, 0, opus_repacketizer_get_nb_frames(rp), - * data, maxlen) - * @endcode - * @param rp OpusRepacketizer*: The repacketizer state from which to - * construct the new packet. - * @param[out] data const unsigned char*: The buffer in which to - * store the output packet. - * @param maxlen opus_int32: The maximum number of bytes to store in - * the output buffer. In order to guarantee - * success, this should be at least - * 1277*opus_repacketizer_get_nb_frames(rp). - * However, - * 1*opus_repacketizer_get_nb_frames(rp) - * plus the size of all packet data - * submitted to the repacketizer since the - * last call to opus_repacketizer_init() or - * opus_repacketizer_create() is also - * sufficient, and possibly much smaller. - * @returns The total size of the output packet on success, or an error code - * on failure. - * @retval #OPUS_BUFFER_TOO_SMALL \a maxlen was insufficient to contain the - * complete output packet. - */ -OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_repacketizer_out(OpusRepacketizer *rp, unsigned char *data, opus_int32 maxlen) OPUS_ARG_NONNULL(1); - -/**@}*/ - -#ifdef __cplusplus -} -#endif - -#endif /* OPUS_H */ diff --git a/src/opus-1.0.2/include/opus_custom.h b/src/opus-1.0.2/include/opus_custom.h deleted file mode 100644 index e7861d6f..00000000 --- a/src/opus-1.0.2/include/opus_custom.h +++ /dev/null @@ -1,329 +0,0 @@ -/* Copyright (c) 2007-2008 CSIRO - Copyright (c) 2007-2009 Xiph.Org Foundation - Copyright (c) 2008-2012 Gregory Maxwell - Written by Jean-Marc Valin and Gregory Maxwell */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/** - @file opus_custom.h - @brief Opus-Custom reference implementation API - */ - -#ifndef OPUS_CUSTOM_H -#define OPUS_CUSTOM_H - -#include "opus_defines.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef CUSTOM_MODES -#define OPUS_CUSTOM_EXPORT OPUS_EXPORT -#define OPUS_CUSTOM_EXPORT_STATIC OPUS_EXPORT -#else -#define OPUS_CUSTOM_EXPORT -#ifdef CELT_C -#define OPUS_CUSTOM_EXPORT_STATIC static inline -#else -#define OPUS_CUSTOM_EXPORT_STATIC -#endif -#endif - -/** @defgroup opus_custom Opus Custom - * @{ - * Opus Custom is an optional part of the Opus specification and - * reference implementation which uses a distinct API from the regular - * API and supports frame sizes that are not normally supported.\ Use - * of Opus Custom is discouraged for all but very special applications - * for which a frame size different from 2.5, 5, 10, or 20 ms is needed - * (for either complexity or latency reasons) and where interoperability - * is less important. - * - * In addition to the interoperability limitations the use of Opus custom - * disables a substantial chunk of the codec and generally lowers the - * quality available at a given bitrate. Normally when an application needs - * a different frame size from the codec it should buffer to match the - * sizes but this adds a small amount of delay which may be important - * in some very low latency applications. Some transports (especially - * constant rate RF transports) may also work best with frames of - * particular durations. - * - * Libopus only supports custom modes if they are enabled at compile time. - * - * The Opus Custom API is similar to the regular API but the - * @ref opus_encoder_create and @ref opus_decoder_create calls take - * an additional mode parameter which is a structure produced by - * a call to @ref opus_custom_mode_create. Both the encoder and decoder - * must create a mode using the same sample rate (fs) and frame size - * (frame size) so these parameters must either be signaled out of band - * or fixed in a particular implementation. - * - * Similar to regular Opus the custom modes support on the fly frame size - * switching, but the sizes available depend on the particular frame size in - * use. For some initial frame sizes on a single on the fly size is available. - */ - -/** Contains the state of an encoder. One encoder state is needed - for each stream. It is initialized once at the beginning of the - stream. Do *not* re-initialize the state for every frame. - @brief Encoder state - */ -typedef struct OpusCustomEncoder OpusCustomEncoder; - -/** State of the decoder. One decoder state is needed for each stream. - It is initialized once at the beginning of the stream. Do *not* - re-initialize the state for every frame. - @brief Decoder state - */ -typedef struct OpusCustomDecoder OpusCustomDecoder; - -/** The mode contains all the information necessary to create an - encoder. Both the encoder and decoder need to be initialized - with exactly the same mode, otherwise the output will be - corrupted. - @brief Mode configuration - */ -typedef struct OpusCustomMode OpusCustomMode; - -/** Creates a new mode struct. This will be passed to an encoder or - * decoder. The mode MUST NOT BE DESTROYED until the encoders and - * decoders that use it are destroyed as well. - * @param [in] Fs int: Sampling rate (8000 to 96000 Hz) - * @param [in] frame_size int: Number of samples (per channel) to encode in each - * packet (64 - 1024, prime factorization must contain zero or more 2s, 3s, or 5s and no other primes) - * @param [out] error int*: Returned error code (if NULL, no error will be returned) - * @return A newly created mode - */ -OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomMode *opus_custom_mode_create(opus_int32 Fs, int frame_size, int *error); - -/** Destroys a mode struct. Only call this after all encoders and - * decoders using this mode are destroyed as well. - * @param [in] mode OpusCustomMode*: Mode to be freed. - */ -OPUS_CUSTOM_EXPORT void opus_custom_mode_destroy(OpusCustomMode *mode); - -/* Encoder */ -/** Gets the size of an OpusCustomEncoder structure. - * @param [in] mode OpusCustomMode *: Mode configuration - * @param [in] channels int: Number of channels - * @returns size - */ -OPUS_CUSTOM_EXPORT_STATIC OPUS_WARN_UNUSED_RESULT int opus_custom_encoder_get_size( - const OpusCustomMode *mode, - int channels -) OPUS_ARG_NONNULL(1); - -/** Creates a new encoder state. Each stream needs its own encoder - * state (can't be shared across simultaneous streams). - * @param [in] mode OpusCustomMode*: Contains all the information about the characteristics of - * the stream (must be the same characteristics as used for the - * decoder) - * @param [in] channels int: Number of channels - * @param [out] error int*: Returns an error code - * @return Newly created encoder state. -*/ -OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomEncoder *opus_custom_encoder_create( - const OpusCustomMode *mode, - int channels, - int *error -) OPUS_ARG_NONNULL(1); - -/** Initializes a previously allocated encoder state - * The memory pointed to by st must be the size returned by opus_custom_encoder_get_size. - * This is intended for applications which use their own allocator instead of malloc. - * @see opus_custom_encoder_create(),opus_custom_encoder_get_size() - * To reset a previously initialized state use the OPUS_RESET_STATE CTL. - * @param [in] st OpusCustomEncoder*: Encoder state - * @param [in] mode OpusCustomMode *: Contains all the information about the characteristics of - * the stream (must be the same characteristics as used for the - * decoder) - * @param [in] channels int: Number of channels - * @return OPUS_OK Success or @ref opus_errorcodes - */ -OPUS_CUSTOM_EXPORT_STATIC int opus_custom_encoder_init( - OpusCustomEncoder *st, - const OpusCustomMode *mode, - int channels -) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2); - -/** Destroys a an encoder state. - * @param[in] st OpusCustomEncoder*: State to be freed. - */ -OPUS_CUSTOM_EXPORT void opus_custom_encoder_destroy(OpusCustomEncoder *st); - -/** Encodes a frame of audio. - * @param [in] st OpusCustomEncoder*: Encoder state - * @param [in] pcm float*: PCM audio in float format, with a normal range of +/-1.0. - * Samples with a range beyond +/-1.0 are supported but will - * be clipped by decoders using the integer API and should - * only be used if it is known that the far end supports - * extended dynamic range. There must be exactly - * frame_size samples per channel. - * @param [in] frame_size int: Number of samples per frame of input signal - * @param [out] compressed char *: The compressed data is written here. This may not alias pcm and must be at least maxCompressedBytes long. - * @param [in] maxCompressedBytes int: Maximum number of bytes to use for compressing the frame - * (can change from one frame to another) - * @return Number of bytes written to "compressed". - * If negative, an error has occurred (see error codes). It is IMPORTANT that - * the length returned be somehow transmitted to the decoder. Otherwise, no - * decoding is possible. - */ -OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_encode_float( - OpusCustomEncoder *st, - const float *pcm, - int frame_size, - unsigned char *compressed, - int maxCompressedBytes -) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); - -/** Encodes a frame of audio. - * @param [in] st OpusCustomEncoder*: Encoder state - * @param [in] pcm opus_int16*: PCM audio in signed 16-bit format (native endian). - * There must be exactly frame_size samples per channel. - * @param [in] frame_size int: Number of samples per frame of input signal - * @param [out] compressed char *: The compressed data is written here. This may not alias pcm and must be at least maxCompressedBytes long. - * @param [in] maxCompressedBytes int: Maximum number of bytes to use for compressing the frame - * (can change from one frame to another) - * @return Number of bytes written to "compressed". - * If negative, an error has occurred (see error codes). It is IMPORTANT that - * the length returned be somehow transmitted to the decoder. Otherwise, no - * decoding is possible. - */ -OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_encode( - OpusCustomEncoder *st, - const opus_int16 *pcm, - int frame_size, - unsigned char *compressed, - int maxCompressedBytes -) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); - -/** Perform a CTL function on an Opus custom encoder. - * - * Generally the request and subsequent arguments are generated - * by a convenience macro. - * @see opus_encoderctls - */ -OPUS_CUSTOM_EXPORT int opus_custom_encoder_ctl(OpusCustomEncoder * OPUS_RESTRICT st, int request, ...) OPUS_ARG_NONNULL(1); - -/* Decoder */ - -/** Gets the size of an OpusCustomDecoder structure. - * @param [in] mode OpusCustomMode *: Mode configuration - * @param [in] channels int: Number of channels - * @returns size - */ -OPUS_CUSTOM_EXPORT_STATIC OPUS_WARN_UNUSED_RESULT int opus_custom_decoder_get_size( - const OpusCustomMode *mode, - int channels -) OPUS_ARG_NONNULL(1); - -/** Creates a new decoder state. Each stream needs its own decoder state (can't - * be shared across simultaneous streams). - * @param [in] mode OpusCustomMode: Contains all the information about the characteristics of the - * stream (must be the same characteristics as used for the encoder) - * @param [in] channels int: Number of channels - * @param [out] error int*: Returns an error code - * @return Newly created decoder state. - */ -OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomDecoder *opus_custom_decoder_create( - const OpusCustomMode *mode, - int channels, - int *error -) OPUS_ARG_NONNULL(1); - -/** Initializes a previously allocated decoder state - * The memory pointed to by st must be the size returned by opus_custom_decoder_get_size. - * This is intended for applications which use their own allocator instead of malloc. - * @see opus_custom_decoder_create(),opus_custom_decoder_get_size() - * To reset a previously initialized state use the OPUS_RESET_STATE CTL. - * @param [in] st OpusCustomDecoder*: Decoder state - * @param [in] mode OpusCustomMode *: Contains all the information about the characteristics of - * the stream (must be the same characteristics as used for the - * encoder) - * @param [in] channels int: Number of channels - * @return OPUS_OK Success or @ref opus_errorcodes - */ -OPUS_CUSTOM_EXPORT_STATIC int opus_custom_decoder_init( - OpusCustomDecoder *st, - const OpusCustomMode *mode, - int channels -) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2); - -/** Destroys a an decoder state. - * @param[in] st OpusCustomDecoder*: State to be freed. - */ -OPUS_CUSTOM_EXPORT void opus_custom_decoder_destroy(OpusCustomDecoder *st); - -/** Decode an opus custom frame with floating point output - * @param [in] st OpusCustomDecoder*: Decoder state - * @param [in] data char*: Input payload. Use a NULL pointer to indicate packet loss - * @param [in] len int: Number of bytes in payload - * @param [out] pcm float*: Output signal (interleaved if 2 channels). length - * is frame_size*channels*sizeof(float) - * @param [in] frame_size Number of samples per channel of available space in *pcm. - * @returns Number of decoded samples or @ref opus_errorcodes - */ -OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_decode_float( - OpusCustomDecoder *st, - const unsigned char *data, - int len, - float *pcm, - int frame_size -) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); - -/** Decode an opus custom frame - * @param [in] st OpusCustomDecoder*: Decoder state - * @param [in] data char*: Input payload. Use a NULL pointer to indicate packet loss - * @param [in] len int: Number of bytes in payload - * @param [out] pcm opus_int16*: Output signal (interleaved if 2 channels). length - * is frame_size*channels*sizeof(opus_int16) - * @param [in] frame_size Number of samples per channel of available space in *pcm. - * @returns Number of decoded samples or @ref opus_errorcodes - */ -OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_decode( - OpusCustomDecoder *st, - const unsigned char *data, - int len, - opus_int16 *pcm, - int frame_size -) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); - -/** Perform a CTL function on an Opus custom decoder. - * - * Generally the request and subsequent arguments are generated - * by a convenience macro. - * @see opus_genericctls - */ -OPUS_CUSTOM_EXPORT int opus_custom_decoder_ctl(OpusCustomDecoder * OPUS_RESTRICT st, int request, ...) OPUS_ARG_NONNULL(1); - -/**@}*/ - -#ifdef __cplusplus -} -#endif - -#endif /* OPUS_CUSTOM_H */ diff --git a/src/opus-1.0.2/include/opus_defines.h b/src/opus-1.0.2/include/opus_defines.h deleted file mode 100644 index cdde061a..00000000 --- a/src/opus-1.0.2/include/opus_defines.h +++ /dev/null @@ -1,655 +0,0 @@ -/* Copyright (c) 2010-2011 Xiph.Org Foundation, Skype Limited - Written by Jean-Marc Valin and Koen Vos */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/** - * @file opus_defines.h - * @brief Opus reference implementation constants - */ - -#ifndef OPUS_DEFINES_H -#define OPUS_DEFINES_H - -#include "opus_types.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** @defgroup opus_errorcodes Error codes - * @{ - */ -/** No error @hideinitializer*/ -#define OPUS_OK 0 -/** One or more invalid/out of range arguments @hideinitializer*/ -#define OPUS_BAD_ARG -1 -/** The mode struct passed is invalid @hideinitializer*/ -#define OPUS_BUFFER_TOO_SMALL -2 -/** An internal error was detected @hideinitializer*/ -#define OPUS_INTERNAL_ERROR -3 -/** The compressed data passed is corrupted @hideinitializer*/ -#define OPUS_INVALID_PACKET -4 -/** Invalid/unsupported request number @hideinitializer*/ -#define OPUS_UNIMPLEMENTED -5 -/** An encoder or decoder structure is invalid or already freed @hideinitializer*/ -#define OPUS_INVALID_STATE -6 -/** Memory allocation has failed @hideinitializer*/ -#define OPUS_ALLOC_FAIL -7 -/**@}*/ - -/** @cond OPUS_INTERNAL_DOC */ -/**Export control for opus functions */ - -#ifndef OPUS_EXPORT -# if defined(__GNUC__) && defined(OPUS_BUILD) -# define OPUS_EXPORT __attribute__ ((visibility ("default"))) -# elif defined(WIN32) && !defined(__MINGW32__) -# ifdef OPUS_BUILD -# define OPUS_EXPORT __declspec(dllexport) -# else -# define OPUS_EXPORT -# endif -# else -# define OPUS_EXPORT -# endif -#endif - -# if !defined(OPUS_GNUC_PREREQ) -# if defined(__GNUC__)&&defined(__GNUC_MINOR__) -# define OPUS_GNUC_PREREQ(_maj,_min) \ - ((__GNUC__<<16)+__GNUC_MINOR__>=((_maj)<<16)+(_min)) -# else -# define OPUS_GNUC_PREREQ(_maj,_min) 0 -# endif -# endif - -#if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) ) -# if OPUS_GNUC_PREREQ(3,0) -# define OPUS_RESTRICT __restrict__ -# elif (defined(_MSC_VER) && _MSC_VER >= 1400) -# define OPUS_RESTRICT __restrict -# else -# define OPUS_RESTRICT -# endif -#else -# define OPUS_RESTRICT restrict -#endif - -/**Warning attributes for opus functions - * NONNULL is not used in OPUS_BUILD to avoid the compiler optimizing out - * some paranoid null checks. */ -#if defined(__GNUC__) && OPUS_GNUC_PREREQ(3, 4) -# define OPUS_WARN_UNUSED_RESULT __attribute__ ((__warn_unused_result__)) -#else -# define OPUS_WARN_UNUSED_RESULT -#endif -#if !defined(OPUS_BUILD) && defined(__GNUC__) && OPUS_GNUC_PREREQ(3, 4) -# define OPUS_ARG_NONNULL(_x) __attribute__ ((__nonnull__(_x))) -#else -# define OPUS_ARG_NONNULL(_x) -#endif - -/** These are the actual Encoder CTL ID numbers. - * They should not be used directly by applications. - * In general, SETs should be even and GETs should be odd.*/ -#define OPUS_SET_APPLICATION_REQUEST 4000 -#define OPUS_GET_APPLICATION_REQUEST 4001 -#define OPUS_SET_BITRATE_REQUEST 4002 -#define OPUS_GET_BITRATE_REQUEST 4003 -#define OPUS_SET_MAX_BANDWIDTH_REQUEST 4004 -#define OPUS_GET_MAX_BANDWIDTH_REQUEST 4005 -#define OPUS_SET_VBR_REQUEST 4006 -#define OPUS_GET_VBR_REQUEST 4007 -#define OPUS_SET_BANDWIDTH_REQUEST 4008 -#define OPUS_GET_BANDWIDTH_REQUEST 4009 -#define OPUS_SET_COMPLEXITY_REQUEST 4010 -#define OPUS_GET_COMPLEXITY_REQUEST 4011 -#define OPUS_SET_INBAND_FEC_REQUEST 4012 -#define OPUS_GET_INBAND_FEC_REQUEST 4013 -#define OPUS_SET_PACKET_LOSS_PERC_REQUEST 4014 -#define OPUS_GET_PACKET_LOSS_PERC_REQUEST 4015 -#define OPUS_SET_DTX_REQUEST 4016 -#define OPUS_GET_DTX_REQUEST 4017 -#define OPUS_SET_VBR_CONSTRAINT_REQUEST 4020 -#define OPUS_GET_VBR_CONSTRAINT_REQUEST 4021 -#define OPUS_SET_FORCE_CHANNELS_REQUEST 4022 -#define OPUS_GET_FORCE_CHANNELS_REQUEST 4023 -#define OPUS_SET_SIGNAL_REQUEST 4024 -#define OPUS_GET_SIGNAL_REQUEST 4025 -#define OPUS_GET_LOOKAHEAD_REQUEST 4027 -/* #define OPUS_RESET_STATE 4028 */ -#define OPUS_GET_SAMPLE_RATE_REQUEST 4029 -#define OPUS_GET_FINAL_RANGE_REQUEST 4031 -#define OPUS_GET_PITCH_REQUEST 4033 -#define OPUS_SET_GAIN_REQUEST 4034 -#define OPUS_GET_GAIN_REQUEST 4045 /* Should have been 4035 */ -#define OPUS_SET_LSB_DEPTH_REQUEST 4036 -#define OPUS_GET_LSB_DEPTH_REQUEST 4037 - -#define OPUS_GET_LAST_PACKET_DURATION_REQUEST 4039 - -/* Don't use 4045, it's already taken by OPUS_GET_GAIN_REQUEST */ - -/* Macros to trigger compilation errors when the wrong types are provided to a CTL */ -#define __opus_check_int(x) (((void)((x) == (opus_int32)0)), (opus_int32)(x)) -#define __opus_check_int_ptr(ptr) ((ptr) + ((ptr) - (opus_int32*)(ptr))) -#define __opus_check_uint_ptr(ptr) ((ptr) + ((ptr) - (opus_uint32*)(ptr))) -/** @endcond */ - -/** @defgroup opus_ctlvalues Pre-defined values for CTL interface - * @see opus_genericctls, opus_encoderctls - * @{ - */ -/* Values for the various encoder CTLs */ -#define OPUS_AUTO -1000 /**opus_int32: Allowed values: 0-10, inclusive. - * - * @hideinitializer */ -#define OPUS_SET_COMPLEXITY(x) OPUS_SET_COMPLEXITY_REQUEST, __opus_check_int(x) -/** Gets the encoder's complexity configuration. - * @see OPUS_SET_COMPLEXITY - * @param[out] x opus_int32 *: Returns a value in the range 0-10, - * inclusive. - * @hideinitializer */ -#define OPUS_GET_COMPLEXITY(x) OPUS_GET_COMPLEXITY_REQUEST, __opus_check_int_ptr(x) - -/** Configures the bitrate in the encoder. - * Rates from 500 to 512000 bits per second are meaningful, as well as the - * special values #OPUS_AUTO and #OPUS_BITRATE_MAX. - * The value #OPUS_BITRATE_MAX can be used to cause the codec to use as much - * rate as it can, which is useful for controlling the rate by adjusting the - * output buffer size. - * @see OPUS_GET_BITRATE - * @param[in] x opus_int32: Bitrate in bits per second. The default - * is determined based on the number of - * channels and the input sampling rate. - * @hideinitializer */ -#define OPUS_SET_BITRATE(x) OPUS_SET_BITRATE_REQUEST, __opus_check_int(x) -/** Gets the encoder's bitrate configuration. - * @see OPUS_SET_BITRATE - * @param[out] x opus_int32 *: Returns the bitrate in bits per second. - * The default is determined based on the - * number of channels and the input - * sampling rate. - * @hideinitializer */ -#define OPUS_GET_BITRATE(x) OPUS_GET_BITRATE_REQUEST, __opus_check_int_ptr(x) - -/** Enables or disables variable bitrate (VBR) in the encoder. - * The configured bitrate may not be met exactly because frames must - * be an integer number of bytes in length. - * @warning Only the MDCT mode of Opus can provide hard CBR behavior. - * @see OPUS_GET_VBR - * @see OPUS_SET_VBR_CONSTRAINT - * @param[in] x opus_int32: Allowed values: - *
    - *
    0
    Hard CBR. For LPC/hybrid modes at very low bit-rate, this can - * cause noticeable quality degradation.
    - *
    1
    VBR (default). The exact type of VBR is controlled by - * #OPUS_SET_VBR_CONSTRAINT.
    - *
    - * @hideinitializer */ -#define OPUS_SET_VBR(x) OPUS_SET_VBR_REQUEST, __opus_check_int(x) -/** Determine if variable bitrate (VBR) is enabled in the encoder. - * @see OPUS_SET_VBR - * @see OPUS_GET_VBR_CONSTRAINT - * @param[out] x opus_int32 *: Returns one of the following values: - *
    - *
    0
    Hard CBR.
    - *
    1
    VBR (default). The exact type of VBR may be retrieved via - * #OPUS_GET_VBR_CONSTRAINT.
    - *
    - * @hideinitializer */ -#define OPUS_GET_VBR(x) OPUS_GET_VBR_REQUEST, __opus_check_int_ptr(x) - -/** Enables or disables constrained VBR in the encoder. - * This setting is ignored when the encoder is in CBR mode. - * @warning Only the MDCT mode of Opus currently heeds the constraint. - * Speech mode ignores it completely, hybrid mode may fail to obey it - * if the LPC layer uses more bitrate than the constraint would have - * permitted. - * @see OPUS_GET_VBR_CONSTRAINT - * @see OPUS_SET_VBR - * @param[in] x opus_int32: Allowed values: - *
    - *
    0
    Unconstrained VBR.
    - *
    1
    Constrained VBR (default). This creates a maximum of one - * frame of buffering delay assuming a transport with a - * serialization speed of the nominal bitrate.
    - *
    - * @hideinitializer */ -#define OPUS_SET_VBR_CONSTRAINT(x) OPUS_SET_VBR_CONSTRAINT_REQUEST, __opus_check_int(x) -/** Determine if constrained VBR is enabled in the encoder. - * @see OPUS_SET_VBR_CONSTRAINT - * @see OPUS_GET_VBR - * @param[out] x opus_int32 *: Returns one of the following values: - *
    - *
    0
    Unconstrained VBR.
    - *
    1
    Constrained VBR (default).
    - *
    - * @hideinitializer */ -#define OPUS_GET_VBR_CONSTRAINT(x) OPUS_GET_VBR_CONSTRAINT_REQUEST, __opus_check_int_ptr(x) - -/** Configures mono/stereo forcing in the encoder. - * This can force the encoder to produce packets encoded as either mono or - * stereo, regardless of the format of the input audio. This is useful when - * the caller knows that the input signal is currently a mono source embedded - * in a stereo stream. - * @see OPUS_GET_FORCE_CHANNELS - * @param[in] x opus_int32: Allowed values: - *
    - *
    #OPUS_AUTO
    Not forced (default)
    - *
    1
    Forced mono
    - *
    2
    Forced stereo
    - *
    - * @hideinitializer */ -#define OPUS_SET_FORCE_CHANNELS(x) OPUS_SET_FORCE_CHANNELS_REQUEST, __opus_check_int(x) -/** Gets the encoder's forced channel configuration. - * @see OPUS_SET_FORCE_CHANNELS - * @param[out] x opus_int32 *: - *
    - *
    #OPUS_AUTO
    Not forced (default)
    - *
    1
    Forced mono
    - *
    2
    Forced stereo
    - *
    - * @hideinitializer */ -#define OPUS_GET_FORCE_CHANNELS(x) OPUS_GET_FORCE_CHANNELS_REQUEST, __opus_check_int_ptr(x) - -/** Configures the maximum bandpass that the encoder will select automatically. - * Applications should normally use this instead of #OPUS_SET_BANDWIDTH - * (leaving that set to the default, #OPUS_AUTO). This allows the - * application to set an upper bound based on the type of input it is - * providing, but still gives the encoder the freedom to reduce the bandpass - * when the bitrate becomes too low, for better overall quality. - * @see OPUS_GET_MAX_BANDWIDTH - * @param[in] x opus_int32: Allowed values: - *
    - *
    OPUS_BANDWIDTH_NARROWBAND
    4 kHz passband
    - *
    OPUS_BANDWIDTH_MEDIUMBAND
    6 kHz passband
    - *
    OPUS_BANDWIDTH_WIDEBAND
    8 kHz passband
    - *
    OPUS_BANDWIDTH_SUPERWIDEBAND
    12 kHz passband
    - *
    OPUS_BANDWIDTH_FULLBAND
    20 kHz passband (default)
    - *
    - * @hideinitializer */ -#define OPUS_SET_MAX_BANDWIDTH(x) OPUS_SET_MAX_BANDWIDTH_REQUEST, __opus_check_int(x) - -/** Gets the encoder's configured maximum allowed bandpass. - * @see OPUS_SET_MAX_BANDWIDTH - * @param[out] x opus_int32 *: Allowed values: - *
    - *
    #OPUS_BANDWIDTH_NARROWBAND
    4 kHz passband
    - *
    #OPUS_BANDWIDTH_MEDIUMBAND
    6 kHz passband
    - *
    #OPUS_BANDWIDTH_WIDEBAND
    8 kHz passband
    - *
    #OPUS_BANDWIDTH_SUPERWIDEBAND
    12 kHz passband
    - *
    #OPUS_BANDWIDTH_FULLBAND
    20 kHz passband (default)
    - *
    - * @hideinitializer */ -#define OPUS_GET_MAX_BANDWIDTH(x) OPUS_GET_MAX_BANDWIDTH_REQUEST, __opus_check_int_ptr(x) - -/** Sets the encoder's bandpass to a specific value. - * This prevents the encoder from automatically selecting the bandpass based - * on the available bitrate. If an application knows the bandpass of the input - * audio it is providing, it should normally use #OPUS_SET_MAX_BANDWIDTH - * instead, which still gives the encoder the freedom to reduce the bandpass - * when the bitrate becomes too low, for better overall quality. - * @see OPUS_GET_BANDWIDTH - * @param[in] x opus_int32: Allowed values: - *
    - *
    #OPUS_AUTO
    (default)
    - *
    #OPUS_BANDWIDTH_NARROWBAND
    4 kHz passband
    - *
    #OPUS_BANDWIDTH_MEDIUMBAND
    6 kHz passband
    - *
    #OPUS_BANDWIDTH_WIDEBAND
    8 kHz passband
    - *
    #OPUS_BANDWIDTH_SUPERWIDEBAND
    12 kHz passband
    - *
    #OPUS_BANDWIDTH_FULLBAND
    20 kHz passband
    - *
    - * @hideinitializer */ -#define OPUS_SET_BANDWIDTH(x) OPUS_SET_BANDWIDTH_REQUEST, __opus_check_int(x) - -/** Configures the type of signal being encoded. - * This is a hint which helps the encoder's mode selection. - * @see OPUS_GET_SIGNAL - * @param[in] x opus_int32: Allowed values: - *
    - *
    #OPUS_AUTO
    (default)
    - *
    #OPUS_SIGNAL_VOICE
    Bias thresholds towards choosing LPC or Hybrid modes.
    - *
    #OPUS_SIGNAL_MUSIC
    Bias thresholds towards choosing MDCT modes.
    - *
    - * @hideinitializer */ -#define OPUS_SET_SIGNAL(x) OPUS_SET_SIGNAL_REQUEST, __opus_check_int(x) -/** Gets the encoder's configured signal type. - * @see OPUS_SET_SIGNAL - * @param[out] x opus_int32 *: Returns one of the following values: - *
    - *
    #OPUS_AUTO
    (default)
    - *
    #OPUS_SIGNAL_VOICE
    Bias thresholds towards choosing LPC or Hybrid modes.
    - *
    #OPUS_SIGNAL_MUSIC
    Bias thresholds towards choosing MDCT modes.
    - *
    - * @hideinitializer */ -#define OPUS_GET_SIGNAL(x) OPUS_GET_SIGNAL_REQUEST, __opus_check_int_ptr(x) - - -/** Configures the encoder's intended application. - * The initial value is a mandatory argument to the encoder_create function. - * @see OPUS_GET_APPLICATION - * @param[in] x opus_int32: Returns one of the following values: - *
    - *
    #OPUS_APPLICATION_VOIP
    - *
    Process signal for improved speech intelligibility.
    - *
    #OPUS_APPLICATION_AUDIO
    - *
    Favor faithfulness to the original input.
    - *
    #OPUS_APPLICATION_RESTRICTED_LOWDELAY
    - *
    Configure the minimum possible coding delay by disabling certain modes - * of operation.
    - *
    - * @hideinitializer */ -#define OPUS_SET_APPLICATION(x) OPUS_SET_APPLICATION_REQUEST, __opus_check_int(x) -/** Gets the encoder's configured application. - * @see OPUS_SET_APPLICATION - * @param[out] x opus_int32 *: Returns one of the following values: - *
    - *
    #OPUS_APPLICATION_VOIP
    - *
    Process signal for improved speech intelligibility.
    - *
    #OPUS_APPLICATION_AUDIO
    - *
    Favor faithfulness to the original input.
    - *
    #OPUS_APPLICATION_RESTRICTED_LOWDELAY
    - *
    Configure the minimum possible coding delay by disabling certain modes - * of operation.
    - *
    - * @hideinitializer */ -#define OPUS_GET_APPLICATION(x) OPUS_GET_APPLICATION_REQUEST, __opus_check_int_ptr(x) - -/** Gets the sampling rate the encoder or decoder was initialized with. - * This simply returns the Fs value passed to opus_encoder_init() - * or opus_decoder_init(). - * @param[out] x opus_int32 *: Sampling rate of encoder or decoder. - * @hideinitializer - */ -#define OPUS_GET_SAMPLE_RATE(x) OPUS_GET_SAMPLE_RATE_REQUEST, __opus_check_int_ptr(x) - -/** Gets the total samples of delay added by the entire codec. - * This can be queried by the encoder and then the provided number of samples can be - * skipped on from the start of the decoder's output to provide time aligned input - * and output. From the perspective of a decoding application the real data begins this many - * samples late. - * - * The decoder contribution to this delay is identical for all decoders, but the - * encoder portion of the delay may vary from implementation to implementation, - * version to version, or even depend on the encoder's initial configuration. - * Applications needing delay compensation should call this CTL rather than - * hard-coding a value. - * @param[out] x opus_int32 *: Number of lookahead samples - * @hideinitializer */ -#define OPUS_GET_LOOKAHEAD(x) OPUS_GET_LOOKAHEAD_REQUEST, __opus_check_int_ptr(x) - -/** Configures the encoder's use of inband forward error correction (FEC). - * @note This is only applicable to the LPC layer - * @see OPUS_GET_INBAND_FEC - * @param[in] x opus_int32: Allowed values: - *
    - *
    0
    Disable inband FEC (default).
    - *
    1
    Enable inband FEC.
    - *
    - * @hideinitializer */ -#define OPUS_SET_INBAND_FEC(x) OPUS_SET_INBAND_FEC_REQUEST, __opus_check_int(x) -/** Gets encoder's configured use of inband forward error correction. - * @see OPUS_SET_INBAND_FEC - * @param[out] x opus_int32 *: Returns one of the following values: - *
    - *
    0
    Inband FEC disabled (default).
    - *
    1
    Inband FEC enabled.
    - *
    - * @hideinitializer */ -#define OPUS_GET_INBAND_FEC(x) OPUS_GET_INBAND_FEC_REQUEST, __opus_check_int_ptr(x) - -/** Configures the encoder's expected packet loss percentage. - * Higher values with trigger progressively more loss resistant behavior in the encoder - * at the expense of quality at a given bitrate in the lossless case, but greater quality - * under loss. - * @see OPUS_GET_PACKET_LOSS_PERC - * @param[in] x opus_int32: Loss percentage in the range 0-100, inclusive (default: 0). - * @hideinitializer */ -#define OPUS_SET_PACKET_LOSS_PERC(x) OPUS_SET_PACKET_LOSS_PERC_REQUEST, __opus_check_int(x) -/** Gets the encoder's configured packet loss percentage. - * @see OPUS_SET_PACKET_LOSS_PERC - * @param[out] x opus_int32 *: Returns the configured loss percentage - * in the range 0-100, inclusive (default: 0). - * @hideinitializer */ -#define OPUS_GET_PACKET_LOSS_PERC(x) OPUS_GET_PACKET_LOSS_PERC_REQUEST, __opus_check_int_ptr(x) - -/** Configures the encoder's use of discontinuous transmission (DTX). - * @note This is only applicable to the LPC layer - * @see OPUS_GET_DTX - * @param[in] x opus_int32: Allowed values: - *
    - *
    0
    Disable DTX (default).
    - *
    1
    Enabled DTX.
    - *
    - * @hideinitializer */ -#define OPUS_SET_DTX(x) OPUS_SET_DTX_REQUEST, __opus_check_int(x) -/** Gets encoder's configured use of discontinuous transmission. - * @see OPUS_SET_DTX - * @param[out] x opus_int32 *: Returns one of the following values: - *
    - *
    0
    DTX disabled (default).
    - *
    1
    DTX enabled.
    - *
    - * @hideinitializer */ -#define OPUS_GET_DTX(x) OPUS_GET_DTX_REQUEST, __opus_check_int_ptr(x) -/** Configures the depth of signal being encoded. - * This is a hint which helps the encoder identify silence and near-silence. - * @see OPUS_GET_LSB_DEPTH - * @param[in] x opus_int32: Input precision in bits, between 8 and 24 - * (default: 24). - * @hideinitializer */ -#define OPUS_SET_LSB_DEPTH(x) OPUS_SET_LSB_DEPTH_REQUEST, __opus_check_int(x) -/** Gets the encoder's configured signal depth. - * @see OPUS_SET_LSB_DEPTH - * @param[out] x opus_int32 *: Input precision in bits, between 8 and - * 24 (default: 24). - * @hideinitializer */ -#define OPUS_GET_LSB_DEPTH(x) OPUS_GET_LSB_DEPTH_REQUEST, __opus_check_int_ptr(x) - -/** Gets the duration (in samples) of the last packet successfully decoded or concealed. - * @param[out] x opus_int32 *: Number of samples (at current sampling rate). - * @hideinitializer */ -#define OPUS_GET_LAST_PACKET_DURATION(x) OPUS_GET_LAST_PACKET_DURATION_REQUEST, __opus_check_int_ptr(x) -/**@}*/ - -/** @defgroup opus_genericctls Generic CTLs - * - * These macros are used with the \c opus_decoder_ctl and - * \c opus_encoder_ctl calls to generate a particular - * request. - * - * When called on an \c OpusDecoder they apply to that - * particular decoder instance. When called on an - * \c OpusEncoder they apply to the corresponding setting - * on that encoder instance, if present. - * - * Some usage examples: - * - * @code - * int ret; - * opus_int32 pitch; - * ret = opus_decoder_ctl(dec_ctx, OPUS_GET_PITCH(&pitch)); - * if (ret == OPUS_OK) return ret; - * - * opus_encoder_ctl(enc_ctx, OPUS_RESET_STATE); - * opus_decoder_ctl(dec_ctx, OPUS_RESET_STATE); - * - * opus_int32 enc_bw, dec_bw; - * opus_encoder_ctl(enc_ctx, OPUS_GET_BANDWIDTH(&enc_bw)); - * opus_decoder_ctl(dec_ctx, OPUS_GET_BANDWIDTH(&dec_bw)); - * if (enc_bw != dec_bw) { - * printf("packet bandwidth mismatch!\n"); - * } - * @endcode - * - * @see opus_encoder, opus_decoder_ctl, opus_encoder_ctl, opus_decoderctls, opus_encoderctls - * @{ - */ - -/** Resets the codec state to be equivalent to a freshly initialized state. - * This should be called when switching streams in order to prevent - * the back to back decoding from giving different results from - * one at a time decoding. - * @hideinitializer */ -#define OPUS_RESET_STATE 4028 - -/** Gets the final state of the codec's entropy coder. - * This is used for testing purposes, - * The encoder and decoder state should be identical after coding a payload - * (assuming no data corruption or software bugs) - * - * @param[out] x opus_uint32 *: Entropy coder state - * - * @hideinitializer */ -#define OPUS_GET_FINAL_RANGE(x) OPUS_GET_FINAL_RANGE_REQUEST, __opus_check_uint_ptr(x) - -/** Gets the pitch of the last decoded frame, if available. - * This can be used for any post-processing algorithm requiring the use of pitch, - * e.g. time stretching/shortening. If the last frame was not voiced, or if the - * pitch was not coded in the frame, then zero is returned. - * - * This CTL is only implemented for decoder instances. - * - * @param[out] x opus_int32 *: pitch period at 48 kHz (or 0 if not available) - * - * @hideinitializer */ -#define OPUS_GET_PITCH(x) OPUS_GET_PITCH_REQUEST, __opus_check_int_ptr(x) - -/** Gets the encoder's configured bandpass or the decoder's last bandpass. - * @see OPUS_SET_BANDWIDTH - * @param[out] x opus_int32 *: Returns one of the following values: - *
    - *
    #OPUS_AUTO
    (default)
    - *
    #OPUS_BANDWIDTH_NARROWBAND
    4 kHz passband
    - *
    #OPUS_BANDWIDTH_MEDIUMBAND
    6 kHz passband
    - *
    #OPUS_BANDWIDTH_WIDEBAND
    8 kHz passband
    - *
    #OPUS_BANDWIDTH_SUPERWIDEBAND
    12 kHz passband
    - *
    #OPUS_BANDWIDTH_FULLBAND
    20 kHz passband
    - *
    - * @hideinitializer */ -#define OPUS_GET_BANDWIDTH(x) OPUS_GET_BANDWIDTH_REQUEST, __opus_check_int_ptr(x) - -/**@}*/ - -/** @defgroup opus_decoderctls Decoder related CTLs - * @see opus_genericctls, opus_encoderctls, opus_decoder - * @{ - */ - -/** Configures decoder gain adjustment. - * Scales the decoded output by a factor specified in Q8 dB units. - * This has a maximum range of -32768 to 32767 inclusive, and returns - * OPUS_BAD_ARG otherwise. The default is zero indicating no adjustment. - * This setting survives decoder reset. - * - * gain = pow(10, x/(20.0*256)) - * - * @param[in] x opus_int32: Amount to scale PCM signal by in Q8 dB units. - * @hideinitializer */ -#define OPUS_SET_GAIN(x) OPUS_SET_GAIN_REQUEST, __opus_check_int(x) -/** Gets the decoder's configured gain adjustment. @see OPUS_SET_GAIN - * - * @param[out] x opus_int32 *: Amount to scale PCM signal by in Q8 dB units. - * @hideinitializer */ -#define OPUS_GET_GAIN(x) OPUS_GET_GAIN_REQUEST, __opus_check_int_ptr(x) - -/**@}*/ - -/** @defgroup opus_libinfo Opus library information functions - * @{ - */ - -/** Converts an opus error code into a human readable string. - * - * @param[in] error int: Error number - * @returns Error string - */ -OPUS_EXPORT const char *opus_strerror(int error); - -/** Gets the libopus version string. - * - * @returns Version string - */ -OPUS_EXPORT const char *opus_get_version_string(void); -/**@}*/ - -#ifdef __cplusplus -} -#endif - -#endif /* OPUS_DEFINES_H */ diff --git a/src/opus-1.0.2/include/opus_multistream.h b/src/opus-1.0.2/include/opus_multistream.h deleted file mode 100644 index 658067f7..00000000 --- a/src/opus-1.0.2/include/opus_multistream.h +++ /dev/null @@ -1,632 +0,0 @@ -/* Copyright (c) 2011 Xiph.Org Foundation - Written by Jean-Marc Valin */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/** - * @file opus_multistream.h - * @brief Opus reference implementation multistream API - */ - -#ifndef OPUS_MULTISTREAM_H -#define OPUS_MULTISTREAM_H - -#include "opus.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** @cond OPUS_INTERNAL_DOC */ - -/** Macros to trigger compilation errors when the wrong types are provided to a - * CTL. */ -/**@{*/ -#define __opus_check_encstate_ptr(ptr) ((ptr) + ((ptr) - (OpusEncoder**)(ptr))) -#define __opus_check_decstate_ptr(ptr) ((ptr) + ((ptr) - (OpusDecoder**)(ptr))) -/**@}*/ - -/** These are the actual encoder and decoder CTL ID numbers. - * They should not be used directly by applications. - * In general, SETs should be even and GETs should be odd.*/ -/**@{*/ -#define OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST 5120 -#define OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST 5122 -/**@}*/ - -/** @endcond */ - -/** @defgroup opus_multistream_ctls Multistream specific encoder and decoder CTLs - * - * These are convenience macros that are specific to the - * opus_multistream_encoder_ctl() and opus_multistream_decoder_ctl() - * interface. - * The CTLs from @ref opus_genericctls, @ref opus_encoderctls, and - * @ref opus_decoderctls may be applied to a multistream encoder or decoder as - * well. - * In addition, you may retrieve the encoder or decoder state for an specific - * stream via #OPUS_MULTISTREAM_GET_ENCODER_STATE or - * #OPUS_MULTISTREAM_GET_DECODER_STATE and apply CTLs to it individually. - */ -/**@{*/ - -/** Gets the encoder state for an individual stream of a multistream encoder. - * @param[in] x opus_int32: The index of the stream whose encoder you - * wish to retrieve. - * This must be non-negative and less than - * the streams parameter used - * to initialize the encoder. - * @param[out] y OpusEncoder**: Returns a pointer to the given - * encoder state. - * @retval OPUS_BAD_ARG The index of the requested stream was out of range. - * @hideinitializer - */ -#define OPUS_MULTISTREAM_GET_ENCODER_STATE(x,y) OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST, __opus_check_int(x), __opus_check_encstate_ptr(y) - -/** Gets the decoder state for an individual stream of a multistream decoder. - * @param[in] x opus_int32: The index of the stream whose decoder you - * wish to retrieve. - * This must be non-negative and less than - * the streams parameter used - * to initialize the decoder. - * @param[out] y OpusDecoder**: Returns a pointer to the given - * decoder state. - * @retval OPUS_BAD_ARG The index of the requested stream was out of range. - * @hideinitializer - */ -#define OPUS_MULTISTREAM_GET_DECODER_STATE(x,y) OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST, __opus_check_int(x), __opus_check_decstate_ptr(y) - -/**@}*/ - -/** @defgroup opus_multistream Opus Multistream API - * @{ - * - * The multistream API allows individual Opus streams to be combined into a - * single packet, enabling support for up to 255 channels. Unlike an - * elementary Opus stream, the encoder and decoder must negotiate the channel - * configuration before the decoder can successfully interpret the data in the - * packets produced by the encoder. Some basic information, such as packet - * duration, can be computed without any special negotiation. - * - * The format for multistream Opus packets is defined in the - * Ogg - * encapsulation specification and is based on the self-delimited Opus - * framing described in Appendix B of RFC 6716. - * Normal Opus packets are just a degenerate case of multistream Opus packets, - * and can be encoded or decoded with the multistream API by setting - * streams to 1 when initializing the encoder or - * decoder. - * - * Multistream Opus streams can contain up to 255 elementary Opus streams. - * These may be either "uncoupled" or "coupled", indicating that the decoder - * is configured to decode them to either 1 or 2 channels, respectively. - * The streams are ordered so that all coupled streams appear at the - * beginning. - * - * A mapping table defines which decoded channel i - * should be used for each input/output (I/O) channel j. This table is - * typically provided as an unsigned char array. - * Let i = mapping[j] be the index for I/O channel j. - * If i < 2*coupled_streams, then I/O channel j is - * encoded as the left channel of stream (i/2) if i - * is even, or as the right channel of stream (i/2) if - * i is odd. Otherwise, I/O channel j is encoded as - * mono in stream (i - coupled_streams), unless it has the special - * value 255, in which case it is omitted from the encoding entirely (the - * decoder will reproduce it as silence). Each value i must either - * be the special value 255 or be less than streams + coupled_streams. - * - * The output channels specified by the encoder - * should use the - * Vorbis - * channel ordering. A decoder may wish to apply an additional permutation - * to the mapping the encoder used to achieve a different output channel - * order (e.g. for outputing in WAV order). - * - * Each multistream packet contains an Opus packet for each stream, and all of - * the Opus packets in a single multistream packet must have the same - * duration. Therefore the duration of a multistream packet can be extracted - * from the TOC sequence of the first stream, which is located at the - * beginning of the packet, just like an elementary Opus stream: - * - * @code - * int nb_samples; - * int nb_frames; - * nb_frames = opus_packet_get_nb_frames(data, len); - * if (nb_frames < 1) - * return nb_frames; - * nb_samples = opus_packet_get_samples_per_frame(data, 48000) * nb_frames; - * @endcode - * - * The general encoding and decoding process proceeds exactly the same as in - * the normal @ref opus_encoder and @ref opus_decoder APIs. - * See their documentation for an overview of how to use the corresponding - * multistream functions. - */ - -/** Opus multistream encoder state. - * This contains the complete state of a multistream Opus encoder. - * It is position independent and can be freely copied. - * @see opus_multistream_encoder_create - * @see opus_multistream_encoder_init - */ -typedef struct OpusMSEncoder OpusMSEncoder; - -/** Opus multistream decoder state. - * This contains the complete state of a multistream Opus decoder. - * It is position independent and can be freely copied. - * @see opus_multistream_decoder_create - * @see opus_multistream_decoder_init - */ -typedef struct OpusMSDecoder OpusMSDecoder; - -/**\name Multistream encoder functions */ -/**@{*/ - -/** Gets the size of an OpusMSEncoder structure. - * @param streams int: The total number of streams to encode from the - * input. - * This must be no more than 255. - * @param coupled_streams int: Number of coupled (2 channel) streams - * to encode. - * This must be no larger than the total - * number of streams. - * Additionally, The total number of - * encoded channels (streams + - * coupled_streams) must be no - * more than 255. - * @returns The size in bytes on success, or a negative error code - * (see @ref opus_errorcodes) on error. - */ -OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_encoder_get_size( - int streams, - int coupled_streams -); - -/** Allocates and initializes a multistream encoder state. - * Call opus_multistream_encoder_destroy() to release - * this object when finished. - * @param Fs opus_int32: Sampling rate of the input signal (in Hz). - * This must be one of 8000, 12000, 16000, - * 24000, or 48000. - * @param channels int: Number of channels in the input signal. - * This must be at most 255. - * It may be greater than the number of - * coded channels (streams + - * coupled_streams). - * @param streams int: The total number of streams to encode from the - * input. - * This must be no more than the number of channels. - * @param coupled_streams int: Number of coupled (2 channel) streams - * to encode. - * This must be no larger than the total - * number of streams. - * Additionally, The total number of - * encoded channels (streams + - * coupled_streams) must be no - * more than the number of input channels. - * @param[in] mapping const unsigned char[channels]: Mapping from - * encoded channels to input channels, as described in - * @ref opus_multistream. As an extra constraint, the - * multistream encoder does not allow encoding coupled - * streams for which one channel is unused since this - * is never a good idea. - * @param application int: The target encoder application. - * This must be one of the following: - *
    - *
    #OPUS_APPLICATION_VOIP
    - *
    Process signal for improved speech intelligibility.
    - *
    #OPUS_APPLICATION_AUDIO
    - *
    Favor faithfulness to the original input.
    - *
    #OPUS_APPLICATION_RESTRICTED_LOWDELAY
    - *
    Configure the minimum possible coding delay by disabling certain modes - * of operation.
    - *
    - * @param[out] error int *: Returns #OPUS_OK on success, or an error - * code (see @ref opus_errorcodes) on - * failure. - */ -OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSEncoder *opus_multistream_encoder_create( - opus_int32 Fs, - int channels, - int streams, - int coupled_streams, - const unsigned char *mapping, - int application, - int *error -) OPUS_ARG_NONNULL(5); - -/** Initialize a previously allocated multistream encoder state. - * The memory pointed to by \a st must be at least the size returned by - * opus_multistream_encoder_get_size(). - * This is intended for applications which use their own allocator instead of - * malloc. - * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. - * @see opus_multistream_encoder_create - * @see opus_multistream_encoder_get_size - * @param st OpusMSEncoder*: Multistream encoder state to initialize. - * @param Fs opus_int32: Sampling rate of the input signal (in Hz). - * This must be one of 8000, 12000, 16000, - * 24000, or 48000. - * @param channels int: Number of channels in the input signal. - * This must be at most 255. - * It may be greater than the number of - * coded channels (streams + - * coupled_streams). - * @param streams int: The total number of streams to encode from the - * input. - * This must be no more than the number of channels. - * @param coupled_streams int: Number of coupled (2 channel) streams - * to encode. - * This must be no larger than the total - * number of streams. - * Additionally, The total number of - * encoded channels (streams + - * coupled_streams) must be no - * more than the number of input channels. - * @param[in] mapping const unsigned char[channels]: Mapping from - * encoded channels to input channels, as described in - * @ref opus_multistream. As an extra constraint, the - * multistream encoder does not allow encoding coupled - * streams for which one channel is unused since this - * is never a good idea. - * @param application int: The target encoder application. - * This must be one of the following: - *
    - *
    #OPUS_APPLICATION_VOIP
    - *
    Process signal for improved speech intelligibility.
    - *
    #OPUS_APPLICATION_AUDIO
    - *
    Favor faithfulness to the original input.
    - *
    #OPUS_APPLICATION_RESTRICTED_LOWDELAY
    - *
    Configure the minimum possible coding delay by disabling certain modes - * of operation.
    - *
    - * @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes) - * on failure. - */ -OPUS_EXPORT int opus_multistream_encoder_init( - OpusMSEncoder *st, - opus_int32 Fs, - int channels, - int streams, - int coupled_streams, - const unsigned char *mapping, - int application -) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6); - -/** Encodes a multistream Opus frame. - * @param st OpusMSEncoder*: Multistream encoder state. - * @param[in] pcm const opus_int16*: The input signal as interleaved - * samples. - * This must contain - * frame_size*channels - * samples. - * @param frame_size int: Number of samples per channel in the input - * signal. - * This must be an Opus frame size for the - * encoder's sampling rate. - * For example, at 48 kHz the permitted values - * are 120, 240, 480, 960, 1920, and 2880. - * Passing in a duration of less than 10 ms - * (480 samples at 48 kHz) will prevent the - * encoder from using the LPC or hybrid modes. - * @param[out] data unsigned char*: Output payload. - * This must contain storage for at - * least \a max_data_bytes. - * @param [in] max_data_bytes opus_int32: Size of the allocated - * memory for the output - * payload. This may be - * used to impose an upper limit on - * the instant bitrate, but should - * not be used as the only bitrate - * control. Use #OPUS_SET_BITRATE to - * control the bitrate. - * @returns The length of the encoded packet (in bytes) on success or a - * negative error code (see @ref opus_errorcodes) on failure. - */ -OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode( - OpusMSEncoder *st, - const opus_int16 *pcm, - int frame_size, - unsigned char *data, - opus_int32 max_data_bytes -) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); - -/** Encodes a multistream Opus frame from floating point input. - * @param st OpusMSEncoder*: Multistream encoder state. - * @param[in] pcm const float*: The input signal as interleaved - * samples with a normal range of - * +/-1.0. - * Samples with a range beyond +/-1.0 - * are supported but will be clipped by - * decoders using the integer API and - * should only be used if it is known - * that the far end supports extended - * dynamic range. - * This must contain - * frame_size*channels - * samples. - * @param frame_size int: Number of samples per channel in the input - * signal. - * This must be an Opus frame size for the - * encoder's sampling rate. - * For example, at 48 kHz the permitted values - * are 120, 240, 480, 960, 1920, and 2880. - * Passing in a duration of less than 10 ms - * (480 samples at 48 kHz) will prevent the - * encoder from using the LPC or hybrid modes. - * @param[out] data unsigned char*: Output payload. - * This must contain storage for at - * least \a max_data_bytes. - * @param [in] max_data_bytes opus_int32: Size of the allocated - * memory for the output - * payload. This may be - * used to impose an upper limit on - * the instant bitrate, but should - * not be used as the only bitrate - * control. Use #OPUS_SET_BITRATE to - * control the bitrate. - * @returns The length of the encoded packet (in bytes) on success or a - * negative error code (see @ref opus_errorcodes) on failure. - */ -OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode_float( - OpusMSEncoder *st, - const float *pcm, - int frame_size, - unsigned char *data, - opus_int32 max_data_bytes -) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); - -/** Frees an OpusMSEncoder allocated by - * opus_multistream_encoder_create(). - * @param st OpusMSEncoder*: Multistream encoder state to be freed. - */ -OPUS_EXPORT void opus_multistream_encoder_destroy(OpusMSEncoder *st); - -/** Perform a CTL function on a multistream Opus encoder. - * - * Generally the request and subsequent arguments are generated by a - * convenience macro. - * @param st OpusMSEncoder*: Multistream encoder state. - * @param request This and all remaining parameters should be replaced by one - * of the convenience macros in @ref opus_genericctls, - * @ref opus_encoderctls, or @ref opus_multistream_ctls. - * @see opus_genericctls - * @see opus_encoderctls - * @see opus_multistream_ctls - */ -OPUS_EXPORT int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...) OPUS_ARG_NONNULL(1); - -/**@}*/ - -/**\name Multistream decoder functions */ -/**@{*/ - -/** Gets the size of an OpusMSDecoder structure. - * @param streams int: The total number of streams coded in the - * input. - * This must be no more than 255. - * @param coupled_streams int: Number streams to decode as coupled - * (2 channel) streams. - * This must be no larger than the total - * number of streams. - * Additionally, The total number of - * coded channels (streams + - * coupled_streams) must be no - * more than 255. - * @returns The size in bytes on success, or a negative error code - * (see @ref opus_errorcodes) on error. - */ -OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_decoder_get_size( - int streams, - int coupled_streams -); - -/** Allocates and initializes a multistream decoder state. - * Call opus_multistream_decoder_destroy() to release - * this object when finished. - * @param Fs opus_int32: Sampling rate to decode at (in Hz). - * This must be one of 8000, 12000, 16000, - * 24000, or 48000. - * @param channels int: Number of channels to output. - * This must be at most 255. - * It may be different from the number of coded - * channels (streams + - * coupled_streams). - * @param streams int: The total number of streams coded in the - * input. - * This must be no more than 255. - * @param coupled_streams int: Number of streams to decode as coupled - * (2 channel) streams. - * This must be no larger than the total - * number of streams. - * Additionally, The total number of - * coded channels (streams + - * coupled_streams) must be no - * more than 255. - * @param[in] mapping const unsigned char[channels]: Mapping from - * coded channels to output channels, as described in - * @ref opus_multistream. - * @param[out] error int *: Returns #OPUS_OK on success, or an error - * code (see @ref opus_errorcodes) on - * failure. - */ -OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSDecoder *opus_multistream_decoder_create( - opus_int32 Fs, - int channels, - int streams, - int coupled_streams, - const unsigned char *mapping, - int *error -) OPUS_ARG_NONNULL(5); - -/** Intialize a previously allocated decoder state object. - * The memory pointed to by \a st must be at least the size returned by - * opus_multistream_encoder_get_size(). - * This is intended for applications which use their own allocator instead of - * malloc. - * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. - * @see opus_multistream_decoder_create - * @see opus_multistream_deocder_get_size - * @param st OpusMSEncoder*: Multistream encoder state to initialize. - * @param Fs opus_int32: Sampling rate to decode at (in Hz). - * This must be one of 8000, 12000, 16000, - * 24000, or 48000. - * @param channels int: Number of channels to output. - * This must be at most 255. - * It may be different from the number of coded - * channels (streams + - * coupled_streams). - * @param streams int: The total number of streams coded in the - * input. - * This must be no more than 255. - * @param coupled_streams int: Number of streams to decode as coupled - * (2 channel) streams. - * This must be no larger than the total - * number of streams. - * Additionally, The total number of - * coded channels (streams + - * coupled_streams) must be no - * more than 255. - * @param[in] mapping const unsigned char[channels]: Mapping from - * coded channels to output channels, as described in - * @ref opus_multistream. - * @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes) - * on failure. - */ -OPUS_EXPORT int opus_multistream_decoder_init( - OpusMSDecoder *st, - opus_int32 Fs, - int channels, - int streams, - int coupled_streams, - const unsigned char *mapping -) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6); - -/** Decode a multistream Opus packet. - * @param st OpusMSDecoder*: Multistream decoder state. - * @param[in] data const unsigned char*: Input payload. - * Use a NULL - * pointer to indicate packet - * loss. - * @param len opus_int32: Number of bytes in payload. - * @param[out] pcm opus_int16*: Output signal, with interleaved - * samples. - * This must contain room for - * frame_size*channels - * samples. - * @param frame_size int: The number of samples per channel of - * available space in \a pcm. - * If this is less than the maximum packet duration - * (120 ms; 5760 for 48kHz), this function will not be capable - * of decoding some packets. In the case of PLC (data==NULL) - * or FEC (decode_fec=1), then frame_size needs to be exactly - * the duration of audio that is missing, otherwise the - * decoder will not be in the optimal state to decode the - * next incoming packet. For the PLC and FEC cases, frame_size - * must be a multiple of 2.5 ms. - * @param decode_fec int: Flag (0 or 1) to request that any in-band - * forward error correction data be decoded. - * If no such data is available, the frame is - * decoded as if it were lost. - * @returns Number of samples decoded on success or a negative error code - * (see @ref opus_errorcodes) on failure. - */ -OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode( - OpusMSDecoder *st, - const unsigned char *data, - opus_int32 len, - opus_int16 *pcm, - int frame_size, - int decode_fec -) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); - -/** Decode a multistream Opus packet with floating point output. - * @param st OpusMSDecoder*: Multistream decoder state. - * @param[in] data const unsigned char*: Input payload. - * Use a NULL - * pointer to indicate packet - * loss. - * @param len opus_int32: Number of bytes in payload. - * @param[out] pcm opus_int16*: Output signal, with interleaved - * samples. - * This must contain room for - * frame_size*channels - * samples. - * @param frame_size int: The number of samples per channel of - * available space in \a pcm. - * If this is less than the maximum packet duration - * (120 ms; 5760 for 48kHz), this function will not be capable - * of decoding some packets. In the case of PLC (data==NULL) - * or FEC (decode_fec=1), then frame_size needs to be exactly - * the duration of audio that is missing, otherwise the - * decoder will not be in the optimal state to decode the - * next incoming packet. For the PLC and FEC cases, frame_size - * must be a multiple of 2.5 ms. - * @param decode_fec int: Flag (0 or 1) to request that any in-band - * forward error correction data be decoded. - * If no such data is available, the frame is - * decoded as if it were lost. - * @returns Number of samples decoded on success or a negative error code - * (see @ref opus_errorcodes) on failure. - */ -OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode_float( - OpusMSDecoder *st, - const unsigned char *data, - opus_int32 len, - float *pcm, - int frame_size, - int decode_fec -) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); - -/** Perform a CTL function on a multistream Opus decoder. - * - * Generally the request and subsequent arguments are generated by a - * convenience macro. - * @param st OpusMSDecoder*: Multistream decoder state. - * @param request This and all remaining parameters should be replaced by one - * of the convenience macros in @ref opus_genericctls, - * @ref opus_decoderctls, or @ref opus_multistream_ctls. - * @see opus_genericctls - * @see opus_decoderctls - * @see opus_multistream_ctls - */ -OPUS_EXPORT int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...) OPUS_ARG_NONNULL(1); - -/** Frees an OpusMSDecoder allocated by - * opus_multistream_decoder_create(). - * @param st OpusMSDecoder: Multistream decoder state to be freed. - */ -OPUS_EXPORT void opus_multistream_decoder_destroy(OpusMSDecoder *st); - -/**@}*/ - -/**@}*/ - -#ifdef __cplusplus -} -#endif - -#endif /* OPUS_MULTISTREAM_H */ diff --git a/src/opus-1.0.2/include/opus_types.h b/src/opus-1.0.2/include/opus_types.h deleted file mode 100644 index b28e03ae..00000000 --- a/src/opus-1.0.2/include/opus_types.h +++ /dev/null @@ -1,159 +0,0 @@ -/* (C) COPYRIGHT 1994-2002 Xiph.Org Foundation */ -/* Modified by Jean-Marc Valin */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -/* opus_types.h based on ogg_types.h from libogg */ - -/** - @file opus_types.h - @brief Opus reference implementation types -*/ -#ifndef OPUS_TYPES_H -#define OPUS_TYPES_H - -/* Use the real stdint.h if it's there (taken from Paul Hsieh's pstdint.h) */ -#if (defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_)) || defined (HAVE_STDINT_H)) -#include - - typedef int16_t opus_int16; - typedef uint16_t opus_uint16; - typedef int32_t opus_int32; - typedef uint32_t opus_uint32; -#elif defined(_WIN32) - -# if defined(__CYGWIN__) -# include <_G_config.h> - typedef _G_int32_t opus_int32; - typedef _G_uint32_t opus_uint32; - typedef _G_int16 opus_int16; - typedef _G_uint16 opus_uint16; -# elif defined(__MINGW32__) - typedef short opus_int16; - typedef unsigned short opus_uint16; - typedef int opus_int32; - typedef unsigned int opus_uint32; -# elif defined(__MWERKS__) - typedef int opus_int32; - typedef unsigned int opus_uint32; - typedef short opus_int16; - typedef unsigned short opus_uint16; -# else - /* MSVC/Borland */ - typedef __int32 opus_int32; - typedef unsigned __int32 opus_uint32; - typedef __int16 opus_int16; - typedef unsigned __int16 opus_uint16; -# endif - -#elif defined(__MACOS__) - -# include - typedef SInt16 opus_int16; - typedef UInt16 opus_uint16; - typedef SInt32 opus_int32; - typedef UInt32 opus_uint32; - -#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */ - -# include - typedef int16_t opus_int16; - typedef u_int16_t opus_uint16; - typedef int32_t opus_int32; - typedef u_int32_t opus_uint32; - -#elif defined(__BEOS__) - - /* Be */ -# include - typedef int16 opus_int16; - typedef u_int16 opus_uint16; - typedef int32_t opus_int32; - typedef u_int32_t opus_uint32; - -#elif defined (__EMX__) - - /* OS/2 GCC */ - typedef short opus_int16; - typedef unsigned short opus_uint16; - typedef int opus_int32; - typedef unsigned int opus_uint32; - -#elif defined (DJGPP) - - /* DJGPP */ - typedef short opus_int16; - typedef unsigned short opus_uint16; - typedef int opus_int32; - typedef unsigned int opus_uint32; - -#elif defined(R5900) - - /* PS2 EE */ - typedef int opus_int32; - typedef unsigned opus_uint32; - typedef short opus_int16; - typedef unsigned short opus_uint16; - -#elif defined(__SYMBIAN32__) - - /* Symbian GCC */ - typedef signed short opus_int16; - typedef unsigned short opus_uint16; - typedef signed int opus_int32; - typedef unsigned int opus_uint32; - -#elif defined(CONFIG_TI_C54X) || defined (CONFIG_TI_C55X) - - typedef short opus_int16; - typedef unsigned short opus_uint16; - typedef long opus_int32; - typedef unsigned long opus_uint32; - -#elif defined(CONFIG_TI_C6X) - - typedef short opus_int16; - typedef unsigned short opus_uint16; - typedef int opus_int32; - typedef unsigned int opus_uint32; - -#else - - /* Give up, take a reasonable guess */ - typedef short opus_int16; - typedef unsigned short opus_uint16; - typedef int opus_int32; - typedef unsigned int opus_uint32; - -#endif - -#define opus_int int /* used for counters etc; at least 16 bits */ -#define opus_int64 long long -#define opus_int8 signed char - -#define opus_uint unsigned int /* used for counters etc; at least 16 bits */ -#define opus_uint64 unsigned long long -#define opus_uint8 unsigned char - -#endif /* OPUS_TYPES_H */ diff --git a/src/opus-1.0.2/silk/A2NLSF.c b/src/opus-1.0.2/silk/A2NLSF.c deleted file mode 100644 index 49d5d9d9..00000000 --- a/src/opus-1.0.2/silk/A2NLSF.c +++ /dev/null @@ -1,252 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -/* Conversion between prediction filter coefficients and NLSFs */ -/* Requires the order to be an even number */ -/* A piecewise linear approximation maps LSF <-> cos(LSF) */ -/* Therefore the result is not accurate NLSFs, but the two */ -/* functions are accurate inverses of each other */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "SigProc_FIX.h" -#include "tables.h" - -/* Number of binary divisions, when not in low complexity mode */ -#define BIN_DIV_STEPS_A2NLSF_FIX 3 /* must be no higher than 16 - log2( LSF_COS_TAB_SZ_FIX ) */ -#define MAX_ITERATIONS_A2NLSF_FIX 30 - -/* Helper function for A2NLSF(..) */ -/* Transforms polynomials from cos(n*f) to cos(f)^n */ -static inline void silk_A2NLSF_trans_poly( - opus_int32 *p, /* I/O Polynomial */ - const opus_int dd /* I Polynomial order (= filter order / 2 ) */ -) -{ - opus_int k, n; - - for( k = 2; k <= dd; k++ ) { - for( n = dd; n > k; n-- ) { - p[ n - 2 ] -= p[ n ]; - } - p[ k - 2 ] -= silk_LSHIFT( p[ k ], 1 ); - } -} -/* Helper function for A2NLSF(..) */ -/* Polynomial evaluation */ -static inline opus_int32 silk_A2NLSF_eval_poly( /* return the polynomial evaluation, in Q16 */ - opus_int32 *p, /* I Polynomial, Q16 */ - const opus_int32 x, /* I Evaluation point, Q12 */ - const opus_int dd /* I Order */ -) -{ - opus_int n; - opus_int32 x_Q16, y32; - - y32 = p[ dd ]; /* Q16 */ - x_Q16 = silk_LSHIFT( x, 4 ); - for( n = dd - 1; n >= 0; n-- ) { - y32 = silk_SMLAWW( p[ n ], y32, x_Q16 ); /* Q16 */ - } - return y32; -} - -static inline void silk_A2NLSF_init( - const opus_int32 *a_Q16, - opus_int32 *P, - opus_int32 *Q, - const opus_int dd -) -{ - opus_int k; - - /* Convert filter coefs to even and odd polynomials */ - P[dd] = silk_LSHIFT( 1, 16 ); - Q[dd] = silk_LSHIFT( 1, 16 ); - for( k = 0; k < dd; k++ ) { - P[ k ] = -a_Q16[ dd - k - 1 ] - a_Q16[ dd + k ]; /* Q16 */ - Q[ k ] = -a_Q16[ dd - k - 1 ] + a_Q16[ dd + k ]; /* Q16 */ - } - - /* Divide out zeros as we have that for even filter orders, */ - /* z = 1 is always a root in Q, and */ - /* z = -1 is always a root in P */ - for( k = dd; k > 0; k-- ) { - P[ k - 1 ] -= P[ k ]; - Q[ k - 1 ] += Q[ k ]; - } - - /* Transform polynomials from cos(n*f) to cos(f)^n */ - silk_A2NLSF_trans_poly( P, dd ); - silk_A2NLSF_trans_poly( Q, dd ); -} - -/* Compute Normalized Line Spectral Frequencies (NLSFs) from whitening filter coefficients */ -/* If not all roots are found, the a_Q16 coefficients are bandwidth expanded until convergence. */ -void silk_A2NLSF( - opus_int16 *NLSF, /* O Normalized Line Spectral Frequencies in Q15 (0..2^15-1) [d] */ - opus_int32 *a_Q16, /* I/O Monic whitening filter coefficients in Q16 [d] */ - const opus_int d /* I Filter order (must be even) */ -) -{ - opus_int i, k, m, dd, root_ix, ffrac; - opus_int32 xlo, xhi, xmid; - opus_int32 ylo, yhi, ymid, thr; - opus_int32 nom, den; - opus_int32 P[ SILK_MAX_ORDER_LPC / 2 + 1 ]; - opus_int32 Q[ SILK_MAX_ORDER_LPC / 2 + 1 ]; - opus_int32 *PQ[ 2 ]; - opus_int32 *p; - - /* Store pointers to array */ - PQ[ 0 ] = P; - PQ[ 1 ] = Q; - - dd = silk_RSHIFT( d, 1 ); - - silk_A2NLSF_init( a_Q16, P, Q, dd ); - - /* Find roots, alternating between P and Q */ - p = P; /* Pointer to polynomial */ - - xlo = silk_LSFCosTab_FIX_Q12[ 0 ]; /* Q12*/ - ylo = silk_A2NLSF_eval_poly( p, xlo, dd ); - - if( ylo < 0 ) { - /* Set the first NLSF to zero and move on to the next */ - NLSF[ 0 ] = 0; - p = Q; /* Pointer to polynomial */ - ylo = silk_A2NLSF_eval_poly( p, xlo, dd ); - root_ix = 1; /* Index of current root */ - } else { - root_ix = 0; /* Index of current root */ - } - k = 1; /* Loop counter */ - i = 0; /* Counter for bandwidth expansions applied */ - thr = 0; - while( 1 ) { - /* Evaluate polynomial */ - xhi = silk_LSFCosTab_FIX_Q12[ k ]; /* Q12 */ - yhi = silk_A2NLSF_eval_poly( p, xhi, dd ); - - /* Detect zero crossing */ - if( ( ylo <= 0 && yhi >= thr ) || ( ylo >= 0 && yhi <= -thr ) ) { - if( yhi == 0 ) { - /* If the root lies exactly at the end of the current */ - /* interval, look for the next root in the next interval */ - thr = 1; - } else { - thr = 0; - } - /* Binary division */ - ffrac = -256; - for( m = 0; m < BIN_DIV_STEPS_A2NLSF_FIX; m++ ) { - /* Evaluate polynomial */ - xmid = silk_RSHIFT_ROUND( xlo + xhi, 1 ); - ymid = silk_A2NLSF_eval_poly( p, xmid, dd ); - - /* Detect zero crossing */ - if( ( ylo <= 0 && ymid >= 0 ) || ( ylo >= 0 && ymid <= 0 ) ) { - /* Reduce frequency */ - xhi = xmid; - yhi = ymid; - } else { - /* Increase frequency */ - xlo = xmid; - ylo = ymid; - ffrac = silk_ADD_RSHIFT( ffrac, 128, m ); - } - } - - /* Interpolate */ - if( silk_abs( ylo ) < 65536 ) { - /* Avoid dividing by zero */ - den = ylo - yhi; - nom = silk_LSHIFT( ylo, 8 - BIN_DIV_STEPS_A2NLSF_FIX ) + silk_RSHIFT( den, 1 ); - if( den != 0 ) { - ffrac += silk_DIV32( nom, den ); - } - } else { - /* No risk of dividing by zero because abs(ylo - yhi) >= abs(ylo) >= 65536 */ - ffrac += silk_DIV32( ylo, silk_RSHIFT( ylo - yhi, 8 - BIN_DIV_STEPS_A2NLSF_FIX ) ); - } - NLSF[ root_ix ] = (opus_int16)silk_min_32( silk_LSHIFT( (opus_int32)k, 8 ) + ffrac, silk_int16_MAX ); - - silk_assert( NLSF[ root_ix ] >= 0 ); - - root_ix++; /* Next root */ - if( root_ix >= d ) { - /* Found all roots */ - break; - } - /* Alternate pointer to polynomial */ - p = PQ[ root_ix & 1 ]; - - /* Evaluate polynomial */ - xlo = silk_LSFCosTab_FIX_Q12[ k - 1 ]; /* Q12*/ - ylo = silk_LSHIFT( 1 - ( root_ix & 2 ), 12 ); - } else { - /* Increment loop counter */ - k++; - xlo = xhi; - ylo = yhi; - thr = 0; - - if( k > LSF_COS_TAB_SZ_FIX ) { - i++; - if( i > MAX_ITERATIONS_A2NLSF_FIX ) { - /* Set NLSFs to white spectrum and exit */ - NLSF[ 0 ] = (opus_int16)silk_DIV32_16( 1 << 15, d + 1 ); - for( k = 1; k < d; k++ ) { - NLSF[ k ] = (opus_int16)silk_SMULBB( k + 1, NLSF[ 0 ] ); - } - return; - } - - /* Error: Apply progressively more bandwidth expansion and run again */ - silk_bwexpander_32( a_Q16, d, 65536 - silk_SMULBB( 10 + i, i ) ); /* 10_Q16 = 0.00015*/ - - silk_A2NLSF_init( a_Q16, P, Q, dd ); - p = P; /* Pointer to polynomial */ - xlo = silk_LSFCosTab_FIX_Q12[ 0 ]; /* Q12*/ - ylo = silk_A2NLSF_eval_poly( p, xlo, dd ); - if( ylo < 0 ) { - /* Set the first NLSF to zero and move on to the next */ - NLSF[ 0 ] = 0; - p = Q; /* Pointer to polynomial */ - ylo = silk_A2NLSF_eval_poly( p, xlo, dd ); - root_ix = 1; /* Index of current root */ - } else { - root_ix = 0; /* Index of current root */ - } - k = 1; /* Reset loop counter */ - } - } - } -} diff --git a/src/opus-1.0.2/silk/API.h b/src/opus-1.0.2/silk/API.h deleted file mode 100644 index 4b8ca12a..00000000 --- a/src/opus-1.0.2/silk/API.h +++ /dev/null @@ -1,132 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifndef SILK_API_H -#define SILK_API_H - -#include "control.h" -#include "typedef.h" -#include "errors.h" -#include "entenc.h" -#include "entdec.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -#define SILK_MAX_FRAMES_PER_PACKET 3 - -/* Struct for TOC (Table of Contents) */ -typedef struct { - opus_int VADFlag; /* Voice activity for packet */ - opus_int VADFlags[ SILK_MAX_FRAMES_PER_PACKET ]; /* Voice activity for each frame in packet */ - opus_int inbandFECFlag; /* Flag indicating if packet contains in-band FEC */ -} silk_TOC_struct; - -/****************************************/ -/* Encoder functions */ -/****************************************/ - -/***********************************************/ -/* Get size in bytes of the Silk encoder state */ -/***********************************************/ -opus_int silk_Get_Encoder_Size( /* O Returns error code */ - opus_int *encSizeBytes /* O Number of bytes in SILK encoder state */ -); - -/*************************/ -/* Init or reset encoder */ -/*************************/ -opus_int silk_InitEncoder( /* O Returns error code */ - void *encState, /* I/O State */ - silk_EncControlStruct *encStatus /* O Encoder Status */ -); - -/**************************/ -/* Encode frame with Silk */ -/**************************/ -/* Note: if prefillFlag is set, the input must contain 10 ms of audio, irrespective of what */ -/* encControl->payloadSize_ms is set to */ -opus_int silk_Encode( /* O Returns error code */ - void *encState, /* I/O State */ - silk_EncControlStruct *encControl, /* I Control status */ - const opus_int16 *samplesIn, /* I Speech sample input vector */ - opus_int nSamplesIn, /* I Number of samples in input vector */ - ec_enc *psRangeEnc, /* I/O Compressor data structure */ - opus_int32 *nBytesOut, /* I/O Number of bytes in payload (input: Max bytes) */ - const opus_int prefillFlag /* I Flag to indicate prefilling buffers no coding */ -); - -/****************************************/ -/* Decoder functions */ -/****************************************/ - -/***********************************************/ -/* Get size in bytes of the Silk decoder state */ -/***********************************************/ -opus_int silk_Get_Decoder_Size( /* O Returns error code */ - opus_int *decSizeBytes /* O Number of bytes in SILK decoder state */ -); - -/*************************/ -/* Init or Reset decoder */ -/*************************/ -opus_int silk_InitDecoder( /* O Returns error code */ - void *decState /* I/O State */ -); - -/******************/ -/* Decode a frame */ -/******************/ -opus_int silk_Decode( /* O Returns error code */ - void* decState, /* I/O State */ - silk_DecControlStruct* decControl, /* I/O Control Structure */ - opus_int lostFlag, /* I 0: no loss, 1 loss, 2 decode fec */ - opus_int newPacketFlag, /* I Indicates first decoder call for this packet */ - ec_dec *psRangeDec, /* I/O Compressor data structure */ - opus_int16 *samplesOut, /* O Decoded output speech vector */ - opus_int32 *nSamplesOut /* O Number of samples decoded */ -); - -#if 0 -/**************************************/ -/* Get table of contents for a packet */ -/**************************************/ -opus_int silk_get_TOC( - const opus_uint8 *payload, /* I Payload data */ - const opus_int nBytesIn, /* I Number of input bytes */ - const opus_int nFramesPerPayload, /* I Number of SILK frames per payload */ - silk_TOC_struct *Silk_TOC /* O Type of content */ -); -#endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/opus-1.0.2/silk/CNG.c b/src/opus-1.0.2/silk/CNG.c deleted file mode 100644 index d0a619c1..00000000 --- a/src/opus-1.0.2/silk/CNG.c +++ /dev/null @@ -1,167 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main.h" - -/* Generates excitation for CNG LPC synthesis */ -static inline void silk_CNG_exc( - opus_int32 residual_Q10[], /* O CNG residual signal Q10 */ - opus_int32 exc_buf_Q14[], /* I Random samples buffer Q10 */ - opus_int32 Gain_Q16, /* I Gain to apply */ - opus_int length, /* I Length */ - opus_int32 *rand_seed /* I/O Seed to random index generator */ -) -{ - opus_int32 seed; - opus_int i, idx, exc_mask; - - exc_mask = CNG_BUF_MASK_MAX; - while( exc_mask > length ) { - exc_mask = silk_RSHIFT( exc_mask, 1 ); - } - - seed = *rand_seed; - for( i = 0; i < length; i++ ) { - seed = silk_RAND( seed ); - idx = (opus_int)( silk_RSHIFT( seed, 24 ) & exc_mask ); - silk_assert( idx >= 0 ); - silk_assert( idx <= CNG_BUF_MASK_MAX ); - residual_Q10[ i ] = (opus_int16)silk_SAT16( silk_SMULWW( exc_buf_Q14[ idx ], Gain_Q16 >> 4 ) ); - } - *rand_seed = seed; -} - -void silk_CNG_Reset( - silk_decoder_state *psDec /* I/O Decoder state */ -) -{ - opus_int i, NLSF_step_Q15, NLSF_acc_Q15; - - NLSF_step_Q15 = silk_DIV32_16( silk_int16_MAX, psDec->LPC_order + 1 ); - NLSF_acc_Q15 = 0; - for( i = 0; i < psDec->LPC_order; i++ ) { - NLSF_acc_Q15 += NLSF_step_Q15; - psDec->sCNG.CNG_smth_NLSF_Q15[ i ] = NLSF_acc_Q15; - } - psDec->sCNG.CNG_smth_Gain_Q16 = 0; - psDec->sCNG.rand_seed = 3176576; -} - -/* Updates CNG estimate, and applies the CNG when packet was lost */ -void silk_CNG( - silk_decoder_state *psDec, /* I/O Decoder state */ - silk_decoder_control *psDecCtrl, /* I/O Decoder control */ - opus_int16 frame[], /* I/O Signal */ - opus_int length /* I Length of residual */ -) -{ - opus_int i, subfr; - opus_int32 sum_Q6, max_Gain_Q16; - opus_int16 A_Q12[ MAX_LPC_ORDER ]; - opus_int32 CNG_sig_Q10[ MAX_FRAME_LENGTH + MAX_LPC_ORDER ]; - silk_CNG_struct *psCNG = &psDec->sCNG; - - if( psDec->fs_kHz != psCNG->fs_kHz ) { - /* Reset state */ - silk_CNG_Reset( psDec ); - - psCNG->fs_kHz = psDec->fs_kHz; - } - if( psDec->lossCnt == 0 && psDec->prevSignalType == TYPE_NO_VOICE_ACTIVITY ) { - /* Update CNG parameters */ - - /* Smoothing of LSF's */ - for( i = 0; i < psDec->LPC_order; i++ ) { - psCNG->CNG_smth_NLSF_Q15[ i ] += silk_SMULWB( (opus_int32)psDec->prevNLSF_Q15[ i ] - (opus_int32)psCNG->CNG_smth_NLSF_Q15[ i ], CNG_NLSF_SMTH_Q16 ); - } - /* Find the subframe with the highest gain */ - max_Gain_Q16 = 0; - subfr = 0; - for( i = 0; i < psDec->nb_subfr; i++ ) { - if( psDecCtrl->Gains_Q16[ i ] > max_Gain_Q16 ) { - max_Gain_Q16 = psDecCtrl->Gains_Q16[ i ]; - subfr = i; - } - } - /* Update CNG excitation buffer with excitation from this subframe */ - silk_memmove( &psCNG->CNG_exc_buf_Q14[ psDec->subfr_length ], psCNG->CNG_exc_buf_Q14, ( psDec->nb_subfr - 1 ) * psDec->subfr_length * sizeof( opus_int32 ) ); - silk_memcpy( psCNG->CNG_exc_buf_Q14, &psDec->exc_Q14[ subfr * psDec->subfr_length ], psDec->subfr_length * sizeof( opus_int32 ) ); - - /* Smooth gains */ - for( i = 0; i < psDec->nb_subfr; i++ ) { - psCNG->CNG_smth_Gain_Q16 += silk_SMULWB( psDecCtrl->Gains_Q16[ i ] - psCNG->CNG_smth_Gain_Q16, CNG_GAIN_SMTH_Q16 ); - } - } - - /* Add CNG when packet is lost or during DTX */ - if( psDec->lossCnt ) { - - /* Generate CNG excitation */ - silk_CNG_exc( CNG_sig_Q10 + MAX_LPC_ORDER, psCNG->CNG_exc_buf_Q14, psCNG->CNG_smth_Gain_Q16, length, &psCNG->rand_seed ); - - /* Convert CNG NLSF to filter representation */ - silk_NLSF2A( A_Q12, psCNG->CNG_smth_NLSF_Q15, psDec->LPC_order ); - - /* Generate CNG signal, by synthesis filtering */ - silk_memcpy( CNG_sig_Q10, psCNG->CNG_synth_state, MAX_LPC_ORDER * sizeof( opus_int32 ) ); - for( i = 0; i < length; i++ ) { - silk_assert( psDec->LPC_order == 10 || psDec->LPC_order == 16 ); - /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ - sum_Q6 = silk_RSHIFT( psDec->LPC_order, 1 ); - sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 1 ], A_Q12[ 0 ] ); - sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 2 ], A_Q12[ 1 ] ); - sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 3 ], A_Q12[ 2 ] ); - sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 4 ], A_Q12[ 3 ] ); - sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 5 ], A_Q12[ 4 ] ); - sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 6 ], A_Q12[ 5 ] ); - sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 7 ], A_Q12[ 6 ] ); - sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 8 ], A_Q12[ 7 ] ); - sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 9 ], A_Q12[ 8 ] ); - sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 10 ], A_Q12[ 9 ] ); - if( psDec->LPC_order == 16 ) { - sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 11 ], A_Q12[ 10 ] ); - sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 12 ], A_Q12[ 11 ] ); - sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 13 ], A_Q12[ 12 ] ); - sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 14 ], A_Q12[ 13 ] ); - sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 15 ], A_Q12[ 14 ] ); - sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 16 ], A_Q12[ 15 ] ); - } - - /* Update states */ - CNG_sig_Q10[ MAX_LPC_ORDER + i ] = silk_ADD_LSHIFT( CNG_sig_Q10[ MAX_LPC_ORDER + i ], sum_Q6, 4 ); - - frame[ i ] = silk_ADD_SAT16( frame[ i ], silk_RSHIFT_ROUND( sum_Q6, 6 ) ); - } - silk_memcpy( psCNG->CNG_synth_state, &CNG_sig_Q10[ length ], MAX_LPC_ORDER * sizeof( opus_int32 ) ); - } else { - silk_memset( psCNG->CNG_synth_state, 0, psDec->LPC_order * sizeof( opus_int32 ) ); - } -} diff --git a/src/opus-1.0.2/silk/HP_variable_cutoff.c b/src/opus-1.0.2/silk/HP_variable_cutoff.c deleted file mode 100644 index 199dbb34..00000000 --- a/src/opus-1.0.2/silk/HP_variable_cutoff.c +++ /dev/null @@ -1,77 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#ifdef FIXED_POINT -#include "main_FIX.h" -#else -#include "main_FLP.h" -#endif -#include "tuning_parameters.h" - -/* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */ -void silk_HP_variable_cutoff( - silk_encoder_state_Fxx state_Fxx[] /* I/O Encoder states */ -) -{ - opus_int quality_Q15; - opus_int32 pitch_freq_Hz_Q16, pitch_freq_log_Q7, delta_freq_Q7; - silk_encoder_state *psEncC1 = &state_Fxx[ 0 ].sCmn; - - /* Adaptive cutoff frequency: estimate low end of pitch frequency range */ - if( psEncC1->prevSignalType == TYPE_VOICED ) { - /* difference, in log domain */ - pitch_freq_Hz_Q16 = silk_DIV32_16( silk_LSHIFT( silk_MUL( psEncC1->fs_kHz, 1000 ), 16 ), psEncC1->prevLag ); - pitch_freq_log_Q7 = silk_lin2log( pitch_freq_Hz_Q16 ) - ( 16 << 7 ); - - /* adjustment based on quality */ - quality_Q15 = psEncC1->input_quality_bands_Q15[ 0 ]; - pitch_freq_log_Q7 = silk_SMLAWB( pitch_freq_log_Q7, silk_SMULWB( silk_LSHIFT( -quality_Q15, 2 ), quality_Q15 ), - pitch_freq_log_Q7 - ( silk_lin2log( SILK_FIX_CONST( VARIABLE_HP_MIN_CUTOFF_HZ, 16 ) ) - ( 16 << 7 ) ) ); - - /* delta_freq = pitch_freq_log - psEnc->variable_HP_smth1; */ - delta_freq_Q7 = pitch_freq_log_Q7 - silk_RSHIFT( psEncC1->variable_HP_smth1_Q15, 8 ); - if( delta_freq_Q7 < 0 ) { - /* less smoothing for decreasing pitch frequency, to track something close to the minimum */ - delta_freq_Q7 = silk_MUL( delta_freq_Q7, 3 ); - } - - /* limit delta, to reduce impact of outliers in pitch estimation */ - delta_freq_Q7 = silk_LIMIT_32( delta_freq_Q7, -SILK_FIX_CONST( VARIABLE_HP_MAX_DELTA_FREQ, 7 ), SILK_FIX_CONST( VARIABLE_HP_MAX_DELTA_FREQ, 7 ) ); - - /* update smoother */ - psEncC1->variable_HP_smth1_Q15 = silk_SMLAWB( psEncC1->variable_HP_smth1_Q15, - silk_SMULBB( psEncC1->speech_activity_Q8, delta_freq_Q7 ), SILK_FIX_CONST( VARIABLE_HP_SMTH_COEF1, 16 ) ); - - /* limit frequency range */ - psEncC1->variable_HP_smth1_Q15 = silk_LIMIT_32( psEncC1->variable_HP_smth1_Q15, - silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 ), - silk_LSHIFT( silk_lin2log( VARIABLE_HP_MAX_CUTOFF_HZ ), 8 ) ); - } -} diff --git a/src/opus-1.0.2/silk/Inlines.h b/src/opus-1.0.2/silk/Inlines.h deleted file mode 100644 index 87ac2e20..00000000 --- a/src/opus-1.0.2/silk/Inlines.h +++ /dev/null @@ -1,188 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -/*! \file silk_Inlines.h - * \brief silk_Inlines.h defines inline signal processing functions. - */ - -#ifndef SILK_FIX_INLINES_H -#define SILK_FIX_INLINES_H - -#ifdef __cplusplus -extern "C" -{ -#endif - -/* count leading zeros of opus_int64 */ -static inline opus_int32 silk_CLZ64( opus_int64 in ) -{ - opus_int32 in_upper; - - in_upper = (opus_int32)silk_RSHIFT64(in, 32); - if (in_upper == 0) { - /* Search in the lower 32 bits */ - return 32 + silk_CLZ32( (opus_int32) in ); - } else { - /* Search in the upper 32 bits */ - return silk_CLZ32( in_upper ); - } -} - -/* get number of leading zeros and fractional part (the bits right after the leading one */ -static inline void silk_CLZ_FRAC( - opus_int32 in, /* I input */ - opus_int32 *lz, /* O number of leading zeros */ - opus_int32 *frac_Q7 /* O the 7 bits right after the leading one */ -) -{ - opus_int32 lzeros = silk_CLZ32(in); - - * lz = lzeros; - * frac_Q7 = silk_ROR32(in, 24 - lzeros) & 0x7f; -} - -/* Approximation of square root */ -/* Accuracy: < +/- 10% for output values > 15 */ -/* < +/- 2.5% for output values > 120 */ -static inline opus_int32 silk_SQRT_APPROX( opus_int32 x ) -{ - opus_int32 y, lz, frac_Q7; - - if( x <= 0 ) { - return 0; - } - - silk_CLZ_FRAC(x, &lz, &frac_Q7); - - if( lz & 1 ) { - y = 32768; - } else { - y = 46214; /* 46214 = sqrt(2) * 32768 */ - } - - /* get scaling right */ - y >>= silk_RSHIFT(lz, 1); - - /* increment using fractional part of input */ - y = silk_SMLAWB(y, y, silk_SMULBB(213, frac_Q7)); - - return y; -} - -/* Divide two int32 values and return result as int32 in a given Q-domain */ -static inline opus_int32 silk_DIV32_varQ( /* O returns a good approximation of "(a32 << Qres) / b32" */ - const opus_int32 a32, /* I numerator (Q0) */ - const opus_int32 b32, /* I denominator (Q0) */ - const opus_int Qres /* I Q-domain of result (>= 0) */ -) -{ - opus_int a_headrm, b_headrm, lshift; - opus_int32 b32_inv, a32_nrm, b32_nrm, result; - - silk_assert( b32 != 0 ); - silk_assert( Qres >= 0 ); - - /* Compute number of bits head room and normalize inputs */ - a_headrm = silk_CLZ32( silk_abs(a32) ) - 1; - a32_nrm = silk_LSHIFT(a32, a_headrm); /* Q: a_headrm */ - b_headrm = silk_CLZ32( silk_abs(b32) ) - 1; - b32_nrm = silk_LSHIFT(b32, b_headrm); /* Q: b_headrm */ - - /* Inverse of b32, with 14 bits of precision */ - b32_inv = silk_DIV32_16( silk_int32_MAX >> 2, silk_RSHIFT(b32_nrm, 16) ); /* Q: 29 + 16 - b_headrm */ - - /* First approximation */ - result = silk_SMULWB(a32_nrm, b32_inv); /* Q: 29 + a_headrm - b_headrm */ - - /* Compute residual by subtracting product of denominator and first approximation */ - /* It's OK to overflow because the final value of a32_nrm should always be small */ - a32_nrm = silk_SUB32_ovflw(a32_nrm, silk_LSHIFT_ovflw( silk_SMMUL(b32_nrm, result), 3 )); /* Q: a_headrm */ - - /* Refinement */ - result = silk_SMLAWB(result, a32_nrm, b32_inv); /* Q: 29 + a_headrm - b_headrm */ - - /* Convert to Qres domain */ - lshift = 29 + a_headrm - b_headrm - Qres; - if( lshift < 0 ) { - return silk_LSHIFT_SAT32(result, -lshift); - } else { - if( lshift < 32){ - return silk_RSHIFT(result, lshift); - } else { - /* Avoid undefined result */ - return 0; - } - } -} - -/* Invert int32 value and return result as int32 in a given Q-domain */ -static inline opus_int32 silk_INVERSE32_varQ( /* O returns a good approximation of "(1 << Qres) / b32" */ - const opus_int32 b32, /* I denominator (Q0) */ - const opus_int Qres /* I Q-domain of result (> 0) */ -) -{ - opus_int b_headrm, lshift; - opus_int32 b32_inv, b32_nrm, err_Q32, result; - - silk_assert( b32 != 0 ); - silk_assert( Qres > 0 ); - - /* Compute number of bits head room and normalize input */ - b_headrm = silk_CLZ32( silk_abs(b32) ) - 1; - b32_nrm = silk_LSHIFT(b32, b_headrm); /* Q: b_headrm */ - - /* Inverse of b32, with 14 bits of precision */ - b32_inv = silk_DIV32_16( silk_int32_MAX >> 2, silk_RSHIFT(b32_nrm, 16) ); /* Q: 29 + 16 - b_headrm */ - - /* First approximation */ - result = silk_LSHIFT(b32_inv, 16); /* Q: 61 - b_headrm */ - - /* Compute residual by subtracting product of denominator and first approximation from one */ - err_Q32 = silk_LSHIFT( ((opus_int32)1<<29) - silk_SMULWB(b32_nrm, b32_inv), 3 ); /* Q32 */ - - /* Refinement */ - result = silk_SMLAWW(result, err_Q32, b32_inv); /* Q: 61 - b_headrm */ - - /* Convert to Qres domain */ - lshift = 61 - b_headrm - Qres; - if( lshift <= 0 ) { - return silk_LSHIFT_SAT32(result, -lshift); - } else { - if( lshift < 32){ - return silk_RSHIFT(result, lshift); - }else{ - /* Avoid undefined result */ - return 0; - } - } -} - -#ifdef __cplusplus -} -#endif - -#endif /* SILK_FIX_INLINES_H */ diff --git a/src/opus-1.0.2/silk/LPC_analysis_filter.c b/src/opus-1.0.2/silk/LPC_analysis_filter.c deleted file mode 100644 index 421dba0b..00000000 --- a/src/opus-1.0.2/silk/LPC_analysis_filter.c +++ /dev/null @@ -1,85 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "SigProc_FIX.h" - -/*******************************************/ -/* LPC analysis filter */ -/* NB! State is kept internally and the */ -/* filter always starts with zero state */ -/* first d output samples are set to zero */ -/*******************************************/ - -void silk_LPC_analysis_filter( - opus_int16 *out, /* O Output signal */ - const opus_int16 *in, /* I Input signal */ - const opus_int16 *B, /* I MA prediction coefficients, Q12 [order] */ - const opus_int32 len, /* I Signal length */ - const opus_int32 d /* I Filter order */ -) -{ - opus_int ix, j; - opus_int32 out32_Q12, out32; - const opus_int16 *in_ptr; - - silk_assert( d >= 6 ); - silk_assert( (d & 1) == 0 ); - silk_assert( d <= len ); - - for( ix = d; ix < len; ix++ ) { - in_ptr = &in[ ix - 1 ]; - - out32_Q12 = silk_SMULBB( in_ptr[ 0 ], B[ 0 ] ); - /* Allowing wrap around so that two wraps can cancel each other. The rare - cases where the result wraps around can only be triggered by invalid streams*/ - out32_Q12 = silk_SMLABB_ovflw( out32_Q12, in_ptr[ -1 ], B[ 1 ] ); - out32_Q12 = silk_SMLABB_ovflw( out32_Q12, in_ptr[ -2 ], B[ 2 ] ); - out32_Q12 = silk_SMLABB_ovflw( out32_Q12, in_ptr[ -3 ], B[ 3 ] ); - out32_Q12 = silk_SMLABB_ovflw( out32_Q12, in_ptr[ -4 ], B[ 4 ] ); - out32_Q12 = silk_SMLABB_ovflw( out32_Q12, in_ptr[ -5 ], B[ 5 ] ); - for( j = 6; j < d; j += 2 ) { - out32_Q12 = silk_SMLABB_ovflw( out32_Q12, in_ptr[ -j ], B[ j ] ); - out32_Q12 = silk_SMLABB_ovflw( out32_Q12, in_ptr[ -j - 1 ], B[ j + 1 ] ); - } - - /* Subtract prediction */ - out32_Q12 = silk_SUB32_ovflw( silk_LSHIFT( (opus_int32)in_ptr[ 1 ], 12 ), out32_Q12 ); - - /* Scale to Q0 */ - out32 = silk_RSHIFT_ROUND( out32_Q12, 12 ); - - /* Saturate output */ - out[ ix ] = (opus_int16)silk_SAT16( out32 ); - } - - /* Set first d output samples to zero */ - silk_memset( out, 0, d * sizeof( opus_int16 ) ); -} diff --git a/src/opus-1.0.2/silk/LPC_inv_pred_gain.c b/src/opus-1.0.2/silk/LPC_inv_pred_gain.c deleted file mode 100644 index c36f3422..00000000 --- a/src/opus-1.0.2/silk/LPC_inv_pred_gain.c +++ /dev/null @@ -1,154 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "SigProc_FIX.h" - -#define QA 24 -#define A_LIMIT SILK_FIX_CONST( 0.99975, QA ) - -#define MUL32_FRAC_Q(a32, b32, Q) ((opus_int32)(silk_RSHIFT_ROUND64(silk_SMULL(a32, b32), Q))) - -/* Compute inverse of LPC prediction gain, and */ -/* test if LPC coefficients are stable (all poles within unit circle) */ -static opus_int32 LPC_inverse_pred_gain_QA( /* O Returns inverse prediction gain in energy domain, Q30 */ - opus_int32 A_QA[ 2 ][ SILK_MAX_ORDER_LPC ], /* I Prediction coefficients */ - const opus_int order /* I Prediction order */ -) -{ - opus_int k, n, mult2Q; - opus_int32 invGain_Q30, rc_Q31, rc_mult1_Q30, rc_mult2, tmp_QA; - opus_int32 *Aold_QA, *Anew_QA; - - Anew_QA = A_QA[ order & 1 ]; - - invGain_Q30 = (opus_int32)1 << 30; - for( k = order - 1; k > 0; k-- ) { - /* Check for stability */ - if( ( Anew_QA[ k ] > A_LIMIT ) || ( Anew_QA[ k ] < -A_LIMIT ) ) { - return 0; - } - - /* Set RC equal to negated AR coef */ - rc_Q31 = -silk_LSHIFT( Anew_QA[ k ], 31 - QA ); - - /* rc_mult1_Q30 range: [ 1 : 2^30 ] */ - rc_mult1_Q30 = ( (opus_int32)1 << 30 ) - silk_SMMUL( rc_Q31, rc_Q31 ); - silk_assert( rc_mult1_Q30 > ( 1 << 15 ) ); /* reduce A_LIMIT if fails */ - silk_assert( rc_mult1_Q30 <= ( 1 << 30 ) ); - - /* rc_mult2 range: [ 2^30 : silk_int32_MAX ] */ - mult2Q = 32 - silk_CLZ32( silk_abs( rc_mult1_Q30 ) ); - rc_mult2 = silk_INVERSE32_varQ( rc_mult1_Q30, mult2Q + 30 ); - - /* Update inverse gain */ - /* invGain_Q30 range: [ 0 : 2^30 ] */ - invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 ); - silk_assert( invGain_Q30 >= 0 ); - silk_assert( invGain_Q30 <= ( 1 << 30 ) ); - - /* Swap pointers */ - Aold_QA = Anew_QA; - Anew_QA = A_QA[ k & 1 ]; - - /* Update AR coefficient */ - for( n = 0; n < k; n++ ) { - tmp_QA = Aold_QA[ n ] - MUL32_FRAC_Q( Aold_QA[ k - n - 1 ], rc_Q31, 31 ); - Anew_QA[ n ] = MUL32_FRAC_Q( tmp_QA, rc_mult2 , mult2Q ); - } - } - - /* Check for stability */ - if( ( Anew_QA[ 0 ] > A_LIMIT ) || ( Anew_QA[ 0 ] < -A_LIMIT ) ) { - return 0; - } - - /* Set RC equal to negated AR coef */ - rc_Q31 = -silk_LSHIFT( Anew_QA[ 0 ], 31 - QA ); - - /* Range: [ 1 : 2^30 ] */ - rc_mult1_Q30 = ( (opus_int32)1 << 30 ) - silk_SMMUL( rc_Q31, rc_Q31 ); - - /* Update inverse gain */ - /* Range: [ 0 : 2^30 ] */ - invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 ); - silk_assert( invGain_Q30 >= 0 ); - silk_assert( invGain_Q30 <= 1<<30 ); - - return invGain_Q30; -} - -/* For input in Q12 domain */ -opus_int32 silk_LPC_inverse_pred_gain( /* O Returns inverse prediction gain in energy domain, Q30 */ - const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */ - const opus_int order /* I Prediction order */ -) -{ - opus_int k; - opus_int32 Atmp_QA[ 2 ][ SILK_MAX_ORDER_LPC ]; - opus_int32 *Anew_QA; - opus_int32 DC_resp = 0; - - Anew_QA = Atmp_QA[ order & 1 ]; - - /* Increase Q domain of the AR coefficients */ - for( k = 0; k < order; k++ ) { - DC_resp += (opus_int32)A_Q12[ k ]; - Anew_QA[ k ] = silk_LSHIFT32( (opus_int32)A_Q12[ k ], QA - 12 ); - } - /* If the DC is unstable, we don't even need to do the full calculations */ - if( DC_resp >= 4096 ) { - return 0; - } - return LPC_inverse_pred_gain_QA( Atmp_QA, order ); -} - -#ifdef FIXED_POINT - -/* For input in Q24 domain */ -opus_int32 silk_LPC_inverse_pred_gain_Q24( /* O Returns inverse prediction gain in energy domain, Q30 */ - const opus_int32 *A_Q24, /* I Prediction coefficients [order] */ - const opus_int order /* I Prediction order */ -) -{ - opus_int k; - opus_int32 Atmp_QA[ 2 ][ SILK_MAX_ORDER_LPC ]; - opus_int32 *Anew_QA; - - Anew_QA = Atmp_QA[ order & 1 ]; - - /* Increase Q domain of the AR coefficients */ - for( k = 0; k < order; k++ ) { - Anew_QA[ k ] = silk_RSHIFT32( A_Q24[ k ], 24 - QA ); - } - - return LPC_inverse_pred_gain_QA( Atmp_QA, order ); -} -#endif diff --git a/src/opus-1.0.2/silk/LP_variable_cutoff.c b/src/opus-1.0.2/silk/LP_variable_cutoff.c deleted file mode 100644 index d0912a64..00000000 --- a/src/opus-1.0.2/silk/LP_variable_cutoff.c +++ /dev/null @@ -1,135 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* - Elliptic/Cauer filters designed with 0.1 dB passband ripple, - 80 dB minimum stopband attenuation, and - [0.95 : 0.15 : 0.35] normalized cut off frequencies. -*/ - -#include "main.h" - -/* Helper function, interpolates the filter taps */ -static inline void silk_LP_interpolate_filter_taps( - opus_int32 B_Q28[ TRANSITION_NB ], - opus_int32 A_Q28[ TRANSITION_NA ], - const opus_int ind, - const opus_int32 fac_Q16 -) -{ - opus_int nb, na; - - if( ind < TRANSITION_INT_NUM - 1 ) { - if( fac_Q16 > 0 ) { - if( fac_Q16 < 32768 ) { /* fac_Q16 is in range of a 16-bit int */ - /* Piece-wise linear interpolation of B and A */ - for( nb = 0; nb < TRANSITION_NB; nb++ ) { - B_Q28[ nb ] = silk_SMLAWB( - silk_Transition_LP_B_Q28[ ind ][ nb ], - silk_Transition_LP_B_Q28[ ind + 1 ][ nb ] - - silk_Transition_LP_B_Q28[ ind ][ nb ], - fac_Q16 ); - } - for( na = 0; na < TRANSITION_NA; na++ ) { - A_Q28[ na ] = silk_SMLAWB( - silk_Transition_LP_A_Q28[ ind ][ na ], - silk_Transition_LP_A_Q28[ ind + 1 ][ na ] - - silk_Transition_LP_A_Q28[ ind ][ na ], - fac_Q16 ); - } - } else { /* ( fac_Q16 - ( 1 << 16 ) ) is in range of a 16-bit int */ - silk_assert( fac_Q16 - ( 1 << 16 ) == silk_SAT16( fac_Q16 - ( 1 << 16 ) ) ); - /* Piece-wise linear interpolation of B and A */ - for( nb = 0; nb < TRANSITION_NB; nb++ ) { - B_Q28[ nb ] = silk_SMLAWB( - silk_Transition_LP_B_Q28[ ind + 1 ][ nb ], - silk_Transition_LP_B_Q28[ ind + 1 ][ nb ] - - silk_Transition_LP_B_Q28[ ind ][ nb ], - fac_Q16 - ( (opus_int32)1 << 16 ) ); - } - for( na = 0; na < TRANSITION_NA; na++ ) { - A_Q28[ na ] = silk_SMLAWB( - silk_Transition_LP_A_Q28[ ind + 1 ][ na ], - silk_Transition_LP_A_Q28[ ind + 1 ][ na ] - - silk_Transition_LP_A_Q28[ ind ][ na ], - fac_Q16 - ( (opus_int32)1 << 16 ) ); - } - } - } else { - silk_memcpy( B_Q28, silk_Transition_LP_B_Q28[ ind ], TRANSITION_NB * sizeof( opus_int32 ) ); - silk_memcpy( A_Q28, silk_Transition_LP_A_Q28[ ind ], TRANSITION_NA * sizeof( opus_int32 ) ); - } - } else { - silk_memcpy( B_Q28, silk_Transition_LP_B_Q28[ TRANSITION_INT_NUM - 1 ], TRANSITION_NB * sizeof( opus_int32 ) ); - silk_memcpy( A_Q28, silk_Transition_LP_A_Q28[ TRANSITION_INT_NUM - 1 ], TRANSITION_NA * sizeof( opus_int32 ) ); - } -} - -/* Low-pass filter with variable cutoff frequency based on */ -/* piece-wise linear interpolation between elliptic filters */ -/* Start by setting psEncC->mode <> 0; */ -/* Deactivate by setting psEncC->mode = 0; */ -void silk_LP_variable_cutoff( - silk_LP_state *psLP, /* I/O LP filter state */ - opus_int16 *frame, /* I/O Low-pass filtered output signal */ - const opus_int frame_length /* I Frame length */ -) -{ - opus_int32 B_Q28[ TRANSITION_NB ], A_Q28[ TRANSITION_NA ], fac_Q16 = 0; - opus_int ind = 0; - - silk_assert( psLP->transition_frame_no >= 0 && psLP->transition_frame_no <= TRANSITION_FRAMES ); - - /* Run filter if needed */ - if( psLP->mode != 0 ) { - /* Calculate index and interpolation factor for interpolation */ -#if( TRANSITION_INT_STEPS == 64 ) - fac_Q16 = silk_LSHIFT( TRANSITION_FRAMES - psLP->transition_frame_no, 16 - 6 ); -#else - fac_Q16 = silk_DIV32_16( silk_LSHIFT( TRANSITION_FRAMES - psLP->transition_frame_no, 16 ), TRANSITION_FRAMES ); -#endif - ind = silk_RSHIFT( fac_Q16, 16 ); - fac_Q16 -= silk_LSHIFT( ind, 16 ); - - silk_assert( ind >= 0 ); - silk_assert( ind < TRANSITION_INT_NUM ); - - /* Interpolate filter coefficients */ - silk_LP_interpolate_filter_taps( B_Q28, A_Q28, ind, fac_Q16 ); - - /* Update transition frame number for next frame */ - psLP->transition_frame_no = silk_LIMIT( psLP->transition_frame_no + psLP->mode, 0, TRANSITION_FRAMES ); - - /* ARMA low-pass filtering */ - silk_assert( TRANSITION_NB == 3 && TRANSITION_NA == 2 ); - silk_biquad_alt( frame, B_Q28, A_Q28, psLP->In_LP_State, frame, frame_length, 1); - } -} diff --git a/src/opus-1.0.2/silk/MacroCount.h b/src/opus-1.0.2/silk/MacroCount.h deleted file mode 100644 index 2829e8cc..00000000 --- a/src/opus-1.0.2/silk/MacroCount.h +++ /dev/null @@ -1,718 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifndef SIGPROCFIX_API_MACROCOUNT_H -#define SIGPROCFIX_API_MACROCOUNT_H -#include - -#ifdef silk_MACRO_COUNT -#define varDefine opus_int64 ops_count = 0; - -extern opus_int64 ops_count; - -static inline opus_int64 silk_SaveCount(){ - return(ops_count); -} - -static inline opus_int64 silk_SaveResetCount(){ - opus_int64 ret; - - ret = ops_count; - ops_count = 0; - return(ret); -} - -static inline silk_PrintCount(){ - printf("ops_count = %d \n ", (opus_int32)ops_count); -} - -#undef silk_MUL -static inline opus_int32 silk_MUL(opus_int32 a32, opus_int32 b32){ - opus_int32 ret; - ops_count += 4; - ret = a32 * b32; - return ret; -} - -#undef silk_MUL_uint -static inline opus_uint32 silk_MUL_uint(opus_uint32 a32, opus_uint32 b32){ - opus_uint32 ret; - ops_count += 4; - ret = a32 * b32; - return ret; -} -#undef silk_MLA -static inline opus_int32 silk_MLA(opus_int32 a32, opus_int32 b32, opus_int32 c32){ - opus_int32 ret; - ops_count += 4; - ret = a32 + b32 * c32; - return ret; -} - -#undef silk_MLA_uint -static inline opus_int32 silk_MLA_uint(opus_uint32 a32, opus_uint32 b32, opus_uint32 c32){ - opus_uint32 ret; - ops_count += 4; - ret = a32 + b32 * c32; - return ret; -} - -#undef silk_SMULWB -static inline opus_int32 silk_SMULWB(opus_int32 a32, opus_int32 b32){ - opus_int32 ret; - ops_count += 5; - ret = (a32 >> 16) * (opus_int32)((opus_int16)b32) + (((a32 & 0x0000FFFF) * (opus_int32)((opus_int16)b32)) >> 16); - return ret; -} -#undef silk_SMLAWB -static inline opus_int32 silk_SMLAWB(opus_int32 a32, opus_int32 b32, opus_int32 c32){ - opus_int32 ret; - ops_count += 5; - ret = ((a32) + ((((b32) >> 16) * (opus_int32)((opus_int16)(c32))) + ((((b32) & 0x0000FFFF) * (opus_int32)((opus_int16)(c32))) >> 16))); - return ret; -} - -#undef silk_SMULWT -static inline opus_int32 silk_SMULWT(opus_int32 a32, opus_int32 b32){ - opus_int32 ret; - ops_count += 4; - ret = (a32 >> 16) * (b32 >> 16) + (((a32 & 0x0000FFFF) * (b32 >> 16)) >> 16); - return ret; -} -#undef silk_SMLAWT -static inline opus_int32 silk_SMLAWT(opus_int32 a32, opus_int32 b32, opus_int32 c32){ - opus_int32 ret; - ops_count += 4; - ret = a32 + ((b32 >> 16) * (c32 >> 16)) + (((b32 & 0x0000FFFF) * ((c32 >> 16)) >> 16)); - return ret; -} - -#undef silk_SMULBB -static inline opus_int32 silk_SMULBB(opus_int32 a32, opus_int32 b32){ - opus_int32 ret; - ops_count += 1; - ret = (opus_int32)((opus_int16)a32) * (opus_int32)((opus_int16)b32); - return ret; -} -#undef silk_SMLABB -static inline opus_int32 silk_SMLABB(opus_int32 a32, opus_int32 b32, opus_int32 c32){ - opus_int32 ret; - ops_count += 1; - ret = a32 + (opus_int32)((opus_int16)b32) * (opus_int32)((opus_int16)c32); - return ret; -} - -#undef silk_SMULBT -static inline opus_int32 silk_SMULBT(opus_int32 a32, opus_int32 b32 ){ - opus_int32 ret; - ops_count += 4; - ret = ((opus_int32)((opus_int16)a32)) * (b32 >> 16); - return ret; -} - -#undef silk_SMLABT -static inline opus_int32 silk_SMLABT(opus_int32 a32, opus_int32 b32, opus_int32 c32){ - opus_int32 ret; - ops_count += 1; - ret = a32 + ((opus_int32)((opus_int16)b32)) * (c32 >> 16); - return ret; -} - -#undef silk_SMULTT -static inline opus_int32 silk_SMULTT(opus_int32 a32, opus_int32 b32){ - opus_int32 ret; - ops_count += 1; - ret = (a32 >> 16) * (b32 >> 16); - return ret; -} - -#undef silk_SMLATT -static inline opus_int32 silk_SMLATT(opus_int32 a32, opus_int32 b32, opus_int32 c32){ - opus_int32 ret; - ops_count += 1; - ret = a32 + (b32 >> 16) * (c32 >> 16); - return ret; -} - - -/* multiply-accumulate macros that allow overflow in the addition (ie, no asserts in debug mode)*/ -#undef silk_MLA_ovflw -#define silk_MLA_ovflw silk_MLA - -#undef silk_SMLABB_ovflw -#define silk_SMLABB_ovflw silk_SMLABB - -#undef silk_SMLABT_ovflw -#define silk_SMLABT_ovflw silk_SMLABT - -#undef silk_SMLATT_ovflw -#define silk_SMLATT_ovflw silk_SMLATT - -#undef silk_SMLAWB_ovflw -#define silk_SMLAWB_ovflw silk_SMLAWB - -#undef silk_SMLAWT_ovflw -#define silk_SMLAWT_ovflw silk_SMLAWT - -#undef silk_SMULL -static inline opus_int64 silk_SMULL(opus_int32 a32, opus_int32 b32){ - opus_int64 ret; - ops_count += 8; - ret = ((opus_int64)(a32) * /*(opus_int64)*/(b32)); - return ret; -} - -#undef silk_SMLAL -static inline opus_int64 silk_SMLAL(opus_int64 a64, opus_int32 b32, opus_int32 c32){ - opus_int64 ret; - ops_count += 8; - ret = a64 + ((opus_int64)(b32) * /*(opus_int64)*/(c32)); - return ret; -} -#undef silk_SMLALBB -static inline opus_int64 silk_SMLALBB(opus_int64 a64, opus_int16 b16, opus_int16 c16){ - opus_int64 ret; - ops_count += 4; - ret = a64 + ((opus_int64)(b16) * /*(opus_int64)*/(c16)); - return ret; -} - -#undef SigProcFIX_CLZ16 -static inline opus_int32 SigProcFIX_CLZ16(opus_int16 in16) -{ - opus_int32 out32 = 0; - ops_count += 10; - if( in16 == 0 ) { - return 16; - } - /* test nibbles */ - if( in16 & 0xFF00 ) { - if( in16 & 0xF000 ) { - in16 >>= 12; - } else { - out32 += 4; - in16 >>= 8; - } - } else { - if( in16 & 0xFFF0 ) { - out32 += 8; - in16 >>= 4; - } else { - out32 += 12; - } - } - /* test bits and return */ - if( in16 & 0xC ) { - if( in16 & 0x8 ) - return out32 + 0; - else - return out32 + 1; - } else { - if( in16 & 0xE ) - return out32 + 2; - else - return out32 + 3; - } -} - -#undef SigProcFIX_CLZ32 -static inline opus_int32 SigProcFIX_CLZ32(opus_int32 in32) -{ - /* test highest 16 bits and convert to opus_int16 */ - ops_count += 2; - if( in32 & 0xFFFF0000 ) { - return SigProcFIX_CLZ16((opus_int16)(in32 >> 16)); - } else { - return SigProcFIX_CLZ16((opus_int16)in32) + 16; - } -} - -#undef silk_DIV32 -static inline opus_int32 silk_DIV32(opus_int32 a32, opus_int32 b32){ - ops_count += 64; - return a32 / b32; -} - -#undef silk_DIV32_16 -static inline opus_int32 silk_DIV32_16(opus_int32 a32, opus_int32 b32){ - ops_count += 32; - return a32 / b32; -} - -#undef silk_SAT8 -static inline opus_int8 silk_SAT8(opus_int64 a){ - opus_int8 tmp; - ops_count += 1; - tmp = (opus_int8)((a) > silk_int8_MAX ? silk_int8_MAX : \ - ((a) < silk_int8_MIN ? silk_int8_MIN : (a))); - return(tmp); -} - -#undef silk_SAT16 -static inline opus_int16 silk_SAT16(opus_int64 a){ - opus_int16 tmp; - ops_count += 1; - tmp = (opus_int16)((a) > silk_int16_MAX ? silk_int16_MAX : \ - ((a) < silk_int16_MIN ? silk_int16_MIN : (a))); - return(tmp); -} -#undef silk_SAT32 -static inline opus_int32 silk_SAT32(opus_int64 a){ - opus_int32 tmp; - ops_count += 1; - tmp = (opus_int32)((a) > silk_int32_MAX ? silk_int32_MAX : \ - ((a) < silk_int32_MIN ? silk_int32_MIN : (a))); - return(tmp); -} -#undef silk_POS_SAT32 -static inline opus_int32 silk_POS_SAT32(opus_int64 a){ - opus_int32 tmp; - ops_count += 1; - tmp = (opus_int32)((a) > silk_int32_MAX ? silk_int32_MAX : (a)); - return(tmp); -} - -#undef silk_ADD_POS_SAT8 -static inline opus_int8 silk_ADD_POS_SAT8(opus_int64 a, opus_int64 b){ - opus_int8 tmp; - ops_count += 1; - tmp = (opus_int8)((((a)+(b)) & 0x80) ? silk_int8_MAX : ((a)+(b))); - return(tmp); -} -#undef silk_ADD_POS_SAT16 -static inline opus_int16 silk_ADD_POS_SAT16(opus_int64 a, opus_int64 b){ - opus_int16 tmp; - ops_count += 1; - tmp = (opus_int16)((((a)+(b)) & 0x8000) ? silk_int16_MAX : ((a)+(b))); - return(tmp); -} - -#undef silk_ADD_POS_SAT32 -static inline opus_int32 silk_ADD_POS_SAT32(opus_int64 a, opus_int64 b){ - opus_int32 tmp; - ops_count += 1; - tmp = (opus_int32)((((a)+(b)) & 0x80000000) ? silk_int32_MAX : ((a)+(b))); - return(tmp); -} - -#undef silk_ADD_POS_SAT64 -static inline opus_int64 silk_ADD_POS_SAT64(opus_int64 a, opus_int64 b){ - opus_int64 tmp; - ops_count += 1; - tmp = ((((a)+(b)) & 0x8000000000000000LL) ? silk_int64_MAX : ((a)+(b))); - return(tmp); -} - -#undef silk_LSHIFT8 -static inline opus_int8 silk_LSHIFT8(opus_int8 a, opus_int32 shift){ - opus_int8 ret; - ops_count += 1; - ret = a << shift; - return ret; -} -#undef silk_LSHIFT16 -static inline opus_int16 silk_LSHIFT16(opus_int16 a, opus_int32 shift){ - opus_int16 ret; - ops_count += 1; - ret = a << shift; - return ret; -} -#undef silk_LSHIFT32 -static inline opus_int32 silk_LSHIFT32(opus_int32 a, opus_int32 shift){ - opus_int32 ret; - ops_count += 1; - ret = a << shift; - return ret; -} -#undef silk_LSHIFT64 -static inline opus_int64 silk_LSHIFT64(opus_int64 a, opus_int shift){ - ops_count += 1; - return a << shift; -} - -#undef silk_LSHIFT_ovflw -static inline opus_int32 silk_LSHIFT_ovflw(opus_int32 a, opus_int32 shift){ - ops_count += 1; - return a << shift; -} - -#undef silk_LSHIFT_uint -static inline opus_uint32 silk_LSHIFT_uint(opus_uint32 a, opus_int32 shift){ - opus_uint32 ret; - ops_count += 1; - ret = a << shift; - return ret; -} - -#undef silk_RSHIFT8 -static inline opus_int8 silk_RSHIFT8(opus_int8 a, opus_int32 shift){ - ops_count += 1; - return a >> shift; -} -#undef silk_RSHIFT16 -static inline opus_int16 silk_RSHIFT16(opus_int16 a, opus_int32 shift){ - ops_count += 1; - return a >> shift; -} -#undef silk_RSHIFT32 -static inline opus_int32 silk_RSHIFT32(opus_int32 a, opus_int32 shift){ - ops_count += 1; - return a >> shift; -} -#undef silk_RSHIFT64 -static inline opus_int64 silk_RSHIFT64(opus_int64 a, opus_int64 shift){ - ops_count += 1; - return a >> shift; -} - -#undef silk_RSHIFT_uint -static inline opus_uint32 silk_RSHIFT_uint(opus_uint32 a, opus_int32 shift){ - ops_count += 1; - return a >> shift; -} - -#undef silk_ADD_LSHIFT -static inline opus_int32 silk_ADD_LSHIFT(opus_int32 a, opus_int32 b, opus_int32 shift){ - opus_int32 ret; - ops_count += 1; - ret = a + (b << shift); - return ret; /* shift >= 0*/ -} -#undef silk_ADD_LSHIFT32 -static inline opus_int32 silk_ADD_LSHIFT32(opus_int32 a, opus_int32 b, opus_int32 shift){ - opus_int32 ret; - ops_count += 1; - ret = a + (b << shift); - return ret; /* shift >= 0*/ -} -#undef silk_ADD_LSHIFT_uint -static inline opus_uint32 silk_ADD_LSHIFT_uint(opus_uint32 a, opus_uint32 b, opus_int32 shift){ - opus_uint32 ret; - ops_count += 1; - ret = a + (b << shift); - return ret; /* shift >= 0*/ -} -#undef silk_ADD_RSHIFT -static inline opus_int32 silk_ADD_RSHIFT(opus_int32 a, opus_int32 b, opus_int32 shift){ - opus_int32 ret; - ops_count += 1; - ret = a + (b >> shift); - return ret; /* shift > 0*/ -} -#undef silk_ADD_RSHIFT32 -static inline opus_int32 silk_ADD_RSHIFT32(opus_int32 a, opus_int32 b, opus_int32 shift){ - opus_int32 ret; - ops_count += 1; - ret = a + (b >> shift); - return ret; /* shift > 0*/ -} -#undef silk_ADD_RSHIFT_uint -static inline opus_uint32 silk_ADD_RSHIFT_uint(opus_uint32 a, opus_uint32 b, opus_int32 shift){ - opus_uint32 ret; - ops_count += 1; - ret = a + (b >> shift); - return ret; /* shift > 0*/ -} -#undef silk_SUB_LSHIFT32 -static inline opus_int32 silk_SUB_LSHIFT32(opus_int32 a, opus_int32 b, opus_int32 shift){ - opus_int32 ret; - ops_count += 1; - ret = a - (b << shift); - return ret; /* shift >= 0*/ -} -#undef silk_SUB_RSHIFT32 -static inline opus_int32 silk_SUB_RSHIFT32(opus_int32 a, opus_int32 b, opus_int32 shift){ - opus_int32 ret; - ops_count += 1; - ret = a - (b >> shift); - return ret; /* shift > 0*/ -} - -#undef silk_RSHIFT_ROUND -static inline opus_int32 silk_RSHIFT_ROUND(opus_int32 a, opus_int32 shift){ - opus_int32 ret; - ops_count += 3; - ret = shift == 1 ? (a >> 1) + (a & 1) : ((a >> (shift - 1)) + 1) >> 1; - return ret; -} - -#undef silk_RSHIFT_ROUND64 -static inline opus_int64 silk_RSHIFT_ROUND64(opus_int64 a, opus_int32 shift){ - opus_int64 ret; - ops_count += 6; - ret = shift == 1 ? (a >> 1) + (a & 1) : ((a >> (shift - 1)) + 1) >> 1; - return ret; -} - -#undef silk_abs_int64 -static inline opus_int64 silk_abs_int64(opus_int64 a){ - ops_count += 1; - return (((a) > 0) ? (a) : -(a)); /* Be careful, silk_abs returns wrong when input equals to silk_intXX_MIN*/ -} - -#undef silk_abs_int32 -static inline opus_int32 silk_abs_int32(opus_int32 a){ - ops_count += 1; - return silk_abs(a); -} - - -#undef silk_min -static silk_min(a, b){ - ops_count += 1; - return (((a) < (b)) ? (a) : (b)); -} -#undef silk_max -static silk_max(a, b){ - ops_count += 1; - return (((a) > (b)) ? (a) : (b)); -} -#undef silk_sign -static silk_sign(a){ - ops_count += 1; - return ((a) > 0 ? 1 : ( (a) < 0 ? -1 : 0 )); -} - -#undef silk_ADD16 -static inline opus_int16 silk_ADD16(opus_int16 a, opus_int16 b){ - opus_int16 ret; - ops_count += 1; - ret = a + b; - return ret; -} - -#undef silk_ADD32 -static inline opus_int32 silk_ADD32(opus_int32 a, opus_int32 b){ - opus_int32 ret; - ops_count += 1; - ret = a + b; - return ret; -} - -#undef silk_ADD64 -static inline opus_int64 silk_ADD64(opus_int64 a, opus_int64 b){ - opus_int64 ret; - ops_count += 2; - ret = a + b; - return ret; -} - -#undef silk_SUB16 -static inline opus_int16 silk_SUB16(opus_int16 a, opus_int16 b){ - opus_int16 ret; - ops_count += 1; - ret = a - b; - return ret; -} - -#undef silk_SUB32 -static inline opus_int32 silk_SUB32(opus_int32 a, opus_int32 b){ - opus_int32 ret; - ops_count += 1; - ret = a - b; - return ret; -} - -#undef silk_SUB64 -static inline opus_int64 silk_SUB64(opus_int64 a, opus_int64 b){ - opus_int64 ret; - ops_count += 2; - ret = a - b; - return ret; -} - -#undef silk_ADD_SAT16 -static inline opus_int16 silk_ADD_SAT16( opus_int16 a16, opus_int16 b16 ) { - opus_int16 res; - /* Nb will be counted in AKP_add32 and silk_SAT16*/ - res = (opus_int16)silk_SAT16( silk_ADD32( (opus_int32)(a16), (b16) ) ); - return res; -} - -#undef silk_ADD_SAT32 -static inline opus_int32 silk_ADD_SAT32(opus_int32 a32, opus_int32 b32){ - opus_int32 res; - ops_count += 1; - res = ((((a32) + (b32)) & 0x80000000) == 0 ? \ - ((((a32) & (b32)) & 0x80000000) != 0 ? silk_int32_MIN : (a32)+(b32)) : \ - ((((a32) | (b32)) & 0x80000000) == 0 ? silk_int32_MAX : (a32)+(b32)) ); - return res; -} - -#undef silk_ADD_SAT64 -static inline opus_int64 silk_ADD_SAT64( opus_int64 a64, opus_int64 b64 ) { - opus_int64 res; - ops_count += 1; - res = ((((a64) + (b64)) & 0x8000000000000000LL) == 0 ? \ - ((((a64) & (b64)) & 0x8000000000000000LL) != 0 ? silk_int64_MIN : (a64)+(b64)) : \ - ((((a64) | (b64)) & 0x8000000000000000LL) == 0 ? silk_int64_MAX : (a64)+(b64)) ); - return res; -} - -#undef silk_SUB_SAT16 -static inline opus_int16 silk_SUB_SAT16( opus_int16 a16, opus_int16 b16 ) { - opus_int16 res; - silk_assert(0); - /* Nb will be counted in sub-macros*/ - res = (opus_int16)silk_SAT16( silk_SUB32( (opus_int32)(a16), (b16) ) ); - return res; -} - -#undef silk_SUB_SAT32 -static inline opus_int32 silk_SUB_SAT32( opus_int32 a32, opus_int32 b32 ) { - opus_int32 res; - ops_count += 1; - res = ((((a32)-(b32)) & 0x80000000) == 0 ? \ - (( (a32) & ((b32)^0x80000000) & 0x80000000) ? silk_int32_MIN : (a32)-(b32)) : \ - ((((a32)^0x80000000) & (b32) & 0x80000000) ? silk_int32_MAX : (a32)-(b32)) ); - return res; -} - -#undef silk_SUB_SAT64 -static inline opus_int64 silk_SUB_SAT64( opus_int64 a64, opus_int64 b64 ) { - opus_int64 res; - ops_count += 1; - res = ((((a64)-(b64)) & 0x8000000000000000LL) == 0 ? \ - (( (a64) & ((b64)^0x8000000000000000LL) & 0x8000000000000000LL) ? silk_int64_MIN : (a64)-(b64)) : \ - ((((a64)^0x8000000000000000LL) & (b64) & 0x8000000000000000LL) ? silk_int64_MAX : (a64)-(b64)) ); - - return res; -} - -#undef silk_SMULWW -static inline opus_int32 silk_SMULWW(opus_int32 a32, opus_int32 b32){ - opus_int32 ret; - /* Nb will be counted in sub-macros*/ - ret = silk_MLA(silk_SMULWB((a32), (b32)), (a32), silk_RSHIFT_ROUND((b32), 16)); - return ret; -} - -#undef silk_SMLAWW -static inline opus_int32 silk_SMLAWW(opus_int32 a32, opus_int32 b32, opus_int32 c32){ - opus_int32 ret; - /* Nb will be counted in sub-macros*/ - ret = silk_MLA(silk_SMLAWB((a32), (b32), (c32)), (b32), silk_RSHIFT_ROUND((c32), 16)); - return ret; -} - -#undef silk_min_int -static inline opus_int silk_min_int(opus_int a, opus_int b) -{ - ops_count += 1; - return (((a) < (b)) ? (a) : (b)); -} - -#undef silk_min_16 -static inline opus_int16 silk_min_16(opus_int16 a, opus_int16 b) -{ - ops_count += 1; - return (((a) < (b)) ? (a) : (b)); -} -#undef silk_min_32 -static inline opus_int32 silk_min_32(opus_int32 a, opus_int32 b) -{ - ops_count += 1; - return (((a) < (b)) ? (a) : (b)); -} -#undef silk_min_64 -static inline opus_int64 silk_min_64(opus_int64 a, opus_int64 b) -{ - ops_count += 1; - return (((a) < (b)) ? (a) : (b)); -} - -/* silk_min() versions with typecast in the function call */ -#undef silk_max_int -static inline opus_int silk_max_int(opus_int a, opus_int b) -{ - ops_count += 1; - return (((a) > (b)) ? (a) : (b)); -} -#undef silk_max_16 -static inline opus_int16 silk_max_16(opus_int16 a, opus_int16 b) -{ - ops_count += 1; - return (((a) > (b)) ? (a) : (b)); -} -#undef silk_max_32 -static inline opus_int32 silk_max_32(opus_int32 a, opus_int32 b) -{ - ops_count += 1; - return (((a) > (b)) ? (a) : (b)); -} - -#undef silk_max_64 -static inline opus_int64 silk_max_64(opus_int64 a, opus_int64 b) -{ - ops_count += 1; - return (((a) > (b)) ? (a) : (b)); -} - - -#undef silk_LIMIT_int -static inline opus_int silk_LIMIT_int(opus_int a, opus_int limit1, opus_int limit2) -{ - opus_int ret; - ops_count += 6; - - ret = ((limit1) > (limit2) ? ((a) > (limit1) ? (limit1) : ((a) < (limit2) ? (limit2) : (a))) \ - : ((a) > (limit2) ? (limit2) : ((a) < (limit1) ? (limit1) : (a)))); - - return(ret); -} - -#undef silk_LIMIT_16 -static inline opus_int16 silk_LIMIT_16(opus_int16 a, opus_int16 limit1, opus_int16 limit2) -{ - opus_int16 ret; - ops_count += 6; - - ret = ((limit1) > (limit2) ? ((a) > (limit1) ? (limit1) : ((a) < (limit2) ? (limit2) : (a))) \ - : ((a) > (limit2) ? (limit2) : ((a) < (limit1) ? (limit1) : (a)))); - -return(ret); -} - - -#undef silk_LIMIT_32 -static inline opus_int silk_LIMIT_32(opus_int32 a, opus_int32 limit1, opus_int32 limit2) -{ - opus_int32 ret; - ops_count += 6; - - ret = ((limit1) > (limit2) ? ((a) > (limit1) ? (limit1) : ((a) < (limit2) ? (limit2) : (a))) \ - : ((a) > (limit2) ? (limit2) : ((a) < (limit1) ? (limit1) : (a)))); - return(ret); -} - -#else -#define varDefine -#define silk_SaveCount() - -#endif -#endif - diff --git a/src/opus-1.0.2/silk/MacroDebug.h b/src/opus-1.0.2/silk/MacroDebug.h deleted file mode 100644 index ecd90bc4..00000000 --- a/src/opus-1.0.2/silk/MacroDebug.h +++ /dev/null @@ -1,952 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Copyright (C) 2012 Xiph.Org Foundation -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifndef MACRO_DEBUG_H -#define MACRO_DEBUG_H - -/* Redefine macro functions with extensive assertion in DEBUG mode. - As functions can't be undefined, this file can't work with SigProcFIX_MacroCount.h */ - -#if ( defined (FIXED_DEBUG) || ( 0 && defined (_DEBUG) ) ) && !defined (silk_MACRO_COUNT) - -#undef silk_ADD16 -#define silk_ADD16(a,b) silk_ADD16_((a), (b), __FILE__, __LINE__) -static inline opus_int16 silk_ADD16_(opus_int16 a, opus_int16 b, char *file, int line){ - opus_int16 ret; - - ret = a + b; - if ( ret != silk_ADD_SAT16( a, b ) ) - { - fprintf (stderr, "silk_ADD16(%d, %d) in %s: line %d\n", a, b, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return ret; -} - -#undef silk_ADD32 -#define silk_ADD32(a,b) silk_ADD32_((a), (b), __FILE__, __LINE__) -static inline opus_int32 silk_ADD32_(opus_int32 a, opus_int32 b, char *file, int line){ - opus_int32 ret; - - ret = a + b; - if ( ret != silk_ADD_SAT32( a, b ) ) - { - fprintf (stderr, "silk_ADD32(%d, %d) in %s: line %d\n", a, b, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return ret; -} - -#undef silk_ADD64 -#define silk_ADD64(a,b) silk_ADD64_((a), (b), __FILE__, __LINE__) -static inline opus_int64 silk_ADD64_(opus_int64 a, opus_int64 b, char *file, int line){ - opus_int64 ret; - - ret = a + b; - if ( ret != silk_ADD_SAT64( a, b ) ) - { - fprintf (stderr, "silk_ADD64(%lld, %lld) in %s: line %d\n", (long long)a, (long long)b, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return ret; -} - -#undef silk_SUB16 -#define silk_SUB16(a,b) silk_SUB16_((a), (b), __FILE__, __LINE__) -static inline opus_int16 silk_SUB16_(opus_int16 a, opus_int16 b, char *file, int line){ - opus_int16 ret; - - ret = a - b; - if ( ret != silk_SUB_SAT16( a, b ) ) - { - fprintf (stderr, "silk_SUB16(%d, %d) in %s: line %d\n", a, b, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return ret; -} - -#undef silk_SUB32 -#define silk_SUB32(a,b) silk_SUB32_((a), (b), __FILE__, __LINE__) -static inline opus_int32 silk_SUB32_(opus_int32 a, opus_int32 b, char *file, int line){ - opus_int32 ret; - - ret = a - b; - if ( ret != silk_SUB_SAT32( a, b ) ) - { - fprintf (stderr, "silk_SUB32(%d, %d) in %s: line %d\n", a, b, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return ret; -} - -#undef silk_SUB64 -#define silk_SUB64(a,b) silk_SUB64_((a), (b), __FILE__, __LINE__) -static inline opus_int64 silk_SUB64_(opus_int64 a, opus_int64 b, char *file, int line){ - opus_int64 ret; - - ret = a - b; - if ( ret != silk_SUB_SAT64( a, b ) ) - { - fprintf (stderr, "silk_SUB64(%lld, %lld) in %s: line %d\n", (long long)a, (long long)b, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return ret; -} - -#undef silk_ADD_SAT16 -#define silk_ADD_SAT16(a,b) silk_ADD_SAT16_((a), (b), __FILE__, __LINE__) -static inline opus_int16 silk_ADD_SAT16_( opus_int16 a16, opus_int16 b16, char *file, int line) { - opus_int16 res; - res = (opus_int16)silk_SAT16( silk_ADD32( (opus_int32)(a16), (b16) ) ); - if ( res != silk_SAT16( (opus_int32)a16 + (opus_int32)b16 ) ) - { - fprintf (stderr, "silk_ADD_SAT16(%d, %d) in %s: line %d\n", a16, b16, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return res; -} - -#undef silk_ADD_SAT32 -#define silk_ADD_SAT32(a,b) silk_ADD_SAT32_((a), (b), __FILE__, __LINE__) -static inline opus_int32 silk_ADD_SAT32_(opus_int32 a32, opus_int32 b32, char *file, int line){ - opus_int32 res; - res = ((((opus_uint32)(a32) + (opus_uint32)(b32)) & 0x80000000) == 0 ? \ - ((((a32) & (b32)) & 0x80000000) != 0 ? silk_int32_MIN : (a32)+(b32)) : \ - ((((a32) | (b32)) & 0x80000000) == 0 ? silk_int32_MAX : (a32)+(b32)) ); - if ( res != silk_SAT32( (opus_int64)a32 + (opus_int64)b32 ) ) - { - fprintf (stderr, "silk_ADD_SAT32(%d, %d) in %s: line %d\n", a32, b32, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return res; -} - -#undef silk_ADD_SAT64 -#define silk_ADD_SAT64(a,b) silk_ADD_SAT64_((a), (b), __FILE__, __LINE__) -static inline opus_int64 silk_ADD_SAT64_( opus_int64 a64, opus_int64 b64, char *file, int line) { - opus_int64 res; - int fail = 0; - res = ((((a64) + (b64)) & 0x8000000000000000LL) == 0 ? \ - ((((a64) & (b64)) & 0x8000000000000000LL) != 0 ? silk_int64_MIN : (a64)+(b64)) : \ - ((((a64) | (b64)) & 0x8000000000000000LL) == 0 ? silk_int64_MAX : (a64)+(b64)) ); - if( res != a64 + b64 ) { - /* Check that we saturated to the correct extreme value */ - if ( !(( res == silk_int64_MAX && ( ( a64 >> 1 ) + ( b64 >> 1 ) > ( silk_int64_MAX >> 3 ) ) ) || - ( res == silk_int64_MIN && ( ( a64 >> 1 ) + ( b64 >> 1 ) < ( silk_int64_MIN >> 3 ) ) ) ) ) - { - fail = 1; - } - } else { - /* Saturation not necessary */ - fail = res != a64 + b64; - } - if ( fail ) - { - fprintf (stderr, "silk_ADD_SAT64(%lld, %lld) in %s: line %d\n", (long long)a64, (long long)b64, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return res; -} - -#undef silk_SUB_SAT16 -#define silk_SUB_SAT16(a,b) silk_SUB_SAT16_((a), (b), __FILE__, __LINE__) -static inline opus_int16 silk_SUB_SAT16_( opus_int16 a16, opus_int16 b16, char *file, int line ) { - opus_int16 res; - res = (opus_int16)silk_SAT16( silk_SUB32( (opus_int32)(a16), (b16) ) ); - if ( res != silk_SAT16( (opus_int32)a16 - (opus_int32)b16 ) ) - { - fprintf (stderr, "silk_SUB_SAT16(%d, %d) in %s: line %d\n", a16, b16, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return res; -} - -#undef silk_SUB_SAT32 -#define silk_SUB_SAT32(a,b) silk_SUB_SAT32_((a), (b), __FILE__, __LINE__) -static inline opus_int32 silk_SUB_SAT32_( opus_int32 a32, opus_int32 b32, char *file, int line ) { - opus_int32 res; - res = ((((opus_uint32)(a32)-(opus_uint32)(b32)) & 0x80000000) == 0 ? \ - (( (a32) & ((b32)^0x80000000) & 0x80000000) ? silk_int32_MIN : (a32)-(b32)) : \ - ((((a32)^0x80000000) & (b32) & 0x80000000) ? silk_int32_MAX : (a32)-(b32)) ); - if ( res != silk_SAT32( (opus_int64)a32 - (opus_int64)b32 ) ) - { - fprintf (stderr, "silk_SUB_SAT32(%d, %d) in %s: line %d\n", a32, b32, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return res; -} - -#undef silk_SUB_SAT64 -#define silk_SUB_SAT64(a,b) silk_SUB_SAT64_((a), (b), __FILE__, __LINE__) -static inline opus_int64 silk_SUB_SAT64_( opus_int64 a64, opus_int64 b64, char *file, int line ) { - opus_int64 res; - int fail = 0; - res = ((((a64)-(b64)) & 0x8000000000000000LL) == 0 ? \ - (( (a64) & ((b64)^0x8000000000000000LL) & 0x8000000000000000LL) ? silk_int64_MIN : (a64)-(b64)) : \ - ((((a64)^0x8000000000000000LL) & (b64) & 0x8000000000000000LL) ? silk_int64_MAX : (a64)-(b64)) ); - if( res != a64 - b64 ) { - /* Check that we saturated to the correct extreme value */ - if( !(( res == silk_int64_MAX && ( ( a64 >> 1 ) + ( b64 >> 1 ) > ( silk_int64_MAX >> 3 ) ) ) || - ( res == silk_int64_MIN && ( ( a64 >> 1 ) + ( b64 >> 1 ) < ( silk_int64_MIN >> 3 ) ) ) )) - { - fail = 1; - } - } else { - /* Saturation not necessary */ - fail = res != a64 - b64; - } - if ( fail ) - { - fprintf (stderr, "silk_SUB_SAT64(%lld, %lld) in %s: line %d\n", (long long)a64, (long long)b64, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return res; -} - -#undef silk_MUL -#define silk_MUL(a,b) silk_MUL_((a), (b), __FILE__, __LINE__) -static inline opus_int32 silk_MUL_(opus_int32 a32, opus_int32 b32, char *file, int line){ - opus_int32 ret; - opus_int64 ret64; - ret = a32 * b32; - ret64 = (opus_int64)a32 * (opus_int64)b32; - if ( (opus_int64)ret != ret64 ) - { - fprintf (stderr, "silk_MUL(%d, %d) in %s: line %d\n", a32, b32, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return ret; -} - -#undef silk_MUL_uint -#define silk_MUL_uint(a,b) silk_MUL_uint_((a), (b), __FILE__, __LINE__) -static inline opus_uint32 silk_MUL_uint_(opus_uint32 a32, opus_uint32 b32, char *file, int line){ - opus_uint32 ret; - ret = a32 * b32; - if ( (opus_uint64)ret != (opus_uint64)a32 * (opus_uint64)b32 ) - { - fprintf (stderr, "silk_MUL_uint(%u, %u) in %s: line %d\n", a32, b32, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return ret; -} - -#undef silk_MLA -#define silk_MLA(a,b,c) silk_MLA_((a), (b), (c), __FILE__, __LINE__) -static inline opus_int32 silk_MLA_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){ - opus_int32 ret; - ret = a32 + b32 * c32; - if ( (opus_int64)ret != (opus_int64)a32 + (opus_int64)b32 * (opus_int64)c32 ) - { - fprintf (stderr, "silk_MLA(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return ret; -} - -#undef silk_MLA_uint -#define silk_MLA_uint(a,b,c) silk_MLA_uint_((a), (b), (c), __FILE__, __LINE__) -static inline opus_int32 silk_MLA_uint_(opus_uint32 a32, opus_uint32 b32, opus_uint32 c32, char *file, int line){ - opus_uint32 ret; - ret = a32 + b32 * c32; - if ( (opus_int64)ret != (opus_int64)a32 + (opus_int64)b32 * (opus_int64)c32 ) - { - fprintf (stderr, "silk_MLA_uint(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return ret; -} - -#undef silk_SMULWB -#define silk_SMULWB(a,b) silk_SMULWB_((a), (b), __FILE__, __LINE__) -static inline opus_int32 silk_SMULWB_(opus_int32 a32, opus_int32 b32, char *file, int line){ - opus_int32 ret; - ret = (a32 >> 16) * (opus_int32)((opus_int16)b32) + (((a32 & 0x0000FFFF) * (opus_int32)((opus_int16)b32)) >> 16); - if ( (opus_int64)ret != ((opus_int64)a32 * (opus_int16)b32) >> 16 ) - { - fprintf (stderr, "silk_SMULWB(%d, %d) in %s: line %d\n", a32, b32, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return ret; -} - -#undef silk_SMLAWB -#define silk_SMLAWB(a,b,c) silk_SMLAWB_((a), (b), (c), __FILE__, __LINE__) -static inline opus_int32 silk_SMLAWB_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){ - opus_int32 ret; - ret = silk_ADD32( a32, silk_SMULWB( b32, c32 ) ); - if ( silk_ADD32( a32, silk_SMULWB( b32, c32 ) ) != silk_ADD_SAT32( a32, silk_SMULWB( b32, c32 ) ) ) - { - fprintf (stderr, "silk_SMLAWB(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return ret; -} - -#undef silk_SMULWT -#define silk_SMULWT(a,b) silk_SMULWT_((a), (b), __FILE__, __LINE__) -static inline opus_int32 silk_SMULWT_(opus_int32 a32, opus_int32 b32, char *file, int line){ - opus_int32 ret; - ret = (a32 >> 16) * (b32 >> 16) + (((a32 & 0x0000FFFF) * (b32 >> 16)) >> 16); - if ( (opus_int64)ret != ((opus_int64)a32 * (b32 >> 16)) >> 16 ) - { - fprintf (stderr, "silk_SMULWT(%d, %d) in %s: line %d\n", a32, b32, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return ret; -} - -#undef silk_SMLAWT -#define silk_SMLAWT(a,b,c) silk_SMLAWT_((a), (b), (c), __FILE__, __LINE__) -static inline opus_int32 silk_SMLAWT_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){ - opus_int32 ret; - ret = a32 + ((b32 >> 16) * (c32 >> 16)) + (((b32 & 0x0000FFFF) * ((c32 >> 16)) >> 16)); - if ( (opus_int64)ret != (opus_int64)a32 + (((opus_int64)b32 * (c32 >> 16)) >> 16) ) - { - fprintf (stderr, "silk_SMLAWT(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return ret; -} - -#undef silk_SMULL -#define silk_SMULL(a,b) silk_SMULL_((a), (b), __FILE__, __LINE__) -static inline opus_int64 silk_SMULL_(opus_int64 a64, opus_int64 b64, char *file, int line){ - opus_int64 ret64; - int fail = 0; - ret64 = a64 * b64; - if( b64 != 0 ) { - fail = a64 != (ret64 / b64); - } else if( a64 != 0 ) { - fail = b64 != (ret64 / a64); - } - if ( fail ) - { - fprintf (stderr, "silk_SMULL(%lld, %lld) in %s: line %d\n", (long long)a64, (long long)b64, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return ret64; -} - -/* no checking needed for silk_SMULBB */ -#undef silk_SMLABB -#define silk_SMLABB(a,b,c) silk_SMLABB_((a), (b), (c), __FILE__, __LINE__) -static inline opus_int32 silk_SMLABB_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){ - opus_int32 ret; - ret = a32 + (opus_int32)((opus_int16)b32) * (opus_int32)((opus_int16)c32); - if ( (opus_int64)ret != (opus_int64)a32 + (opus_int64)b32 * (opus_int16)c32 ) - { - fprintf (stderr, "silk_SMLABB(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return ret; -} - -/* no checking needed for silk_SMULBT */ -#undef silk_SMLABT -#define silk_SMLABT(a,b,c) silk_SMLABT_((a), (b), (c), __FILE__, __LINE__) -static inline opus_int32 silk_SMLABT_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){ - opus_int32 ret; - ret = a32 + ((opus_int32)((opus_int16)b32)) * (c32 >> 16); - if ( (opus_int64)ret != (opus_int64)a32 + (opus_int64)b32 * (c32 >> 16) ) - { - fprintf (stderr, "silk_SMLABT(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return ret; -} - -/* no checking needed for silk_SMULTT */ -#undef silk_SMLATT -#define silk_SMLATT(a,b,c) silk_SMLATT_((a), (b), (c), __FILE__, __LINE__) -static inline opus_int32 silk_SMLATT_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){ - opus_int32 ret; - ret = a32 + (b32 >> 16) * (c32 >> 16); - if ( (opus_int64)ret != (opus_int64)a32 + (b32 >> 16) * (c32 >> 16) ) - { - fprintf (stderr, "silk_SMLATT(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return ret; -} - -#undef silk_SMULWW -#define silk_SMULWW(a,b) silk_SMULWW_((a), (b), __FILE__, __LINE__) -static inline opus_int32 silk_SMULWW_(opus_int32 a32, opus_int32 b32, char *file, int line){ - opus_int32 ret, tmp1, tmp2; - opus_int64 ret64; - int fail = 0; - - ret = silk_SMULWB( a32, b32 ); - tmp1 = silk_RSHIFT_ROUND( b32, 16 ); - tmp2 = silk_MUL( a32, tmp1 ); - - fail |= (opus_int64)tmp2 != (opus_int64) a32 * (opus_int64) tmp1; - - tmp1 = ret; - ret = silk_ADD32( tmp1, tmp2 ); - fail |= silk_ADD32( tmp1, tmp2 ) != silk_ADD_SAT32( tmp1, tmp2 ); - - ret64 = silk_RSHIFT64( silk_SMULL( a32, b32 ), 16 ); - fail |= (opus_int64)ret != ret64; - - if ( fail ) - { - fprintf (stderr, "silk_SMULWT(%d, %d) in %s: line %d\n", a32, b32, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - - return ret; -} - -#undef silk_SMLAWW -#define silk_SMLAWW(a,b,c) silk_SMLAWW_((a), (b), (c), __FILE__, __LINE__) -static inline opus_int32 silk_SMLAWW_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){ - opus_int32 ret, tmp; - - tmp = silk_SMULWW( b32, c32 ); - ret = silk_ADD32( a32, tmp ); - if ( ret != silk_ADD_SAT32( a32, tmp ) ) - { - fprintf (stderr, "silk_SMLAWW(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return ret; -} - -/* Multiply-accumulate macros that allow overflow in the addition (ie, no asserts in debug mode) */ -#undef silk_MLA_ovflw -#define silk_MLA_ovflw(a32, b32, c32) ((a32) + ((b32) * (c32))) -#undef silk_SMLABB_ovflw -#define silk_SMLABB_ovflw(a32, b32, c32) ((a32) + ((opus_int32)((opus_int16)(b32))) * (opus_int32)((opus_int16)(c32))) - -/* no checking needed for silk_SMULL - no checking needed for silk_SMLAL - no checking needed for silk_SMLALBB - no checking needed for SigProcFIX_CLZ16 - no checking needed for SigProcFIX_CLZ32*/ - -#undef silk_DIV32 -#define silk_DIV32(a,b) silk_DIV32_((a), (b), __FILE__, __LINE__) -static inline opus_int32 silk_DIV32_(opus_int32 a32, opus_int32 b32, char *file, int line){ - if ( b32 == 0 ) - { - fprintf (stderr, "silk_DIV32(%d, %d) in %s: line %d\n", a32, b32, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return a32 / b32; -} - -#undef silk_DIV32_16 -#define silk_DIV32_16(a,b) silk_DIV32_16_((a), (b), __FILE__, __LINE__) -static inline opus_int32 silk_DIV32_16_(opus_int32 a32, opus_int32 b32, char *file, int line){ - int fail = 0; - fail |= b32 == 0; - fail |= b32 > silk_int16_MAX; - fail |= b32 < silk_int16_MIN; - if ( fail ) - { - fprintf (stderr, "silk_DIV32_16(%d, %d) in %s: line %d\n", a32, b32, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return a32 / b32; -} - -/* no checking needed for silk_SAT8 - no checking needed for silk_SAT16 - no checking needed for silk_SAT32 - no checking needed for silk_POS_SAT32 - no checking needed for silk_ADD_POS_SAT8 - no checking needed for silk_ADD_POS_SAT16 - no checking needed for silk_ADD_POS_SAT32 - no checking needed for silk_ADD_POS_SAT64 */ - -#undef silk_LSHIFT8 -#define silk_LSHIFT8(a,b) silk_LSHIFT8_((a), (b), __FILE__, __LINE__) -static inline opus_int8 silk_LSHIFT8_(opus_int8 a, opus_int32 shift, char *file, int line){ - opus_int8 ret; - int fail = 0; - ret = a << shift; - fail |= shift < 0; - fail |= shift >= 8; - fail |= (opus_int64)ret != ((opus_int64)a) << shift; - if ( fail ) - { - fprintf (stderr, "silk_LSHIFT8(%d, %d) in %s: line %d\n", a, shift, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return ret; -} - -#undef silk_LSHIFT16 -#define silk_LSHIFT16(a,b) silk_LSHIFT16_((a), (b), __FILE__, __LINE__) -static inline opus_int16 silk_LSHIFT16_(opus_int16 a, opus_int32 shift, char *file, int line){ - opus_int16 ret; - int fail = 0; - ret = a << shift; - fail |= shift < 0; - fail |= shift >= 16; - fail |= (opus_int64)ret != ((opus_int64)a) << shift; - if ( fail ) - { - fprintf (stderr, "silk_LSHIFT16(%d, %d) in %s: line %d\n", a, shift, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return ret; -} - -#undef silk_LSHIFT32 -#define silk_LSHIFT32(a,b) silk_LSHIFT32_((a), (b), __FILE__, __LINE__) -static inline opus_int32 silk_LSHIFT32_(opus_int32 a, opus_int32 shift, char *file, int line){ - opus_int32 ret; - int fail = 0; - ret = a << shift; - fail |= shift < 0; - fail |= shift >= 32; - fail |= (opus_int64)ret != ((opus_int64)a) << shift; - if ( fail ) - { - fprintf (stderr, "silk_LSHIFT32(%d, %d) in %s: line %d\n", a, shift, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return ret; -} - -#undef silk_LSHIFT64 -#define silk_LSHIFT64(a,b) silk_LSHIFT64_((a), (b), __FILE__, __LINE__) -static inline opus_int64 silk_LSHIFT64_(opus_int64 a, opus_int shift, char *file, int line){ - opus_int64 ret; - int fail = 0; - ret = a << shift; - fail |= shift < 0; - fail |= shift >= 64; - fail |= (ret>>shift) != ((opus_int64)a); - if ( fail ) - { - fprintf (stderr, "silk_LSHIFT64(%lld, %d) in %s: line %d\n", (long long)a, shift, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return ret; -} - -#undef silk_LSHIFT_ovflw -#define silk_LSHIFT_ovflw(a,b) silk_LSHIFT_ovflw_((a), (b), __FILE__, __LINE__) -static inline opus_int32 silk_LSHIFT_ovflw_(opus_int32 a, opus_int32 shift, char *file, int line){ - if ( (shift < 0) || (shift >= 32) ) /* no check for overflow */ - { - fprintf (stderr, "silk_LSHIFT_ovflw(%d, %d) in %s: line %d\n", a, shift, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return a << shift; -} - -#undef silk_LSHIFT_uint -#define silk_LSHIFT_uint(a,b) silk_LSHIFT_uint_((a), (b), __FILE__, __LINE__) -static inline opus_uint32 silk_LSHIFT_uint_(opus_uint32 a, opus_int32 shift, char *file, int line){ - opus_uint32 ret; - ret = a << shift; - if ( (shift < 0) || ((opus_int64)ret != ((opus_int64)a) << shift)) - { - fprintf (stderr, "silk_LSHIFT_uint(%u, %d) in %s: line %d\n", a, shift, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return ret; -} - -#undef silk_RSHIFT8 -#define silk_RSHITF8(a,b) silk_RSHIFT8_((a), (b), __FILE__, __LINE__) -static inline opus_int8 silk_RSHIFT8_(opus_int8 a, opus_int32 shift, char *file, int line){ - if ( (shift < 0) || (shift>=8) ) - { - fprintf (stderr, "silk_RSHITF8(%d, %d) in %s: line %d\n", a, shift, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return a >> shift; -} - -#undef silk_RSHIFT16 -#define silk_RSHITF16(a,b) silk_RSHIFT16_((a), (b), __FILE__, __LINE__) -static inline opus_int16 silk_RSHIFT16_(opus_int16 a, opus_int32 shift, char *file, int line){ - if ( (shift < 0) || (shift>=16) ) - { - fprintf (stderr, "silk_RSHITF16(%d, %d) in %s: line %d\n", a, shift, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return a >> shift; -} - -#undef silk_RSHIFT32 -#define silk_RSHIFT32(a,b) silk_RSHIFT32_((a), (b), __FILE__, __LINE__) -static inline opus_int32 silk_RSHIFT32_(opus_int32 a, opus_int32 shift, char *file, int line){ - if ( (shift < 0) || (shift>=32) ) - { - fprintf (stderr, "silk_RSHITF32(%d, %d) in %s: line %d\n", a, shift, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return a >> shift; -} - -#undef silk_RSHIFT64 -#define silk_RSHIFT64(a,b) silk_RSHIFT64_((a), (b), __FILE__, __LINE__) -static inline opus_int64 silk_RSHIFT64_(opus_int64 a, opus_int64 shift, char *file, int line){ - if ( (shift < 0) || (shift>=64) ) - { - fprintf (stderr, "silk_RSHITF64(%lld, %lld) in %s: line %d\n", (long long)a, (long long)shift, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return a >> shift; -} - -#undef silk_RSHIFT_uint -#define silk_RSHIFT_uint(a,b) silk_RSHIFT_uint_((a), (b), __FILE__, __LINE__) -static inline opus_uint32 silk_RSHIFT_uint_(opus_uint32 a, opus_int32 shift, char *file, int line){ - if ( (shift < 0) || (shift>32) ) - { - fprintf (stderr, "silk_RSHIFT_uint(%u, %d) in %s: line %d\n", a, shift, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return a >> shift; -} - -#undef silk_ADD_LSHIFT -#define silk_ADD_LSHIFT(a,b,c) silk_ADD_LSHIFT_((a), (b), (c), __FILE__, __LINE__) -static inline int silk_ADD_LSHIFT_(int a, int b, int shift, char *file, int line){ - opus_int16 ret; - ret = a + (b << shift); - if ( (shift < 0) || (shift>15) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) << shift)) ) - { - fprintf (stderr, "silk_ADD_LSHIFT(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return ret; /* shift >= 0 */ -} - -#undef silk_ADD_LSHIFT32 -#define silk_ADD_LSHIFT32(a,b,c) silk_ADD_LSHIFT32_((a), (b), (c), __FILE__, __LINE__) -static inline opus_int32 silk_ADD_LSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){ - opus_int32 ret; - ret = a + (b << shift); - if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) << shift)) ) - { - fprintf (stderr, "silk_ADD_LSHIFT32(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return ret; /* shift >= 0 */ -} - -#undef silk_ADD_LSHIFT_uint -#define silk_ADD_LSHIFT_uint(a,b,c) silk_ADD_LSHIFT_uint_((a), (b), (c), __FILE__, __LINE__) -static inline opus_uint32 silk_ADD_LSHIFT_uint_(opus_uint32 a, opus_uint32 b, opus_int32 shift, char *file, int line){ - opus_uint32 ret; - ret = a + (b << shift); - if ( (shift < 0) || (shift>32) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) << shift)) ) - { - fprintf (stderr, "silk_ADD_LSHIFT_uint(%u, %u, %d) in %s: line %d\n", a, b, shift, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return ret; /* shift >= 0 */ -} - -#undef silk_ADD_RSHIFT -#define silk_ADD_RSHIFT(a,b,c) silk_ADD_RSHIFT_((a), (b), (c), __FILE__, __LINE__) -static inline int silk_ADD_RSHIFT_(int a, int b, int shift, char *file, int line){ - opus_int16 ret; - ret = a + (b >> shift); - if ( (shift < 0) || (shift>15) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) >> shift)) ) - { - fprintf (stderr, "silk_ADD_RSHIFT(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return ret; /* shift > 0 */ -} - -#undef silk_ADD_RSHIFT32 -#define silk_ADD_RSHIFT32(a,b,c) silk_ADD_RSHIFT32_((a), (b), (c), __FILE__, __LINE__) -static inline opus_int32 silk_ADD_RSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){ - opus_int32 ret; - ret = a + (b >> shift); - if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) >> shift)) ) - { - fprintf (stderr, "silk_ADD_RSHIFT32(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return ret; /* shift > 0 */ -} - -#undef silk_ADD_RSHIFT_uint -#define silk_ADD_RSHIFT_uint(a,b,c) silk_ADD_RSHIFT_uint_((a), (b), (c), __FILE__, __LINE__) -static inline opus_uint32 silk_ADD_RSHIFT_uint_(opus_uint32 a, opus_uint32 b, opus_int32 shift, char *file, int line){ - opus_uint32 ret; - ret = a + (b >> shift); - if ( (shift < 0) || (shift>32) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) >> shift)) ) - { - fprintf (stderr, "silk_ADD_RSHIFT_uint(%u, %u, %d) in %s: line %d\n", a, b, shift, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return ret; /* shift > 0 */ -} - -#undef silk_SUB_LSHIFT32 -#define silk_SUB_LSHIFT32(a,b,c) silk_SUB_LSHIFT32_((a), (b), (c), __FILE__, __LINE__) -static inline opus_int32 silk_SUB_LSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){ - opus_int32 ret; - ret = a - (b << shift); - if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a - (((opus_int64)b) << shift)) ) - { - fprintf (stderr, "silk_SUB_LSHIFT32(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return ret; /* shift >= 0 */ -} - -#undef silk_SUB_RSHIFT32 -#define silk_SUB_RSHIFT32(a,b,c) silk_SUB_RSHIFT32_((a), (b), (c), __FILE__, __LINE__) -static inline opus_int32 silk_SUB_RSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){ - opus_int32 ret; - ret = a - (b >> shift); - if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a - (((opus_int64)b) >> shift)) ) - { - fprintf (stderr, "silk_SUB_RSHIFT32(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return ret; /* shift > 0 */ -} - -#undef silk_RSHIFT_ROUND -#define silk_RSHIFT_ROUND(a,b) silk_RSHIFT_ROUND_((a), (b), __FILE__, __LINE__) -static inline opus_int32 silk_RSHIFT_ROUND_(opus_int32 a, opus_int32 shift, char *file, int line){ - opus_int32 ret; - ret = shift == 1 ? (a >> 1) + (a & 1) : ((a >> (shift - 1)) + 1) >> 1; - /* the marco definition can't handle a shift of zero */ - if ( (shift <= 0) || (shift>31) || ((opus_int64)ret != ((opus_int64)a + ((opus_int64)1 << (shift - 1))) >> shift) ) - { - fprintf (stderr, "silk_RSHIFT_ROUND(%d, %d) in %s: line %d\n", a, shift, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return ret; -} - -#undef silk_RSHIFT_ROUND64 -#define silk_RSHIFT_ROUND64(a,b) silk_RSHIFT_ROUND64_((a), (b), __FILE__, __LINE__) -static inline opus_int64 silk_RSHIFT_ROUND64_(opus_int64 a, opus_int32 shift, char *file, int line){ - opus_int64 ret; - /* the marco definition can't handle a shift of zero */ - if ( (shift <= 0) || (shift>=64) ) - { - fprintf (stderr, "silk_RSHIFT_ROUND64(%lld, %d) in %s: line %d\n", (long long)a, shift, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - ret = shift == 1 ? (a >> 1) + (a & 1) : ((a >> (shift - 1)) + 1) >> 1; - return ret; -} - -/* silk_abs is used on floats also, so doesn't work... */ -/*#undef silk_abs -static inline opus_int32 silk_abs(opus_int32 a){ - silk_assert(a != 0x80000000); - return (((a) > 0) ? (a) : -(a)); // Be careful, silk_abs returns wrong when input equals to silk_intXX_MIN -}*/ - -#undef silk_abs_int64 -#define silk_abs_int64(a) silk_abs_int64_((a), __FILE__, __LINE__) -static inline opus_int64 silk_abs_int64_(opus_int64 a, char *file, int line){ - if ( a == silk_int64_MIN ) - { - fprintf (stderr, "silk_abs_int64(%lld) in %s: line %d\n", (long long)a, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return (((a) > 0) ? (a) : -(a)); /* Be careful, silk_abs returns wrong when input equals to silk_intXX_MIN */ -} - -#undef silk_abs_int32 -#define silk_abs_int32(a) silk_abs_int32_((a), __FILE__, __LINE__) -static inline opus_int32 silk_abs_int32_(opus_int32 a, char *file, int line){ - if ( a == silk_int32_MIN ) - { - fprintf (stderr, "silk_abs_int32(%d) in %s: line %d\n", a, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return silk_abs(a); -} - -#undef silk_CHECK_FIT8 -#define silk_CHECK_FIT8(a) silk_CHECK_FIT8_((a), __FILE__, __LINE__) -static inline opus_int8 silk_CHECK_FIT8_( opus_int64 a, char *file, int line ){ - opus_int8 ret; - ret = (opus_int8)a; - if ( (opus_int64)ret != a ) - { - fprintf (stderr, "silk_CHECK_FIT8(%lld) in %s: line %d\n", (long long)a, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return( ret ); -} - -#undef silk_CHECK_FIT16 -#define silk_CHECK_FIT16(a) silk_CHECK_FIT16_((a), __FILE__, __LINE__) -static inline opus_int16 silk_CHECK_FIT16_( opus_int64 a, char *file, int line ){ - opus_int16 ret; - ret = (opus_int16)a; - if ( (opus_int64)ret != a ) - { - fprintf (stderr, "silk_CHECK_FIT16(%lld) in %s: line %d\n", (long long)a, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return( ret ); -} - -#undef silk_CHECK_FIT32 -#define silk_CHECK_FIT32(a) silk_CHECK_FIT32_((a), __FILE__, __LINE__) -static inline opus_int32 silk_CHECK_FIT32_( opus_int64 a, char *file, int line ){ - opus_int32 ret; - ret = (opus_int32)a; - if ( (opus_int64)ret != a ) - { - fprintf (stderr, "silk_CHECK_FIT32(%lld) in %s: line %d\n", (long long)a, file, line); -#ifdef FIXED_DEBUG_ASSERT - silk_assert( 0 ); -#endif - } - return( ret ); -} - -/* no checking for silk_NSHIFT_MUL_32_32 - no checking for silk_NSHIFT_MUL_16_16 - no checking needed for silk_min - no checking needed for silk_max - no checking needed for silk_sign -*/ - -#endif -#endif /* MACRO_DEBUG_H */ diff --git a/src/opus-1.0.2/silk/NLSF2A.c b/src/opus-1.0.2/silk/NLSF2A.c deleted file mode 100644 index 10b66b64..00000000 --- a/src/opus-1.0.2/silk/NLSF2A.c +++ /dev/null @@ -1,178 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* conversion between prediction filter coefficients and LSFs */ -/* order should be even */ -/* a piecewise linear approximation maps LSF <-> cos(LSF) */ -/* therefore the result is not accurate LSFs, but the two */ -/* functions are accurate inverses of each other */ - -#include "SigProc_FIX.h" -#include "tables.h" - -#define QA 16 - -/* helper function for NLSF2A(..) */ -static inline void silk_NLSF2A_find_poly( - opus_int32 *out, /* O intermediate polynomial, QA [dd+1] */ - const opus_int32 *cLSF, /* I vector of interleaved 2*cos(LSFs), QA [d] */ - opus_int dd /* I polynomial order (= 1/2 * filter order) */ -) -{ - opus_int k, n; - opus_int32 ftmp; - - out[0] = silk_LSHIFT( 1, QA ); - out[1] = -cLSF[0]; - for( k = 1; k < dd; k++ ) { - ftmp = cLSF[2*k]; /* QA*/ - out[k+1] = silk_LSHIFT( out[k-1], 1 ) - (opus_int32)silk_RSHIFT_ROUND64( silk_SMULL( ftmp, out[k] ), QA ); - for( n = k; n > 1; n-- ) { - out[n] += out[n-2] - (opus_int32)silk_RSHIFT_ROUND64( silk_SMULL( ftmp, out[n-1] ), QA ); - } - out[1] -= ftmp; - } -} - -/* compute whitening filter coefficients from normalized line spectral frequencies */ -void silk_NLSF2A( - opus_int16 *a_Q12, /* O monic whitening filter coefficients in Q12, [ d ] */ - const opus_int16 *NLSF, /* I normalized line spectral frequencies in Q15, [ d ] */ - const opus_int d /* I filter order (should be even) */ -) -{ - /* This ordering was found to maximize quality. It improves numerical accuracy of - silk_NLSF2A_find_poly() compared to "standard" ordering. */ - static const unsigned char ordering16[16] = { - 0, 15, 8, 7, 4, 11, 12, 3, 2, 13, 10, 5, 6, 9, 14, 1 - }; - static const unsigned char ordering10[10] = { - 0, 9, 6, 3, 4, 5, 8, 1, 2, 7 - }; - const unsigned char *ordering; - opus_int k, i, dd; - opus_int32 cos_LSF_QA[ SILK_MAX_ORDER_LPC ]; - opus_int32 P[ SILK_MAX_ORDER_LPC / 2 + 1 ], Q[ SILK_MAX_ORDER_LPC / 2 + 1 ]; - opus_int32 Ptmp, Qtmp, f_int, f_frac, cos_val, delta; - opus_int32 a32_QA1[ SILK_MAX_ORDER_LPC ]; - opus_int32 maxabs, absval, idx=0, sc_Q16; - - silk_assert( LSF_COS_TAB_SZ_FIX == 128 ); - silk_assert( d==10||d==16 ); - - /* convert LSFs to 2*cos(LSF), using piecewise linear curve from table */ - ordering = d == 16 ? ordering16 : ordering10; - for( k = 0; k < d; k++ ) { - silk_assert(NLSF[k] >= 0 ); - - /* f_int on a scale 0-127 (rounded down) */ - f_int = silk_RSHIFT( NLSF[k], 15 - 7 ); - - /* f_frac, range: 0..255 */ - f_frac = NLSF[k] - silk_LSHIFT( f_int, 15 - 7 ); - - silk_assert(f_int >= 0); - silk_assert(f_int < LSF_COS_TAB_SZ_FIX ); - - /* Read start and end value from table */ - cos_val = silk_LSFCosTab_FIX_Q12[ f_int ]; /* Q12 */ - delta = silk_LSFCosTab_FIX_Q12[ f_int + 1 ] - cos_val; /* Q12, with a range of 0..200 */ - - /* Linear interpolation */ - cos_LSF_QA[ordering[k]] = silk_RSHIFT_ROUND( silk_LSHIFT( cos_val, 8 ) + silk_MUL( delta, f_frac ), 20 - QA ); /* QA */ - } - - dd = silk_RSHIFT( d, 1 ); - - /* generate even and odd polynomials using convolution */ - silk_NLSF2A_find_poly( P, &cos_LSF_QA[ 0 ], dd ); - silk_NLSF2A_find_poly( Q, &cos_LSF_QA[ 1 ], dd ); - - /* convert even and odd polynomials to opus_int32 Q12 filter coefs */ - for( k = 0; k < dd; k++ ) { - Ptmp = P[ k+1 ] + P[ k ]; - Qtmp = Q[ k+1 ] - Q[ k ]; - - /* the Ptmp and Qtmp values at this stage need to fit in int32 */ - a32_QA1[ k ] = -Qtmp - Ptmp; /* QA+1 */ - a32_QA1[ d-k-1 ] = Qtmp - Ptmp; /* QA+1 */ - } - - /* Limit the maximum absolute value of the prediction coefficients, so that they'll fit in int16 */ - for( i = 0; i < 10; i++ ) { - /* Find maximum absolute value and its index */ - maxabs = 0; - for( k = 0; k < d; k++ ) { - absval = silk_abs( a32_QA1[k] ); - if( absval > maxabs ) { - maxabs = absval; - idx = k; - } - } - maxabs = silk_RSHIFT_ROUND( maxabs, QA + 1 - 12 ); /* QA+1 -> Q12 */ - - if( maxabs > silk_int16_MAX ) { - /* Reduce magnitude of prediction coefficients */ - maxabs = silk_min( maxabs, 163838 ); /* ( silk_int32_MAX >> 14 ) + silk_int16_MAX = 163838 */ - sc_Q16 = SILK_FIX_CONST( 0.999, 16 ) - silk_DIV32( silk_LSHIFT( maxabs - silk_int16_MAX, 14 ), - silk_RSHIFT32( silk_MUL( maxabs, idx + 1), 2 ) ); - silk_bwexpander_32( a32_QA1, d, sc_Q16 ); - } else { - break; - } - } - - if( i == 10 ) { - /* Reached the last iteration, clip the coefficients */ - for( k = 0; k < d; k++ ) { - a_Q12[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ) ); /* QA+1 -> Q12 */ - a32_QA1[ k ] = silk_LSHIFT( (opus_int32)a_Q12[ k ], QA + 1 - 12 ); - } - } else { - for( k = 0; k < d; k++ ) { - a_Q12[ k ] = (opus_int16)silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ); /* QA+1 -> Q12 */ - } - } - - for( i = 0; i < MAX_LPC_STABILIZE_ITERATIONS; i++ ) { - if( silk_LPC_inverse_pred_gain( a_Q12, d ) < SILK_FIX_CONST( 1.0 / MAX_PREDICTION_POWER_GAIN, 30 ) ) { - /* Prediction coefficients are (too close to) unstable; apply bandwidth expansion */ - /* on the unscaled coefficients, convert to Q12 and measure again */ - silk_bwexpander_32( a32_QA1, d, 65536 - silk_LSHIFT( 2, i ) ); - for( k = 0; k < d; k++ ) { - a_Q12[ k ] = (opus_int16)silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ); /* QA+1 -> Q12 */ - } - } else { - break; - } - } -} - diff --git a/src/opus-1.0.2/silk/NLSF_VQ.c b/src/opus-1.0.2/silk/NLSF_VQ.c deleted file mode 100644 index 352dda26..00000000 --- a/src/opus-1.0.2/silk/NLSF_VQ.c +++ /dev/null @@ -1,68 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main.h" - -/* Compute quantization errors for an LPC_order element input vector for a VQ codebook */ -void silk_NLSF_VQ( - opus_int32 err_Q26[], /* O Quantization errors [K] */ - const opus_int16 in_Q15[], /* I Input vectors to be quantized [LPC_order] */ - const opus_uint8 pCB_Q8[], /* I Codebook vectors [K*LPC_order] */ - const opus_int K, /* I Number of codebook vectors */ - const opus_int LPC_order /* I Number of LPCs */ -) -{ - opus_int i, m; - opus_int32 diff_Q15, sum_error_Q30, sum_error_Q26; - - silk_assert( LPC_order <= 16 ); - silk_assert( ( LPC_order & 1 ) == 0 ); - - /* Loop over codebook */ - for( i = 0; i < K; i++ ) { - sum_error_Q26 = 0; - for( m = 0; m < LPC_order; m += 2 ) { - /* Compute weighted squared quantization error for index m */ - diff_Q15 = silk_SUB_LSHIFT32( in_Q15[ m ], (opus_int32)*pCB_Q8++, 7 ); /* range: [ -32767 : 32767 ]*/ - sum_error_Q30 = silk_SMULBB( diff_Q15, diff_Q15 ); - - /* Compute weighted squared quantization error for index m + 1 */ - diff_Q15 = silk_SUB_LSHIFT32( in_Q15[m + 1], (opus_int32)*pCB_Q8++, 7 ); /* range: [ -32767 : 32767 ]*/ - sum_error_Q30 = silk_SMLABB( sum_error_Q30, diff_Q15, diff_Q15 ); - - sum_error_Q26 = silk_ADD_RSHIFT32( sum_error_Q26, sum_error_Q30, 4 ); - - silk_assert( sum_error_Q26 >= 0 ); - silk_assert( sum_error_Q30 >= 0 ); - } - err_Q26[ i ] = sum_error_Q26; - } -} diff --git a/src/opus-1.0.2/silk/NLSF_VQ_weights_laroia.c b/src/opus-1.0.2/silk/NLSF_VQ_weights_laroia.c deleted file mode 100644 index 05bb17af..00000000 --- a/src/opus-1.0.2/silk/NLSF_VQ_weights_laroia.c +++ /dev/null @@ -1,80 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "define.h" -#include "SigProc_FIX.h" - -/* -R. Laroia, N. Phamdo and N. Farvardin, "Robust and Efficient Quantization of Speech LSP -Parameters Using Structured Vector Quantization", Proc. IEEE Int. Conf. Acoust., Speech, -Signal Processing, pp. 641-644, 1991. -*/ - -/* Laroia low complexity NLSF weights */ -void silk_NLSF_VQ_weights_laroia( - opus_int16 *pNLSFW_Q_OUT, /* O Pointer to input vector weights [D] */ - const opus_int16 *pNLSF_Q15, /* I Pointer to input vector [D] */ - const opus_int D /* I Input vector dimension (even) */ -) -{ - opus_int k; - opus_int32 tmp1_int, tmp2_int; - - silk_assert( D > 0 ); - silk_assert( ( D & 1 ) == 0 ); - - /* First value */ - tmp1_int = silk_max_int( pNLSF_Q15[ 0 ], 1 ); - tmp1_int = silk_DIV32_16( (opus_int32)1 << ( 15 + NLSF_W_Q ), tmp1_int ); - tmp2_int = silk_max_int( pNLSF_Q15[ 1 ] - pNLSF_Q15[ 0 ], 1 ); - tmp2_int = silk_DIV32_16( (opus_int32)1 << ( 15 + NLSF_W_Q ), tmp2_int ); - pNLSFW_Q_OUT[ 0 ] = (opus_int16)silk_min_int( tmp1_int + tmp2_int, silk_int16_MAX ); - silk_assert( pNLSFW_Q_OUT[ 0 ] > 0 ); - - /* Main loop */ - for( k = 1; k < D - 1; k += 2 ) { - tmp1_int = silk_max_int( pNLSF_Q15[ k + 1 ] - pNLSF_Q15[ k ], 1 ); - tmp1_int = silk_DIV32_16( (opus_int32)1 << ( 15 + NLSF_W_Q ), tmp1_int ); - pNLSFW_Q_OUT[ k ] = (opus_int16)silk_min_int( tmp1_int + tmp2_int, silk_int16_MAX ); - silk_assert( pNLSFW_Q_OUT[ k ] > 0 ); - - tmp2_int = silk_max_int( pNLSF_Q15[ k + 2 ] - pNLSF_Q15[ k + 1 ], 1 ); - tmp2_int = silk_DIV32_16( (opus_int32)1 << ( 15 + NLSF_W_Q ), tmp2_int ); - pNLSFW_Q_OUT[ k + 1 ] = (opus_int16)silk_min_int( tmp1_int + tmp2_int, silk_int16_MAX ); - silk_assert( pNLSFW_Q_OUT[ k + 1 ] > 0 ); - } - - /* Last value */ - tmp1_int = silk_max_int( ( 1 << 15 ) - pNLSF_Q15[ D - 1 ], 1 ); - tmp1_int = silk_DIV32_16( (opus_int32)1 << ( 15 + NLSF_W_Q ), tmp1_int ); - pNLSFW_Q_OUT[ D - 1 ] = (opus_int16)silk_min_int( tmp1_int + tmp2_int, silk_int16_MAX ); - silk_assert( pNLSFW_Q_OUT[ D - 1 ] > 0 ); -} diff --git a/src/opus-1.0.2/silk/NLSF_decode.c b/src/opus-1.0.2/silk/NLSF_decode.c deleted file mode 100644 index e007c49a..00000000 --- a/src/opus-1.0.2/silk/NLSF_decode.c +++ /dev/null @@ -1,101 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main.h" - -/* Predictive dequantizer for NLSF residuals */ -static inline void silk_NLSF_residual_dequant( /* O Returns RD value in Q30 */ - opus_int16 x_Q10[], /* O Output [ order ] */ - const opus_int8 indices[], /* I Quantization indices [ order ] */ - const opus_uint8 pred_coef_Q8[], /* I Backward predictor coefs [ order ] */ - const opus_int quant_step_size_Q16, /* I Quantization step size */ - const opus_int16 order /* I Number of input values */ -) -{ - opus_int i, out_Q10, pred_Q10; - - out_Q10 = 0; - for( i = order-1; i >= 0; i-- ) { - pred_Q10 = silk_RSHIFT( silk_SMULBB( out_Q10, (opus_int16)pred_coef_Q8[ i ] ), 8 ); - out_Q10 = silk_LSHIFT( indices[ i ], 10 ); - if( out_Q10 > 0 ) { - out_Q10 = silk_SUB16( out_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) ); - } else if( out_Q10 < 0 ) { - out_Q10 = silk_ADD16( out_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) ); - } - out_Q10 = silk_SMLAWB( pred_Q10, (opus_int32)out_Q10, quant_step_size_Q16 ); - x_Q10[ i ] = out_Q10; - } -} - - -/***********************/ -/* NLSF vector decoder */ -/***********************/ -void silk_NLSF_decode( - opus_int16 *pNLSF_Q15, /* O Quantized NLSF vector [ LPC_ORDER ] */ - opus_int8 *NLSFIndices, /* I Codebook path vector [ LPC_ORDER + 1 ] */ - const silk_NLSF_CB_struct *psNLSF_CB /* I Codebook object */ -) -{ - opus_int i; - opus_uint8 pred_Q8[ MAX_LPC_ORDER ]; - opus_int16 ec_ix[ MAX_LPC_ORDER ]; - opus_int16 res_Q10[ MAX_LPC_ORDER ]; - opus_int16 W_tmp_QW[ MAX_LPC_ORDER ]; - opus_int32 W_tmp_Q9, NLSF_Q15_tmp; - const opus_uint8 *pCB_element; - - /* Decode first stage */ - pCB_element = &psNLSF_CB->CB1_NLSF_Q8[ NLSFIndices[ 0 ] * psNLSF_CB->order ]; - for( i = 0; i < psNLSF_CB->order; i++ ) { - pNLSF_Q15[ i ] = silk_LSHIFT( (opus_int16)pCB_element[ i ], 7 ); - } - - /* Unpack entropy table indices and predictor for current CB1 index */ - silk_NLSF_unpack( ec_ix, pred_Q8, psNLSF_CB, NLSFIndices[ 0 ] ); - - /* Predictive residual dequantizer */ - silk_NLSF_residual_dequant( res_Q10, &NLSFIndices[ 1 ], pred_Q8, psNLSF_CB->quantStepSize_Q16, psNLSF_CB->order ); - - /* Weights from codebook vector */ - silk_NLSF_VQ_weights_laroia( W_tmp_QW, pNLSF_Q15, psNLSF_CB->order ); - - /* Apply inverse square-rooted weights and add to output */ - for( i = 0; i < psNLSF_CB->order; i++ ) { - W_tmp_Q9 = silk_SQRT_APPROX( silk_LSHIFT( (opus_int32)W_tmp_QW[ i ], 18 - NLSF_W_Q ) ); - NLSF_Q15_tmp = silk_ADD32( pNLSF_Q15[ i ], silk_DIV32_16( silk_LSHIFT( (opus_int32)res_Q10[ i ], 14 ), W_tmp_Q9 ) ); - pNLSF_Q15[ i ] = (opus_int16)silk_LIMIT( NLSF_Q15_tmp, 0, 32767 ); - } - - /* NLSF stabilization */ - silk_NLSF_stabilize( pNLSF_Q15, psNLSF_CB->deltaMin_Q15, psNLSF_CB->order ); -} diff --git a/src/opus-1.0.2/silk/NLSF_del_dec_quant.c b/src/opus-1.0.2/silk/NLSF_del_dec_quant.c deleted file mode 100644 index 78870de5..00000000 --- a/src/opus-1.0.2/silk/NLSF_del_dec_quant.c +++ /dev/null @@ -1,207 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main.h" - -/* Delayed-decision quantizer for NLSF residuals */ -opus_int32 silk_NLSF_del_dec_quant( /* O Returns RD value in Q25 */ - opus_int8 indices[], /* O Quantization indices [ order ] */ - const opus_int16 x_Q10[], /* I Input [ order ] */ - const opus_int16 w_Q5[], /* I Weights [ order ] */ - const opus_uint8 pred_coef_Q8[], /* I Backward predictor coefs [ order ] */ - const opus_int16 ec_ix[], /* I Indices to entropy coding tables [ order ] */ - const opus_uint8 ec_rates_Q5[], /* I Rates [] */ - const opus_int quant_step_size_Q16, /* I Quantization step size */ - const opus_int16 inv_quant_step_size_Q6, /* I Inverse quantization step size */ - const opus_int32 mu_Q20, /* I R/D tradeoff */ - const opus_int16 order /* I Number of input values */ -) -{ - opus_int i, j, nStates, ind_tmp, ind_min_max, ind_max_min, in_Q10, res_Q10; - opus_int pred_Q10, diff_Q10, out0_Q10, out1_Q10, rate0_Q5, rate1_Q5; - opus_int32 RD_tmp_Q25, min_Q25, min_max_Q25, max_min_Q25, pred_coef_Q16; - opus_int ind_sort[ NLSF_QUANT_DEL_DEC_STATES ]; - opus_int8 ind[ NLSF_QUANT_DEL_DEC_STATES ][ MAX_LPC_ORDER ]; - opus_int16 prev_out_Q10[ 2 * NLSF_QUANT_DEL_DEC_STATES ]; - opus_int32 RD_Q25[ 2 * NLSF_QUANT_DEL_DEC_STATES ]; - opus_int32 RD_min_Q25[ NLSF_QUANT_DEL_DEC_STATES ]; - opus_int32 RD_max_Q25[ NLSF_QUANT_DEL_DEC_STATES ]; - const opus_uint8 *rates_Q5; - - silk_assert( (NLSF_QUANT_DEL_DEC_STATES & (NLSF_QUANT_DEL_DEC_STATES-1)) == 0 ); /* must be power of two */ - - nStates = 1; - RD_Q25[ 0 ] = 0; - prev_out_Q10[ 0 ] = 0; - for( i = order - 1; ; i-- ) { - rates_Q5 = &ec_rates_Q5[ ec_ix[ i ] ]; - pred_coef_Q16 = silk_LSHIFT( (opus_int32)pred_coef_Q8[ i ], 8 ); - in_Q10 = x_Q10[ i ]; - for( j = 0; j < nStates; j++ ) { - pred_Q10 = silk_SMULWB( pred_coef_Q16, prev_out_Q10[ j ] ); - res_Q10 = silk_SUB16( in_Q10, pred_Q10 ); - ind_tmp = silk_SMULWB( (opus_int32)inv_quant_step_size_Q6, res_Q10 ); - ind_tmp = silk_LIMIT( ind_tmp, -NLSF_QUANT_MAX_AMPLITUDE_EXT, NLSF_QUANT_MAX_AMPLITUDE_EXT-1 ); - ind[ j ][ i ] = (opus_int8)ind_tmp; - - /* compute outputs for ind_tmp and ind_tmp + 1 */ - out0_Q10 = silk_LSHIFT( ind_tmp, 10 ); - out1_Q10 = silk_ADD16( out0_Q10, 1024 ); - if( ind_tmp > 0 ) { - out0_Q10 = silk_SUB16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) ); - out1_Q10 = silk_SUB16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) ); - } else if( ind_tmp == 0 ) { - out1_Q10 = silk_SUB16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) ); - } else if( ind_tmp == -1 ) { - out0_Q10 = silk_ADD16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) ); - } else { - out0_Q10 = silk_ADD16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) ); - out1_Q10 = silk_ADD16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) ); - } - out0_Q10 = silk_SMULWB( (opus_int32)out0_Q10, quant_step_size_Q16 ); - out1_Q10 = silk_SMULWB( (opus_int32)out1_Q10, quant_step_size_Q16 ); - out0_Q10 = silk_ADD16( out0_Q10, pred_Q10 ); - out1_Q10 = silk_ADD16( out1_Q10, pred_Q10 ); - prev_out_Q10[ j ] = out0_Q10; - prev_out_Q10[ j + nStates ] = out1_Q10; - - /* compute RD for ind_tmp and ind_tmp + 1 */ - if( ind_tmp + 1 >= NLSF_QUANT_MAX_AMPLITUDE ) { - if( ind_tmp + 1 == NLSF_QUANT_MAX_AMPLITUDE ) { - rate0_Q5 = rates_Q5[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE ]; - rate1_Q5 = 280; - } else { - rate0_Q5 = silk_SMLABB( 280 - 43 * NLSF_QUANT_MAX_AMPLITUDE, 43, ind_tmp ); - rate1_Q5 = silk_ADD16( rate0_Q5, 43 ); - } - } else if( ind_tmp <= -NLSF_QUANT_MAX_AMPLITUDE ) { - if( ind_tmp == -NLSF_QUANT_MAX_AMPLITUDE ) { - rate0_Q5 = 280; - rate1_Q5 = rates_Q5[ ind_tmp + 1 + NLSF_QUANT_MAX_AMPLITUDE ]; - } else { - rate0_Q5 = silk_SMLABB( 280 - 43 * NLSF_QUANT_MAX_AMPLITUDE, -43, ind_tmp ); - rate1_Q5 = silk_SUB16( rate0_Q5, 43 ); - } - } else { - rate0_Q5 = rates_Q5[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE ]; - rate1_Q5 = rates_Q5[ ind_tmp + 1 + NLSF_QUANT_MAX_AMPLITUDE ]; - } - RD_tmp_Q25 = RD_Q25[ j ]; - diff_Q10 = silk_SUB16( in_Q10, out0_Q10 ); - RD_Q25[ j ] = silk_SMLABB( silk_MLA( RD_tmp_Q25, silk_SMULBB( diff_Q10, diff_Q10 ), w_Q5[ i ] ), mu_Q20, rate0_Q5 ); - diff_Q10 = silk_SUB16( in_Q10, out1_Q10 ); - RD_Q25[ j + nStates ] = silk_SMLABB( silk_MLA( RD_tmp_Q25, silk_SMULBB( diff_Q10, diff_Q10 ), w_Q5[ i ] ), mu_Q20, rate1_Q5 ); - } - - if( nStates < NLSF_QUANT_DEL_DEC_STATES ) { - /* double number of states and copy */ - for( j = 0; j < nStates; j++ ) { - ind[ j + nStates ][ i ] = ind[ j ][ i ] + 1; - } - nStates = silk_LSHIFT( nStates, 1 ); - for( j = nStates; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) { - ind[ j ][ i ] = ind[ j - nStates ][ i ]; - } - } else if( i > 0 ) { - /* sort lower and upper half of RD_Q25, pairwise */ - for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) { - if( RD_Q25[ j ] > RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ] ) { - RD_max_Q25[ j ] = RD_Q25[ j ]; - RD_min_Q25[ j ] = RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ]; - RD_Q25[ j ] = RD_min_Q25[ j ]; - RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ] = RD_max_Q25[ j ]; - /* swap prev_out values */ - out0_Q10 = prev_out_Q10[ j ]; - prev_out_Q10[ j ] = prev_out_Q10[ j + NLSF_QUANT_DEL_DEC_STATES ]; - prev_out_Q10[ j + NLSF_QUANT_DEL_DEC_STATES ] = out0_Q10; - ind_sort[ j ] = j + NLSF_QUANT_DEL_DEC_STATES; - } else { - RD_min_Q25[ j ] = RD_Q25[ j ]; - RD_max_Q25[ j ] = RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ]; - ind_sort[ j ] = j; - } - } - /* compare the highest RD values of the winning half with the lowest one in the losing half, and copy if necessary */ - /* afterwards ind_sort[] will contain the indices of the NLSF_QUANT_DEL_DEC_STATES winning RD values */ - while( 1 ) { - min_max_Q25 = silk_int32_MAX; - max_min_Q25 = 0; - ind_min_max = 0; - ind_max_min = 0; - for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) { - if( min_max_Q25 > RD_max_Q25[ j ] ) { - min_max_Q25 = RD_max_Q25[ j ]; - ind_min_max = j; - } - if( max_min_Q25 < RD_min_Q25[ j ] ) { - max_min_Q25 = RD_min_Q25[ j ]; - ind_max_min = j; - } - } - if( min_max_Q25 >= max_min_Q25 ) { - break; - } - /* copy ind_min_max to ind_max_min */ - ind_sort[ ind_max_min ] = ind_sort[ ind_min_max ] ^ NLSF_QUANT_DEL_DEC_STATES; - RD_Q25[ ind_max_min ] = RD_Q25[ ind_min_max + NLSF_QUANT_DEL_DEC_STATES ]; - prev_out_Q10[ ind_max_min ] = prev_out_Q10[ ind_min_max + NLSF_QUANT_DEL_DEC_STATES ]; - RD_min_Q25[ ind_max_min ] = 0; - RD_max_Q25[ ind_min_max ] = silk_int32_MAX; - silk_memcpy( ind[ ind_max_min ], ind[ ind_min_max ], MAX_LPC_ORDER * sizeof( opus_int8 ) ); - } - /* increment index if it comes from the upper half */ - for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) { - ind[ j ][ i ] += silk_RSHIFT( ind_sort[ j ], NLSF_QUANT_DEL_DEC_STATES_LOG2 ); - } - } else { /* i == 0 */ - break; - } - } - - /* last sample: find winner, copy indices and return RD value */ - ind_tmp = 0; - min_Q25 = silk_int32_MAX; - for( j = 0; j < 2 * NLSF_QUANT_DEL_DEC_STATES; j++ ) { - if( min_Q25 > RD_Q25[ j ] ) { - min_Q25 = RD_Q25[ j ]; - ind_tmp = j; - } - } - for( j = 0; j < order; j++ ) { - indices[ j ] = ind[ ind_tmp & ( NLSF_QUANT_DEL_DEC_STATES - 1 ) ][ j ]; - silk_assert( indices[ j ] >= -NLSF_QUANT_MAX_AMPLITUDE_EXT ); - silk_assert( indices[ j ] <= NLSF_QUANT_MAX_AMPLITUDE_EXT ); - } - indices[ 0 ] += silk_RSHIFT( ind_tmp, NLSF_QUANT_DEL_DEC_STATES_LOG2 ); - silk_assert( indices[ 0 ] <= NLSF_QUANT_MAX_AMPLITUDE_EXT ); - silk_assert( min_Q25 >= 0 ); - return min_Q25; -} diff --git a/src/opus-1.0.2/silk/NLSF_encode.c b/src/opus-1.0.2/silk/NLSF_encode.c deleted file mode 100644 index 52a263d9..00000000 --- a/src/opus-1.0.2/silk/NLSF_encode.c +++ /dev/null @@ -1,128 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main.h" - -/***********************/ -/* NLSF vector encoder */ -/***********************/ -opus_int32 silk_NLSF_encode( /* O Returns RD value in Q25 */ - opus_int8 *NLSFIndices, /* I Codebook path vector [ LPC_ORDER + 1 ] */ - opus_int16 *pNLSF_Q15, /* I/O Quantized NLSF vector [ LPC_ORDER ] */ - const silk_NLSF_CB_struct *psNLSF_CB, /* I Codebook object */ - const opus_int16 *pW_QW, /* I NLSF weight vector [ LPC_ORDER ] */ - const opus_int NLSF_mu_Q20, /* I Rate weight for the RD optimization */ - const opus_int nSurvivors, /* I Max survivors after first stage */ - const opus_int signalType /* I Signal type: 0/1/2 */ -) -{ - opus_int i, s, ind1, bestIndex, prob_Q8, bits_q7; - opus_int32 W_tmp_Q9; - opus_int32 err_Q26[ NLSF_VQ_MAX_VECTORS ]; - opus_int32 RD_Q25[ NLSF_VQ_MAX_SURVIVORS ]; - opus_int tempIndices1[ NLSF_VQ_MAX_SURVIVORS ]; - opus_int8 tempIndices2[ NLSF_VQ_MAX_SURVIVORS * MAX_LPC_ORDER ]; - opus_int16 res_Q15[ MAX_LPC_ORDER ]; - opus_int16 res_Q10[ MAX_LPC_ORDER ]; - opus_int16 NLSF_tmp_Q15[ MAX_LPC_ORDER ]; - opus_int16 W_tmp_QW[ MAX_LPC_ORDER ]; - opus_int16 W_adj_Q5[ MAX_LPC_ORDER ]; - opus_uint8 pred_Q8[ MAX_LPC_ORDER ]; - opus_int16 ec_ix[ MAX_LPC_ORDER ]; - const opus_uint8 *pCB_element, *iCDF_ptr; - - silk_assert( nSurvivors <= NLSF_VQ_MAX_SURVIVORS ); - silk_assert( signalType >= 0 && signalType <= 2 ); - silk_assert( NLSF_mu_Q20 <= 32767 && NLSF_mu_Q20 >= 0 ); - - /* NLSF stabilization */ - silk_NLSF_stabilize( pNLSF_Q15, psNLSF_CB->deltaMin_Q15, psNLSF_CB->order ); - - /* First stage: VQ */ - silk_NLSF_VQ( err_Q26, pNLSF_Q15, psNLSF_CB->CB1_NLSF_Q8, psNLSF_CB->nVectors, psNLSF_CB->order ); - - /* Sort the quantization errors */ - silk_insertion_sort_increasing( err_Q26, tempIndices1, psNLSF_CB->nVectors, nSurvivors ); - - /* Loop over survivors */ - for( s = 0; s < nSurvivors; s++ ) { - ind1 = tempIndices1[ s ]; - - /* Residual after first stage */ - pCB_element = &psNLSF_CB->CB1_NLSF_Q8[ ind1 * psNLSF_CB->order ]; - for( i = 0; i < psNLSF_CB->order; i++ ) { - NLSF_tmp_Q15[ i ] = silk_LSHIFT16( (opus_int16)pCB_element[ i ], 7 ); - res_Q15[ i ] = pNLSF_Q15[ i ] - NLSF_tmp_Q15[ i ]; - } - - /* Weights from codebook vector */ - silk_NLSF_VQ_weights_laroia( W_tmp_QW, NLSF_tmp_Q15, psNLSF_CB->order ); - - /* Apply square-rooted weights */ - for( i = 0; i < psNLSF_CB->order; i++ ) { - W_tmp_Q9 = silk_SQRT_APPROX( silk_LSHIFT( (opus_int32)W_tmp_QW[ i ], 18 - NLSF_W_Q ) ); - res_Q10[ i ] = (opus_int16)silk_RSHIFT( silk_SMULBB( res_Q15[ i ], W_tmp_Q9 ), 14 ); - } - - /* Modify input weights accordingly */ - for( i = 0; i < psNLSF_CB->order; i++ ) { - W_adj_Q5[ i ] = silk_DIV32_16( silk_LSHIFT( (opus_int32)pW_QW[ i ], 5 ), W_tmp_QW[ i ] ); - } - - /* Unpack entropy table indices and predictor for current CB1 index */ - silk_NLSF_unpack( ec_ix, pred_Q8, psNLSF_CB, ind1 ); - - /* Trellis quantizer */ - RD_Q25[ s ] = silk_NLSF_del_dec_quant( &tempIndices2[ s * MAX_LPC_ORDER ], res_Q10, W_adj_Q5, pred_Q8, ec_ix, - psNLSF_CB->ec_Rates_Q5, psNLSF_CB->quantStepSize_Q16, psNLSF_CB->invQuantStepSize_Q6, NLSF_mu_Q20, psNLSF_CB->order ); - - /* Add rate for first stage */ - iCDF_ptr = &psNLSF_CB->CB1_iCDF[ ( signalType >> 1 ) * psNLSF_CB->nVectors ]; - if( ind1 == 0 ) { - prob_Q8 = 256 - iCDF_ptr[ ind1 ]; - } else { - prob_Q8 = iCDF_ptr[ ind1 - 1 ] - iCDF_ptr[ ind1 ]; - } - bits_q7 = ( 8 << 7 ) - silk_lin2log( prob_Q8 ); - RD_Q25[ s ] = silk_SMLABB( RD_Q25[ s ], bits_q7, silk_RSHIFT( NLSF_mu_Q20, 2 ) ); - } - - /* Find the lowest rate-distortion error */ - silk_insertion_sort_increasing( RD_Q25, &bestIndex, nSurvivors, 1 ); - - NLSFIndices[ 0 ] = (opus_int8)tempIndices1[ bestIndex ]; - silk_memcpy( &NLSFIndices[ 1 ], &tempIndices2[ bestIndex * MAX_LPC_ORDER ], psNLSF_CB->order * sizeof( opus_int8 ) ); - - /* Decode */ - silk_NLSF_decode( pNLSF_Q15, NLSFIndices, psNLSF_CB ); - - return RD_Q25[ 0 ]; -} diff --git a/src/opus-1.0.2/silk/NLSF_stabilize.c b/src/opus-1.0.2/silk/NLSF_stabilize.c deleted file mode 100644 index 7498b54a..00000000 --- a/src/opus-1.0.2/silk/NLSF_stabilize.c +++ /dev/null @@ -1,142 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* NLSF stabilizer: */ -/* */ -/* - Moves NLSFs further apart if they are too close */ -/* - Moves NLSFs away from borders if they are too close */ -/* - High effort to achieve a modification with minimum */ -/* Euclidean distance to input vector */ -/* - Output are sorted NLSF coefficients */ -/* */ - -#include "SigProc_FIX.h" - -/* Constant Definitions */ -#define MAX_LOOPS 20 - -/* NLSF stabilizer, for a single input data vector */ -void silk_NLSF_stabilize( - opus_int16 *NLSF_Q15, /* I/O Unstable/stabilized normalized LSF vector in Q15 [L] */ - const opus_int16 *NDeltaMin_Q15, /* I Min distance vector, NDeltaMin_Q15[L] must be >= 1 [L+1] */ - const opus_int L /* I Number of NLSF parameters in the input vector */ -) -{ - opus_int i, I=0, k, loops; - opus_int16 center_freq_Q15; - opus_int32 diff_Q15, min_diff_Q15, min_center_Q15, max_center_Q15; - - /* This is necessary to ensure an output within range of a opus_int16 */ - silk_assert( NDeltaMin_Q15[L] >= 1 ); - - for( loops = 0; loops < MAX_LOOPS; loops++ ) { - /**************************/ - /* Find smallest distance */ - /**************************/ - /* First element */ - min_diff_Q15 = NLSF_Q15[0] - NDeltaMin_Q15[0]; - I = 0; - /* Middle elements */ - for( i = 1; i <= L-1; i++ ) { - diff_Q15 = NLSF_Q15[i] - ( NLSF_Q15[i-1] + NDeltaMin_Q15[i] ); - if( diff_Q15 < min_diff_Q15 ) { - min_diff_Q15 = diff_Q15; - I = i; - } - } - /* Last element */ - diff_Q15 = ( 1 << 15 ) - ( NLSF_Q15[L-1] + NDeltaMin_Q15[L] ); - if( diff_Q15 < min_diff_Q15 ) { - min_diff_Q15 = diff_Q15; - I = L; - } - - /***************************************************/ - /* Now check if the smallest distance non-negative */ - /***************************************************/ - if( min_diff_Q15 >= 0 ) { - return; - } - - if( I == 0 ) { - /* Move away from lower limit */ - NLSF_Q15[0] = NDeltaMin_Q15[0]; - - } else if( I == L) { - /* Move away from higher limit */ - NLSF_Q15[L-1] = ( 1 << 15 ) - NDeltaMin_Q15[L]; - - } else { - /* Find the lower extreme for the location of the current center frequency */ - min_center_Q15 = 0; - for( k = 0; k < I; k++ ) { - min_center_Q15 += NDeltaMin_Q15[k]; - } - min_center_Q15 += silk_RSHIFT( NDeltaMin_Q15[I], 1 ); - - /* Find the upper extreme for the location of the current center frequency */ - max_center_Q15 = 1 << 15; - for( k = L; k > I; k-- ) { - max_center_Q15 -= NDeltaMin_Q15[k]; - } - max_center_Q15 -= silk_RSHIFT( NDeltaMin_Q15[I], 1 ); - - /* Move apart, sorted by value, keeping the same center frequency */ - center_freq_Q15 = (opus_int16)silk_LIMIT_32( silk_RSHIFT_ROUND( (opus_int32)NLSF_Q15[I-1] + (opus_int32)NLSF_Q15[I], 1 ), - min_center_Q15, max_center_Q15 ); - NLSF_Q15[I-1] = center_freq_Q15 - silk_RSHIFT( NDeltaMin_Q15[I], 1 ); - NLSF_Q15[I] = NLSF_Q15[I-1] + NDeltaMin_Q15[I]; - } - } - - /* Safe and simple fall back method, which is less ideal than the above */ - if( loops == MAX_LOOPS ) - { - /* Insertion sort (fast for already almost sorted arrays): */ - /* Best case: O(n) for an already sorted array */ - /* Worst case: O(n^2) for an inversely sorted array */ - silk_insertion_sort_increasing_all_values_int16( &NLSF_Q15[0], L ); - - /* First NLSF should be no less than NDeltaMin[0] */ - NLSF_Q15[0] = silk_max_int( NLSF_Q15[0], NDeltaMin_Q15[0] ); - - /* Keep delta_min distance between the NLSFs */ - for( i = 1; i < L; i++ ) - NLSF_Q15[i] = silk_max_int( NLSF_Q15[i], NLSF_Q15[i-1] + NDeltaMin_Q15[i] ); - - /* Last NLSF should be no higher than 1 - NDeltaMin[L] */ - NLSF_Q15[L-1] = silk_min_int( NLSF_Q15[L-1], (1<<15) - NDeltaMin_Q15[L] ); - - /* Keep NDeltaMin distance between the NLSFs */ - for( i = L-2; i >= 0; i-- ) - NLSF_Q15[i] = silk_min_int( NLSF_Q15[i], NLSF_Q15[i+1] - NDeltaMin_Q15[i+1] ); - } -} diff --git a/src/opus-1.0.2/silk/NLSF_unpack.c b/src/opus-1.0.2/silk/NLSF_unpack.c deleted file mode 100644 index 47f6cfe8..00000000 --- a/src/opus-1.0.2/silk/NLSF_unpack.c +++ /dev/null @@ -1,55 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main.h" - -/* Unpack predictor values and indices for entropy coding tables */ -void silk_NLSF_unpack( - opus_int16 ec_ix[], /* O Indices to entropy tables [ LPC_ORDER ] */ - opus_uint8 pred_Q8[], /* O LSF predictor [ LPC_ORDER ] */ - const silk_NLSF_CB_struct *psNLSF_CB, /* I Codebook object */ - const opus_int CB1_index /* I Index of vector in first LSF codebook */ -) -{ - opus_int i; - opus_uint8 entry; - const opus_uint8 *ec_sel_ptr; - - ec_sel_ptr = &psNLSF_CB->ec_sel[ CB1_index * psNLSF_CB->order / 2 ]; - for( i = 0; i < psNLSF_CB->order; i += 2 ) { - entry = *ec_sel_ptr++; - ec_ix [ i ] = silk_SMULBB( silk_RSHIFT( entry, 1 ) & 7, 2 * NLSF_QUANT_MAX_AMPLITUDE + 1 ); - pred_Q8[ i ] = psNLSF_CB->pred_Q8[ i + ( entry & 1 ) * ( psNLSF_CB->order - 1 ) ]; - ec_ix [ i + 1 ] = silk_SMULBB( silk_RSHIFT( entry, 5 ) & 7, 2 * NLSF_QUANT_MAX_AMPLITUDE + 1 ); - pred_Q8[ i + 1 ] = psNLSF_CB->pred_Q8[ i + ( silk_RSHIFT( entry, 4 ) & 1 ) * ( psNLSF_CB->order - 1 ) + 1 ]; - } -} - diff --git a/src/opus-1.0.2/silk/NSQ.c b/src/opus-1.0.2/silk/NSQ.c deleted file mode 100644 index b49cdf58..00000000 --- a/src/opus-1.0.2/silk/NSQ.c +++ /dev/null @@ -1,439 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main.h" - -static inline void silk_nsq_scale_states( - const silk_encoder_state *psEncC, /* I Encoder State */ - silk_nsq_state *NSQ, /* I/O NSQ state */ - const opus_int32 x_Q3[], /* I input in Q3 */ - opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */ - const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */ - opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ - opus_int subfr, /* I subframe number */ - const opus_int LTP_scale_Q14, /* I */ - const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ - const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ - const opus_int signal_type /* I Signal type */ -); - -static inline void silk_noise_shape_quantizer( - silk_nsq_state *NSQ, /* I/O NSQ state */ - opus_int signalType, /* I Signal type */ - const opus_int32 x_sc_Q10[], /* I */ - opus_int8 pulses[], /* O */ - opus_int16 xq[], /* O */ - opus_int32 sLTP_Q15[], /* I/O LTP state */ - const opus_int16 a_Q12[], /* I Short term prediction coefs */ - const opus_int16 b_Q14[], /* I Long term prediction coefs */ - const opus_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */ - opus_int lag, /* I Pitch lag */ - opus_int32 HarmShapeFIRPacked_Q14, /* I */ - opus_int Tilt_Q14, /* I Spectral tilt */ - opus_int32 LF_shp_Q14, /* I */ - opus_int32 Gain_Q16, /* I */ - opus_int Lambda_Q10, /* I */ - opus_int offset_Q10, /* I */ - opus_int length, /* I Input length */ - opus_int shapingLPCOrder, /* I Noise shaping AR filter order */ - opus_int predictLPCOrder /* I Prediction filter order */ -); - -void silk_NSQ( - const silk_encoder_state *psEncC, /* I/O Encoder State */ - silk_nsq_state *NSQ, /* I/O NSQ state */ - SideInfoIndices *psIndices, /* I/O Quantization Indices */ - const opus_int32 x_Q3[], /* I Prefiltered input signal */ - opus_int8 pulses[], /* O Quantized pulse signal */ - const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ - const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ - const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ - const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ - const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ - const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ - const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ - const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ - const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ - const opus_int LTP_scale_Q14 /* I LTP state scaling */ -) -{ - opus_int k, lag, start_idx, LSF_interpolation_flag; - const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13; - opus_int16 *pxq; - opus_int32 sLTP_Q15[ 2 * MAX_FRAME_LENGTH ]; - opus_int16 sLTP[ 2 * MAX_FRAME_LENGTH ]; - opus_int32 HarmShapeFIRPacked_Q14; - opus_int offset_Q10; - opus_int32 x_sc_Q10[ MAX_SUB_FRAME_LENGTH ]; - - NSQ->rand_seed = psIndices->Seed; - - /* Set unvoiced lag to the previous one, overwrite later for voiced */ - lag = NSQ->lagPrev; - - silk_assert( NSQ->prev_gain_Q16 != 0 ); - - offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ]; - - if( psIndices->NLSFInterpCoef_Q2 == 4 ) { - LSF_interpolation_flag = 0; - } else { - LSF_interpolation_flag = 1; - } - - /* Set up pointers to start of sub frame */ - NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length; - NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; - pxq = &NSQ->xq[ psEncC->ltp_mem_length ]; - for( k = 0; k < psEncC->nb_subfr; k++ ) { - A_Q12 = &PredCoef_Q12[ (( k >> 1 ) | ( 1 - LSF_interpolation_flag )) * MAX_LPC_ORDER ]; - B_Q14 = <PCoef_Q14[ k * LTP_ORDER ]; - AR_shp_Q13 = &AR2_Q13[ k * MAX_SHAPE_LPC_ORDER ]; - - /* Noise shape parameters */ - silk_assert( HarmShapeGain_Q14[ k ] >= 0 ); - HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 ); - HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 ); - - NSQ->rewhite_flag = 0; - if( psIndices->signalType == TYPE_VOICED ) { - /* Voiced */ - lag = pitchL[ k ]; - - /* Re-whitening */ - if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) { - /* Rewhiten with new A coefs */ - start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2; - silk_assert( start_idx > 0 ); - - silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ], - A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder ); - - NSQ->rewhite_flag = 1; - NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; - } - } - - silk_nsq_scale_states( psEncC, NSQ, x_Q3, x_sc_Q10, sLTP, sLTP_Q15, k, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType ); - - silk_noise_shape_quantizer( NSQ, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, A_Q12, B_Q14, - AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10, - offset_Q10, psEncC->subfr_length, psEncC->shapingLPCOrder, psEncC->predictLPCOrder ); - - x_Q3 += psEncC->subfr_length; - pulses += psEncC->subfr_length; - pxq += psEncC->subfr_length; - } - - /* Update lagPrev for next frame */ - NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ]; - - /* Save quantized speech and noise shaping signals */ - /* DEBUG_STORE_DATA( enc.pcm, &NSQ->xq[ psEncC->ltp_mem_length ], psEncC->frame_length * sizeof( opus_int16 ) ) */ - silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) ); - silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) ); -} - -/***********************************/ -/* silk_noise_shape_quantizer */ -/***********************************/ -static inline void silk_noise_shape_quantizer( - silk_nsq_state *NSQ, /* I/O NSQ state */ - opus_int signalType, /* I Signal type */ - const opus_int32 x_sc_Q10[], /* I */ - opus_int8 pulses[], /* O */ - opus_int16 xq[], /* O */ - opus_int32 sLTP_Q15[], /* I/O LTP state */ - const opus_int16 a_Q12[], /* I Short term prediction coefs */ - const opus_int16 b_Q14[], /* I Long term prediction coefs */ - const opus_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */ - opus_int lag, /* I Pitch lag */ - opus_int32 HarmShapeFIRPacked_Q14, /* I */ - opus_int Tilt_Q14, /* I Spectral tilt */ - opus_int32 LF_shp_Q14, /* I */ - opus_int32 Gain_Q16, /* I */ - opus_int Lambda_Q10, /* I */ - opus_int offset_Q10, /* I */ - opus_int length, /* I Input length */ - opus_int shapingLPCOrder, /* I Noise shaping AR filter order */ - opus_int predictLPCOrder /* I Prediction filter order */ -) -{ - opus_int i, j; - opus_int32 LTP_pred_Q13, LPC_pred_Q10, n_AR_Q12, n_LTP_Q13; - opus_int32 n_LF_Q12, r_Q10, rr_Q10, q1_Q0, q1_Q10, q2_Q10, rd1_Q20, rd2_Q20; - opus_int32 exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10; - opus_int32 tmp1, tmp2, sLF_AR_shp_Q14; - opus_int32 *psLPC_Q14, *shp_lag_ptr, *pred_lag_ptr; - - shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ]; - pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ]; - Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 ); - - /* Set up short term AR state */ - psLPC_Q14 = &NSQ->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 ]; - - for( i = 0; i < length; i++ ) { - /* Generate dither */ - NSQ->rand_seed = silk_RAND( NSQ->rand_seed ); - - /* Short-term prediction */ - silk_assert( predictLPCOrder == 10 || predictLPCOrder == 16 ); - /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ - LPC_pred_Q10 = silk_RSHIFT( predictLPCOrder, 1 ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ 0 ], a_Q12[ 0 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -1 ], a_Q12[ 1 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -2 ], a_Q12[ 2 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -3 ], a_Q12[ 3 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -4 ], a_Q12[ 4 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -5 ], a_Q12[ 5 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -6 ], a_Q12[ 6 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -7 ], a_Q12[ 7 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -8 ], a_Q12[ 8 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -9 ], a_Q12[ 9 ] ); - if( predictLPCOrder == 16 ) { - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -10 ], a_Q12[ 10 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -11 ], a_Q12[ 11 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -12 ], a_Q12[ 12 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -13 ], a_Q12[ 13 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -14 ], a_Q12[ 14 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -15 ], a_Q12[ 15 ] ); - } - - /* Long-term prediction */ - if( signalType == TYPE_VOICED ) { - /* Unrolled loop */ - /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ - LTP_pred_Q13 = 2; - LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ 0 ], b_Q14[ 0 ] ); - LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -1 ], b_Q14[ 1 ] ); - LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -2 ], b_Q14[ 2 ] ); - LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -3 ], b_Q14[ 3 ] ); - LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -4 ], b_Q14[ 4 ] ); - pred_lag_ptr++; - } else { - LTP_pred_Q13 = 0; - } - - /* Noise shape feedback */ - silk_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */ - tmp2 = psLPC_Q14[ 0 ]; - tmp1 = NSQ->sAR2_Q14[ 0 ]; - NSQ->sAR2_Q14[ 0 ] = tmp2; - n_AR_Q12 = silk_RSHIFT( shapingLPCOrder, 1 ); - n_AR_Q12 = silk_SMLAWB( n_AR_Q12, tmp2, AR_shp_Q13[ 0 ] ); - for( j = 2; j < shapingLPCOrder; j += 2 ) { - tmp2 = NSQ->sAR2_Q14[ j - 1 ]; - NSQ->sAR2_Q14[ j - 1 ] = tmp1; - n_AR_Q12 = silk_SMLAWB( n_AR_Q12, tmp1, AR_shp_Q13[ j - 1 ] ); - tmp1 = NSQ->sAR2_Q14[ j + 0 ]; - NSQ->sAR2_Q14[ j + 0 ] = tmp2; - n_AR_Q12 = silk_SMLAWB( n_AR_Q12, tmp2, AR_shp_Q13[ j ] ); - } - NSQ->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1; - n_AR_Q12 = silk_SMLAWB( n_AR_Q12, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] ); - - n_AR_Q12 = silk_LSHIFT32( n_AR_Q12, 1 ); /* Q11 -> Q12 */ - n_AR_Q12 = silk_SMLAWB( n_AR_Q12, NSQ->sLF_AR_shp_Q14, Tilt_Q14 ); - - n_LF_Q12 = silk_SMULWB( NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - 1 ], LF_shp_Q14 ); - n_LF_Q12 = silk_SMLAWT( n_LF_Q12, NSQ->sLF_AR_shp_Q14, LF_shp_Q14 ); - - silk_assert( lag > 0 || signalType != TYPE_VOICED ); - - /* Combine prediction and noise shaping signals */ - tmp1 = silk_SUB32( silk_LSHIFT32( LPC_pred_Q10, 2 ), n_AR_Q12 ); /* Q12 */ - tmp1 = silk_SUB32( tmp1, n_LF_Q12 ); /* Q12 */ - if( lag > 0 ) { - /* Symmetric, packed FIR coefficients */ - n_LTP_Q13 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 ); - n_LTP_Q13 = silk_SMLAWT( n_LTP_Q13, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 ); - n_LTP_Q13 = silk_LSHIFT( n_LTP_Q13, 1 ); - shp_lag_ptr++; - - tmp2 = silk_SUB32( LTP_pred_Q13, n_LTP_Q13 ); /* Q13 */ - tmp1 = silk_ADD_LSHIFT32( tmp2, tmp1, 1 ); /* Q13 */ - tmp1 = silk_RSHIFT_ROUND( tmp1, 3 ); /* Q10 */ - } else { - tmp1 = silk_RSHIFT_ROUND( tmp1, 2 ); /* Q10 */ - } - - r_Q10 = silk_SUB32( x_sc_Q10[ i ], tmp1 ); /* residual error Q10 */ - - /* Flip sign depending on dither */ - if ( NSQ->rand_seed < 0 ) { - r_Q10 = -r_Q10; - } - r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 ); - - /* Find two quantization level candidates and measure their rate-distortion */ - q1_Q10 = silk_SUB32( r_Q10, offset_Q10 ); - q1_Q0 = silk_RSHIFT( q1_Q10, 10 ); - if( q1_Q0 > 0 ) { - q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); - q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 ); - q2_Q10 = silk_ADD32( q1_Q10, 1024 ); - rd1_Q20 = silk_SMULBB( q1_Q10, Lambda_Q10 ); - rd2_Q20 = silk_SMULBB( q2_Q10, Lambda_Q10 ); - } else if( q1_Q0 == 0 ) { - q1_Q10 = offset_Q10; - q2_Q10 = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 ); - rd1_Q20 = silk_SMULBB( q1_Q10, Lambda_Q10 ); - rd2_Q20 = silk_SMULBB( q2_Q10, Lambda_Q10 ); - } else if( q1_Q0 == -1 ) { - q2_Q10 = offset_Q10; - q1_Q10 = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 ); - rd1_Q20 = silk_SMULBB( -q1_Q10, Lambda_Q10 ); - rd2_Q20 = silk_SMULBB( q2_Q10, Lambda_Q10 ); - } else { /* Q1_Q0 < -1 */ - q1_Q10 = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); - q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 ); - q2_Q10 = silk_ADD32( q1_Q10, 1024 ); - rd1_Q20 = silk_SMULBB( -q1_Q10, Lambda_Q10 ); - rd2_Q20 = silk_SMULBB( -q2_Q10, Lambda_Q10 ); - } - rr_Q10 = silk_SUB32( r_Q10, q1_Q10 ); - rd1_Q20 = silk_SMLABB( rd1_Q20, rr_Q10, rr_Q10 ); - rr_Q10 = silk_SUB32( r_Q10, q2_Q10 ); - rd2_Q20 = silk_SMLABB( rd2_Q20, rr_Q10, rr_Q10 ); - - if( rd2_Q20 < rd1_Q20 ) { - q1_Q10 = q2_Q10; - } - - pulses[ i ] = (opus_int8)silk_RSHIFT_ROUND( q1_Q10, 10 ); - - /* Excitation */ - exc_Q14 = silk_LSHIFT( q1_Q10, 4 ); - if ( NSQ->rand_seed < 0 ) { - exc_Q14 = -exc_Q14; - } - - /* Add predictions */ - LPC_exc_Q14 = silk_ADD_LSHIFT32( exc_Q14, LTP_pred_Q13, 1 ); - xq_Q14 = silk_ADD_LSHIFT32( LPC_exc_Q14, LPC_pred_Q10, 4 ); - - /* Scale XQ back to normal level before saving */ - xq[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( xq_Q14, Gain_Q10 ), 8 ) ); - - /* Update states */ - psLPC_Q14++; - *psLPC_Q14 = xq_Q14; - sLF_AR_shp_Q14 = silk_SUB_LSHIFT32( xq_Q14, n_AR_Q12, 2 ); - NSQ->sLF_AR_shp_Q14 = sLF_AR_shp_Q14; - - NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx ] = silk_SUB_LSHIFT32( sLF_AR_shp_Q14, n_LF_Q12, 2 ); - sLTP_Q15[ NSQ->sLTP_buf_idx ] = silk_LSHIFT( LPC_exc_Q14, 1 ); - NSQ->sLTP_shp_buf_idx++; - NSQ->sLTP_buf_idx++; - - /* Make dither dependent on quantized signal */ - NSQ->rand_seed = silk_ADD32_ovflw( NSQ->rand_seed, pulses[ i ] ); - } - - /* Update LPC synth buffer */ - silk_memcpy( NSQ->sLPC_Q14, &NSQ->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); -} - -static inline void silk_nsq_scale_states( - const silk_encoder_state *psEncC, /* I Encoder State */ - silk_nsq_state *NSQ, /* I/O NSQ state */ - const opus_int32 x_Q3[], /* I input in Q3 */ - opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */ - const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */ - opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ - opus_int subfr, /* I subframe number */ - const opus_int LTP_scale_Q14, /* I */ - const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ - const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ - const opus_int signal_type /* I Signal type */ -) -{ - opus_int i, lag; - opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q23; - - lag = pitchL[ subfr ]; - inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 ); - silk_assert( inv_gain_Q31 != 0 ); - - /* Calculate gain adjustment factor */ - if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) { - gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 ); - } else { - gain_adj_Q16 = (opus_int32)1 << 16; - } - - /* Scale input */ - inv_gain_Q23 = silk_RSHIFT_ROUND( inv_gain_Q31, 8 ); - for( i = 0; i < psEncC->subfr_length; i++ ) { - x_sc_Q10[ i ] = silk_SMULWW( x_Q3[ i ], inv_gain_Q23 ); - } - - /* Save inverse gain */ - NSQ->prev_gain_Q16 = Gains_Q16[ subfr ]; - - /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */ - if( NSQ->rewhite_flag ) { - if( subfr == 0 ) { - /* Do LTP downscaling */ - inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 ); - } - for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) { - silk_assert( i < MAX_FRAME_LENGTH ); - sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] ); - } - } - - /* Adjust for changing gain */ - if( gain_adj_Q16 != (opus_int32)1 << 16 ) { - /* Scale long-term shaping state */ - for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx; i++ ) { - NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] ); - } - - /* Scale long-term prediction state */ - if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) { - for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) { - sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] ); - } - } - - NSQ->sLF_AR_shp_Q14 = silk_SMULWW( gain_adj_Q16, NSQ->sLF_AR_shp_Q14 ); - - /* Scale short-term prediction and shaping states */ - for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) { - NSQ->sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLPC_Q14[ i ] ); - } - for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) { - NSQ->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sAR2_Q14[ i ] ); - } - } -} diff --git a/src/opus-1.0.2/silk/NSQ_del_dec.c b/src/opus-1.0.2/silk/NSQ_del_dec.c deleted file mode 100644 index b877fa96..00000000 --- a/src/opus-1.0.2/silk/NSQ_del_dec.c +++ /dev/null @@ -1,705 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main.h" - -typedef struct { - opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ]; - opus_int32 RandState[ DECISION_DELAY ]; - opus_int32 Q_Q10[ DECISION_DELAY ]; - opus_int32 Xq_Q14[ DECISION_DELAY ]; - opus_int32 Pred_Q15[ DECISION_DELAY ]; - opus_int32 Shape_Q14[ DECISION_DELAY ]; - opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ]; - opus_int32 LF_AR_Q14; - opus_int32 Seed; - opus_int32 SeedInit; - opus_int32 RD_Q10; -} NSQ_del_dec_struct; - -typedef struct { - opus_int32 Q_Q10; - opus_int32 RD_Q10; - opus_int32 xq_Q14; - opus_int32 LF_AR_Q14; - opus_int32 sLTP_shp_Q14; - opus_int32 LPC_exc_Q14; -} NSQ_sample_struct; - -static inline void silk_nsq_del_dec_scale_states( - const silk_encoder_state *psEncC, /* I Encoder State */ - silk_nsq_state *NSQ, /* I/O NSQ state */ - NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ - const opus_int32 x_Q3[], /* I Input in Q3 */ - opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */ - const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */ - opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ - opus_int subfr, /* I Subframe number */ - opus_int nStatesDelayedDecision, /* I Number of del dec states */ - const opus_int LTP_scale_Q14, /* I LTP state scaling */ - const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ - const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ - const opus_int signal_type, /* I Signal type */ - const opus_int decisionDelay /* I Decision delay */ -); - -/******************************************/ -/* Noise shape quantizer for one subframe */ -/******************************************/ -static inline void silk_noise_shape_quantizer_del_dec( - silk_nsq_state *NSQ, /* I/O NSQ state */ - NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ - opus_int signalType, /* I Signal type */ - const opus_int32 x_Q10[], /* I */ - opus_int8 pulses[], /* O */ - opus_int16 xq[], /* O */ - opus_int32 sLTP_Q15[], /* I/O LTP filter state */ - opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */ - const opus_int16 a_Q12[], /* I Short term prediction coefs */ - const opus_int16 b_Q14[], /* I Long term prediction coefs */ - const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */ - opus_int lag, /* I Pitch lag */ - opus_int32 HarmShapeFIRPacked_Q14, /* I */ - opus_int Tilt_Q14, /* I Spectral tilt */ - opus_int32 LF_shp_Q14, /* I */ - opus_int32 Gain_Q16, /* I */ - opus_int Lambda_Q10, /* I */ - opus_int offset_Q10, /* I */ - opus_int length, /* I Input length */ - opus_int subfr, /* I Subframe number */ - opus_int shapingLPCOrder, /* I Shaping LPC filter order */ - opus_int predictLPCOrder, /* I Prediction filter order */ - opus_int warping_Q16, /* I */ - opus_int nStatesDelayedDecision, /* I Number of states in decision tree */ - opus_int *smpl_buf_idx, /* I Index to newest samples in buffers */ - opus_int decisionDelay /* I */ -); - -void silk_NSQ_del_dec( - const silk_encoder_state *psEncC, /* I/O Encoder State */ - silk_nsq_state *NSQ, /* I/O NSQ state */ - SideInfoIndices *psIndices, /* I/O Quantization Indices */ - const opus_int32 x_Q3[], /* I Prefiltered input signal */ - opus_int8 pulses[], /* O Quantized pulse signal */ - const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ - const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ - const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ - const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ - const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ - const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ - const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ - const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ - const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ - const opus_int LTP_scale_Q14 /* I LTP state scaling */ -) -{ - opus_int i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr; - opus_int last_smple_idx, smpl_buf_idx, decisionDelay; - const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13; - opus_int16 *pxq; - opus_int32 sLTP_Q15[ 2 * MAX_FRAME_LENGTH ]; - opus_int16 sLTP[ 2 * MAX_FRAME_LENGTH ]; - opus_int32 HarmShapeFIRPacked_Q14; - opus_int offset_Q10; - opus_int32 RDmin_Q10, Gain_Q10; - opus_int32 x_sc_Q10[ MAX_SUB_FRAME_LENGTH ]; - opus_int32 delayedGain_Q10[ DECISION_DELAY ]; - NSQ_del_dec_struct psDelDec[ MAX_DEL_DEC_STATES ]; - NSQ_del_dec_struct *psDD; - - /* Set unvoiced lag to the previous one, overwrite later for voiced */ - lag = NSQ->lagPrev; - - silk_assert( NSQ->prev_gain_Q16 != 0 ); - - /* Initialize delayed decision states */ - silk_memset( psDelDec, 0, psEncC->nStatesDelayedDecision * sizeof( NSQ_del_dec_struct ) ); - for( k = 0; k < psEncC->nStatesDelayedDecision; k++ ) { - psDD = &psDelDec[ k ]; - psDD->Seed = ( k + psIndices->Seed ) & 3; - psDD->SeedInit = psDD->Seed; - psDD->RD_Q10 = 0; - psDD->LF_AR_Q14 = NSQ->sLF_AR_shp_Q14; - psDD->Shape_Q14[ 0 ] = NSQ->sLTP_shp_Q14[ psEncC->ltp_mem_length - 1 ]; - silk_memcpy( psDD->sLPC_Q14, NSQ->sLPC_Q14, NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); - silk_memcpy( psDD->sAR2_Q14, NSQ->sAR2_Q14, sizeof( NSQ->sAR2_Q14 ) ); - } - - offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ]; - smpl_buf_idx = 0; /* index of oldest samples */ - - decisionDelay = silk_min_int( DECISION_DELAY, psEncC->subfr_length ); - - /* For voiced frames limit the decision delay to lower than the pitch lag */ - if( psIndices->signalType == TYPE_VOICED ) { - for( k = 0; k < psEncC->nb_subfr; k++ ) { - decisionDelay = silk_min_int( decisionDelay, pitchL[ k ] - LTP_ORDER / 2 - 1 ); - } - } else { - if( lag > 0 ) { - decisionDelay = silk_min_int( decisionDelay, lag - LTP_ORDER / 2 - 1 ); - } - } - - if( psIndices->NLSFInterpCoef_Q2 == 4 ) { - LSF_interpolation_flag = 0; - } else { - LSF_interpolation_flag = 1; - } - - /* Set up pointers to start of sub frame */ - pxq = &NSQ->xq[ psEncC->ltp_mem_length ]; - NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length; - NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; - subfr = 0; - for( k = 0; k < psEncC->nb_subfr; k++ ) { - A_Q12 = &PredCoef_Q12[ ( ( k >> 1 ) | ( 1 - LSF_interpolation_flag ) ) * MAX_LPC_ORDER ]; - B_Q14 = <PCoef_Q14[ k * LTP_ORDER ]; - AR_shp_Q13 = &AR2_Q13[ k * MAX_SHAPE_LPC_ORDER ]; - - /* Noise shape parameters */ - silk_assert( HarmShapeGain_Q14[ k ] >= 0 ); - HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 ); - HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 ); - - NSQ->rewhite_flag = 0; - if( psIndices->signalType == TYPE_VOICED ) { - /* Voiced */ - lag = pitchL[ k ]; - - /* Re-whitening */ - if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) { - if( k == 2 ) { - /* RESET DELAYED DECISIONS */ - /* Find winner */ - RDmin_Q10 = psDelDec[ 0 ].RD_Q10; - Winner_ind = 0; - for( i = 1; i < psEncC->nStatesDelayedDecision; i++ ) { - if( psDelDec[ i ].RD_Q10 < RDmin_Q10 ) { - RDmin_Q10 = psDelDec[ i ].RD_Q10; - Winner_ind = i; - } - } - for( i = 0; i < psEncC->nStatesDelayedDecision; i++ ) { - if( i != Winner_ind ) { - psDelDec[ i ].RD_Q10 += ( silk_int32_MAX >> 4 ); - silk_assert( psDelDec[ i ].RD_Q10 >= 0 ); - } - } - - /* Copy final part of signals from winner state to output and long-term filter states */ - psDD = &psDelDec[ Winner_ind ]; - last_smple_idx = smpl_buf_idx + decisionDelay; - for( i = 0; i < decisionDelay; i++ ) { - last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK; - pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 ); - pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( - silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gains_Q16[ 1 ] ), 14 ) ); - NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q14[ last_smple_idx ]; - } - - subfr = 0; - } - - /* Rewhiten with new A coefs */ - start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2; - silk_assert( start_idx > 0 ); - - silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ], - A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder ); - - NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; - NSQ->rewhite_flag = 1; - } - } - - silk_nsq_del_dec_scale_states( psEncC, NSQ, psDelDec, x_Q3, x_sc_Q10, sLTP, sLTP_Q15, k, - psEncC->nStatesDelayedDecision, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType, decisionDelay ); - - silk_noise_shape_quantizer_del_dec( NSQ, psDelDec, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, - delayedGain_Q10, A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], - Gains_Q16[ k ], Lambda_Q10, offset_Q10, psEncC->subfr_length, subfr++, psEncC->shapingLPCOrder, - psEncC->predictLPCOrder, psEncC->warping_Q16, psEncC->nStatesDelayedDecision, &smpl_buf_idx, decisionDelay ); - - x_Q3 += psEncC->subfr_length; - pulses += psEncC->subfr_length; - pxq += psEncC->subfr_length; - } - - /* Find winner */ - RDmin_Q10 = psDelDec[ 0 ].RD_Q10; - Winner_ind = 0; - for( k = 1; k < psEncC->nStatesDelayedDecision; k++ ) { - if( psDelDec[ k ].RD_Q10 < RDmin_Q10 ) { - RDmin_Q10 = psDelDec[ k ].RD_Q10; - Winner_ind = k; - } - } - - /* Copy final part of signals from winner state to output and long-term filter states */ - psDD = &psDelDec[ Winner_ind ]; - psIndices->Seed = psDD->SeedInit; - last_smple_idx = smpl_buf_idx + decisionDelay; - Gain_Q10 = silk_RSHIFT32( Gains_Q16[ psEncC->nb_subfr - 1 ], 6 ); - for( i = 0; i < decisionDelay; i++ ) { - last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK; - pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 ); - pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( - silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gain_Q10 ), 8 ) ); - NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q14[ last_smple_idx ]; - } - silk_memcpy( NSQ->sLPC_Q14, &psDD->sLPC_Q14[ psEncC->subfr_length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); - silk_memcpy( NSQ->sAR2_Q14, psDD->sAR2_Q14, sizeof( psDD->sAR2_Q14 ) ); - - /* Update states */ - NSQ->sLF_AR_shp_Q14 = psDD->LF_AR_Q14; - NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ]; - - /* Save quantized speech signal */ - /* DEBUG_STORE_DATA( enc.pcm, &NSQ->xq[psEncC->ltp_mem_length], psEncC->frame_length * sizeof( opus_int16 ) ) */ - silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) ); - silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) ); -} - -/******************************************/ -/* Noise shape quantizer for one subframe */ -/******************************************/ -static inline void silk_noise_shape_quantizer_del_dec( - silk_nsq_state *NSQ, /* I/O NSQ state */ - NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ - opus_int signalType, /* I Signal type */ - const opus_int32 x_Q10[], /* I */ - opus_int8 pulses[], /* O */ - opus_int16 xq[], /* O */ - opus_int32 sLTP_Q15[], /* I/O LTP filter state */ - opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */ - const opus_int16 a_Q12[], /* I Short term prediction coefs */ - const opus_int16 b_Q14[], /* I Long term prediction coefs */ - const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */ - opus_int lag, /* I Pitch lag */ - opus_int32 HarmShapeFIRPacked_Q14, /* I */ - opus_int Tilt_Q14, /* I Spectral tilt */ - opus_int32 LF_shp_Q14, /* I */ - opus_int32 Gain_Q16, /* I */ - opus_int Lambda_Q10, /* I */ - opus_int offset_Q10, /* I */ - opus_int length, /* I Input length */ - opus_int subfr, /* I Subframe number */ - opus_int shapingLPCOrder, /* I Shaping LPC filter order */ - opus_int predictLPCOrder, /* I Prediction filter order */ - opus_int warping_Q16, /* I */ - opus_int nStatesDelayedDecision, /* I Number of states in decision tree */ - opus_int *smpl_buf_idx, /* I Index to newest samples in buffers */ - opus_int decisionDelay /* I */ -) -{ - opus_int i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx; - opus_int32 Winner_rand_state; - opus_int32 LTP_pred_Q14, LPC_pred_Q14, n_AR_Q14, n_LTP_Q14; - opus_int32 n_LF_Q14, r_Q10, rr_Q10, rd1_Q10, rd2_Q10, RDmin_Q10, RDmax_Q10; - opus_int32 q1_Q0, q1_Q10, q2_Q10, exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10; - opus_int32 tmp1, tmp2, sLF_AR_shp_Q14; - opus_int32 *pred_lag_ptr, *shp_lag_ptr, *psLPC_Q14; - NSQ_sample_struct psSampleState[ MAX_DEL_DEC_STATES ][ 2 ]; - NSQ_del_dec_struct *psDD; - NSQ_sample_struct *psSS; - - silk_assert( nStatesDelayedDecision > 0 ); - - shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ]; - pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ]; - Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 ); - - for( i = 0; i < length; i++ ) { - /* Perform common calculations used in all states */ - - /* Long-term prediction */ - if( signalType == TYPE_VOICED ) { - /* Unrolled loop */ - /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ - LTP_pred_Q14 = 2; - LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ 0 ], b_Q14[ 0 ] ); - LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], b_Q14[ 1 ] ); - LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], b_Q14[ 2 ] ); - LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], b_Q14[ 3 ] ); - LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], b_Q14[ 4 ] ); - LTP_pred_Q14 = silk_LSHIFT( LTP_pred_Q14, 1 ); /* Q13 -> Q14 */ - pred_lag_ptr++; - } else { - LTP_pred_Q14 = 0; - } - - /* Long-term shaping */ - if( lag > 0 ) { - /* Symmetric, packed FIR coefficients */ - n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 ); - n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 ); - n_LTP_Q14 = silk_SUB_LSHIFT32( LTP_pred_Q14, n_LTP_Q14, 2 ); /* Q12 -> Q14 */ - shp_lag_ptr++; - } else { - n_LTP_Q14 = 0; - } - - for( k = 0; k < nStatesDelayedDecision; k++ ) { - /* Delayed decision state */ - psDD = &psDelDec[ k ]; - - /* Sample state */ - psSS = psSampleState[ k ]; - - /* Generate dither */ - psDD->Seed = silk_RAND( psDD->Seed ); - - /* Pointer used in short term prediction and shaping */ - psLPC_Q14 = &psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 + i ]; - /* Short-term prediction */ - silk_assert( predictLPCOrder == 10 || predictLPCOrder == 16 ); - /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ - LPC_pred_Q14 = silk_RSHIFT( predictLPCOrder, 1 ); - LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ 0 ], a_Q12[ 0 ] ); - LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -1 ], a_Q12[ 1 ] ); - LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -2 ], a_Q12[ 2 ] ); - LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -3 ], a_Q12[ 3 ] ); - LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -4 ], a_Q12[ 4 ] ); - LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -5 ], a_Q12[ 5 ] ); - LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -6 ], a_Q12[ 6 ] ); - LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -7 ], a_Q12[ 7 ] ); - LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -8 ], a_Q12[ 8 ] ); - LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -9 ], a_Q12[ 9 ] ); - if( predictLPCOrder == 16 ) { - LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -10 ], a_Q12[ 10 ] ); - LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -11 ], a_Q12[ 11 ] ); - LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -12 ], a_Q12[ 12 ] ); - LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -13 ], a_Q12[ 13 ] ); - LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -14 ], a_Q12[ 14 ] ); - LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -15 ], a_Q12[ 15 ] ); - } - LPC_pred_Q14 = silk_LSHIFT( LPC_pred_Q14, 4 ); /* Q10 -> Q14 */ - - /* Noise shape feedback */ - silk_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */ - /* Output of lowpass section */ - tmp2 = silk_SMLAWB( psLPC_Q14[ 0 ], psDD->sAR2_Q14[ 0 ], warping_Q16 ); - /* Output of allpass section */ - tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ 0 ], psDD->sAR2_Q14[ 1 ] - tmp2, warping_Q16 ); - psDD->sAR2_Q14[ 0 ] = tmp2; - n_AR_Q14 = silk_RSHIFT( shapingLPCOrder, 1 ); - n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp2, AR_shp_Q13[ 0 ] ); - /* Loop over allpass sections */ - for( j = 2; j < shapingLPCOrder; j += 2 ) { - /* Output of allpass section */ - tmp2 = silk_SMLAWB( psDD->sAR2_Q14[ j - 1 ], psDD->sAR2_Q14[ j + 0 ] - tmp1, warping_Q16 ); - psDD->sAR2_Q14[ j - 1 ] = tmp1; - n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp1, AR_shp_Q13[ j - 1 ] ); - /* Output of allpass section */ - tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ j + 0 ], psDD->sAR2_Q14[ j + 1 ] - tmp2, warping_Q16 ); - psDD->sAR2_Q14[ j + 0 ] = tmp2; - n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp2, AR_shp_Q13[ j ] ); - } - psDD->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1; - n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] ); - - n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 1 ); /* Q11 -> Q12 */ - n_AR_Q14 = silk_SMLAWB( n_AR_Q14, psDD->LF_AR_Q14, Tilt_Q14 ); /* Q12 */ - n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 2 ); /* Q12 -> Q14 */ - - n_LF_Q14 = silk_SMULWB( psDD->Shape_Q14[ *smpl_buf_idx ], LF_shp_Q14 ); /* Q12 */ - n_LF_Q14 = silk_SMLAWT( n_LF_Q14, psDD->LF_AR_Q14, LF_shp_Q14 ); /* Q12 */ - n_LF_Q14 = silk_LSHIFT( n_LF_Q14, 2 ); /* Q12 -> Q14 */ - - /* Input minus prediction plus noise feedback */ - /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP */ - tmp1 = silk_ADD32( n_AR_Q14, n_LF_Q14 ); /* Q14 */ - tmp2 = silk_ADD32( n_LTP_Q14, LPC_pred_Q14 ); /* Q13 */ - tmp1 = silk_SUB32( tmp2, tmp1 ); /* Q13 */ - tmp1 = silk_RSHIFT_ROUND( tmp1, 4 ); /* Q10 */ - - r_Q10 = silk_SUB32( x_Q10[ i ], tmp1 ); /* residual error Q10 */ - - /* Flip sign depending on dither */ - if ( psDD->Seed < 0 ) { - r_Q10 = -r_Q10; - } - r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 ); - - /* Find two quantization level candidates and measure their rate-distortion */ - q1_Q10 = silk_SUB32( r_Q10, offset_Q10 ); - q1_Q0 = silk_RSHIFT( q1_Q10, 10 ); - if( q1_Q0 > 0 ) { - q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); - q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 ); - q2_Q10 = silk_ADD32( q1_Q10, 1024 ); - rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 ); - rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 ); - } else if( q1_Q0 == 0 ) { - q1_Q10 = offset_Q10; - q2_Q10 = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 ); - rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 ); - rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 ); - } else if( q1_Q0 == -1 ) { - q2_Q10 = offset_Q10; - q1_Q10 = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 ); - rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 ); - rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 ); - } else { /* q1_Q0 < -1 */ - q1_Q10 = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); - q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 ); - q2_Q10 = silk_ADD32( q1_Q10, 1024 ); - rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 ); - rd2_Q10 = silk_SMULBB( -q2_Q10, Lambda_Q10 ); - } - rr_Q10 = silk_SUB32( r_Q10, q1_Q10 ); - rd1_Q10 = silk_RSHIFT( silk_SMLABB( rd1_Q10, rr_Q10, rr_Q10 ), 10 ); - rr_Q10 = silk_SUB32( r_Q10, q2_Q10 ); - rd2_Q10 = silk_RSHIFT( silk_SMLABB( rd2_Q10, rr_Q10, rr_Q10 ), 10 ); - - if( rd1_Q10 < rd2_Q10 ) { - psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 ); - psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 ); - psSS[ 0 ].Q_Q10 = q1_Q10; - psSS[ 1 ].Q_Q10 = q2_Q10; - } else { - psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 ); - psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 ); - psSS[ 0 ].Q_Q10 = q2_Q10; - psSS[ 1 ].Q_Q10 = q1_Q10; - } - - /* Update states for best quantization */ - - /* Quantized excitation */ - exc_Q14 = silk_LSHIFT32( psSS[ 0 ].Q_Q10, 4 ); - if ( psDD->Seed < 0 ) { - exc_Q14 = -exc_Q14; - } - - /* Add predictions */ - LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 ); - xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 ); - - /* Update states */ - sLF_AR_shp_Q14 = silk_SUB32( xq_Q14, n_AR_Q14 ); - psSS[ 0 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 ); - psSS[ 0 ].LF_AR_Q14 = sLF_AR_shp_Q14; - psSS[ 0 ].LPC_exc_Q14 = LPC_exc_Q14; - psSS[ 0 ].xq_Q14 = xq_Q14; - - /* Update states for second best quantization */ - - /* Quantized excitation */ - exc_Q14 = silk_LSHIFT32( psSS[ 1 ].Q_Q10, 4 ); - if ( psDD->Seed < 0 ) { - exc_Q14 = -exc_Q14; - } - - - /* Add predictions */ - LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 ); - xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 ); - - /* Update states */ - sLF_AR_shp_Q14 = silk_SUB32( xq_Q14, n_AR_Q14 ); - psSS[ 1 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 ); - psSS[ 1 ].LF_AR_Q14 = sLF_AR_shp_Q14; - psSS[ 1 ].LPC_exc_Q14 = LPC_exc_Q14; - psSS[ 1 ].xq_Q14 = xq_Q14; - } - - *smpl_buf_idx = ( *smpl_buf_idx - 1 ) & DECISION_DELAY_MASK; /* Index to newest samples */ - last_smple_idx = ( *smpl_buf_idx + decisionDelay ) & DECISION_DELAY_MASK; /* Index to decisionDelay old samples */ - - /* Find winner */ - RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10; - Winner_ind = 0; - for( k = 1; k < nStatesDelayedDecision; k++ ) { - if( psSampleState[ k ][ 0 ].RD_Q10 < RDmin_Q10 ) { - RDmin_Q10 = psSampleState[ k ][ 0 ].RD_Q10; - Winner_ind = k; - } - } - - /* Increase RD values of expired states */ - Winner_rand_state = psDelDec[ Winner_ind ].RandState[ last_smple_idx ]; - for( k = 0; k < nStatesDelayedDecision; k++ ) { - if( psDelDec[ k ].RandState[ last_smple_idx ] != Winner_rand_state ) { - psSampleState[ k ][ 0 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 0 ].RD_Q10, silk_int32_MAX >> 4 ); - psSampleState[ k ][ 1 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 1 ].RD_Q10, silk_int32_MAX >> 4 ); - silk_assert( psSampleState[ k ][ 0 ].RD_Q10 >= 0 ); - } - } - - /* Find worst in first set and best in second set */ - RDmax_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10; - RDmin_Q10 = psSampleState[ 0 ][ 1 ].RD_Q10; - RDmax_ind = 0; - RDmin_ind = 0; - for( k = 1; k < nStatesDelayedDecision; k++ ) { - /* find worst in first set */ - if( psSampleState[ k ][ 0 ].RD_Q10 > RDmax_Q10 ) { - RDmax_Q10 = psSampleState[ k ][ 0 ].RD_Q10; - RDmax_ind = k; - } - /* find best in second set */ - if( psSampleState[ k ][ 1 ].RD_Q10 < RDmin_Q10 ) { - RDmin_Q10 = psSampleState[ k ][ 1 ].RD_Q10; - RDmin_ind = k; - } - } - - /* Replace a state if best from second set outperforms worst in first set */ - if( RDmin_Q10 < RDmax_Q10 ) { - silk_memcpy( ( (opus_int32 *)&psDelDec[ RDmax_ind ] ) + i, - ( (opus_int32 *)&psDelDec[ RDmin_ind ] ) + i, sizeof( NSQ_del_dec_struct ) - i * sizeof( opus_int32) ); - silk_memcpy( &psSampleState[ RDmax_ind ][ 0 ], &psSampleState[ RDmin_ind ][ 1 ], sizeof( NSQ_sample_struct ) ); - } - - /* Write samples from winner to output and long-term filter states */ - psDD = &psDelDec[ Winner_ind ]; - if( subfr > 0 || i >= decisionDelay ) { - pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 ); - xq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( - silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], delayedGain_Q10[ last_smple_idx ] ), 8 ) ); - NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDD->Shape_Q14[ last_smple_idx ]; - sLTP_Q15[ NSQ->sLTP_buf_idx - decisionDelay ] = psDD->Pred_Q15[ last_smple_idx ]; - } - NSQ->sLTP_shp_buf_idx++; - NSQ->sLTP_buf_idx++; - - /* Update states */ - for( k = 0; k < nStatesDelayedDecision; k++ ) { - psDD = &psDelDec[ k ]; - psSS = &psSampleState[ k ][ 0 ]; - psDD->LF_AR_Q14 = psSS->LF_AR_Q14; - psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ] = psSS->xq_Q14; - psDD->Xq_Q14[ *smpl_buf_idx ] = psSS->xq_Q14; - psDD->Q_Q10[ *smpl_buf_idx ] = psSS->Q_Q10; - psDD->Pred_Q15[ *smpl_buf_idx ] = silk_LSHIFT32( psSS->LPC_exc_Q14, 1 ); - psDD->Shape_Q14[ *smpl_buf_idx ] = psSS->sLTP_shp_Q14; - psDD->Seed = silk_ADD32_ovflw( psDD->Seed, silk_RSHIFT_ROUND( psSS->Q_Q10, 10 ) ); - psDD->RandState[ *smpl_buf_idx ] = psDD->Seed; - psDD->RD_Q10 = psSS->RD_Q10; - } - delayedGain_Q10[ *smpl_buf_idx ] = Gain_Q10; - } - /* Update LPC states */ - for( k = 0; k < nStatesDelayedDecision; k++ ) { - psDD = &psDelDec[ k ]; - silk_memcpy( psDD->sLPC_Q14, &psDD->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); - } -} - -static inline void silk_nsq_del_dec_scale_states( - const silk_encoder_state *psEncC, /* I Encoder State */ - silk_nsq_state *NSQ, /* I/O NSQ state */ - NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ - const opus_int32 x_Q3[], /* I Input in Q3 */ - opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */ - const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */ - opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ - opus_int subfr, /* I Subframe number */ - opus_int nStatesDelayedDecision, /* I Number of del dec states */ - const opus_int LTP_scale_Q14, /* I LTP state scaling */ - const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ - const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ - const opus_int signal_type, /* I Signal type */ - const opus_int decisionDelay /* I Decision delay */ -) -{ - opus_int i, k, lag; - opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q23; - NSQ_del_dec_struct *psDD; - - lag = pitchL[ subfr ]; - inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 ); - silk_assert( inv_gain_Q31 != 0 ); - - /* Calculate gain adjustment factor */ - if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) { - gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 ); - } else { - gain_adj_Q16 = (opus_int32)1 << 16; - } - - /* Scale input */ - inv_gain_Q23 = silk_RSHIFT_ROUND( inv_gain_Q31, 8 ); - for( i = 0; i < psEncC->subfr_length; i++ ) { - x_sc_Q10[ i ] = silk_SMULWW( x_Q3[ i ], inv_gain_Q23 ); - } - - /* Save inverse gain */ - NSQ->prev_gain_Q16 = Gains_Q16[ subfr ]; - - /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */ - if( NSQ->rewhite_flag ) { - if( subfr == 0 ) { - /* Do LTP downscaling */ - inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 ); - } - for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) { - silk_assert( i < MAX_FRAME_LENGTH ); - sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] ); - } - } - - /* Adjust for changing gain */ - if( gain_adj_Q16 != (opus_int32)1 << 16 ) { - /* Scale long-term shaping state */ - for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx; i++ ) { - NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] ); - } - - /* Scale long-term prediction state */ - if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) { - for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx - decisionDelay; i++ ) { - sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] ); - } - } - - for( k = 0; k < nStatesDelayedDecision; k++ ) { - psDD = &psDelDec[ k ]; - - /* Scale scalar states */ - psDD->LF_AR_Q14 = silk_SMULWW( gain_adj_Q16, psDD->LF_AR_Q14 ); - - /* Scale short-term prediction and shaping states */ - for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) { - psDD->sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->sLPC_Q14[ i ] ); - } - for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) { - psDD->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->sAR2_Q14[ i ] ); - } - for( i = 0; i < DECISION_DELAY; i++ ) { - psDD->Pred_Q15[ i ] = silk_SMULWW( gain_adj_Q16, psDD->Pred_Q15[ i ] ); - psDD->Shape_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->Shape_Q14[ i ] ); - } - } - } -} diff --git a/src/opus-1.0.2/silk/PLC.c b/src/opus-1.0.2/silk/PLC.c deleted file mode 100644 index 8d547295..00000000 --- a/src/opus-1.0.2/silk/PLC.c +++ /dev/null @@ -1,423 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main.h" -#include "stack_alloc.h" -#include "PLC.h" - -#define NB_ATT 2 -static const opus_int16 HARM_ATT_Q15[NB_ATT] = { 32440, 31130 }; /* 0.99, 0.95 */ -static const opus_int16 PLC_RAND_ATTENUATE_V_Q15[NB_ATT] = { 31130, 26214 }; /* 0.95, 0.8 */ -static const opus_int16 PLC_RAND_ATTENUATE_UV_Q15[NB_ATT] = { 32440, 29491 }; /* 0.99, 0.9 */ - -static inline void silk_PLC_update( - silk_decoder_state *psDec, /* I/O Decoder state */ - silk_decoder_control *psDecCtrl /* I/O Decoder control */ -); - -static inline void silk_PLC_conceal( - silk_decoder_state *psDec, /* I/O Decoder state */ - silk_decoder_control *psDecCtrl, /* I/O Decoder control */ - opus_int16 frame[] /* O LPC residual signal */ -); - - -void silk_PLC_Reset( - silk_decoder_state *psDec /* I/O Decoder state */ -) -{ - psDec->sPLC.pitchL_Q8 = silk_LSHIFT( psDec->frame_length, 8 - 1 ); - psDec->sPLC.prevGain_Q16[ 0 ] = SILK_FIX_CONST( 1, 16 ); - psDec->sPLC.prevGain_Q16[ 1 ] = SILK_FIX_CONST( 1, 16 ); - psDec->sPLC.subfr_length = 20; - psDec->sPLC.nb_subfr = 2; -} - -void silk_PLC( - silk_decoder_state *psDec, /* I/O Decoder state */ - silk_decoder_control *psDecCtrl, /* I/O Decoder control */ - opus_int16 frame[], /* I/O signal */ - opus_int lost /* I Loss flag */ -) -{ - /* PLC control function */ - if( psDec->fs_kHz != psDec->sPLC.fs_kHz ) { - silk_PLC_Reset( psDec ); - psDec->sPLC.fs_kHz = psDec->fs_kHz; - } - - if( lost ) { - /****************************/ - /* Generate Signal */ - /****************************/ - silk_PLC_conceal( psDec, psDecCtrl, frame ); - - psDec->lossCnt++; - } else { - /****************************/ - /* Update state */ - /****************************/ - silk_PLC_update( psDec, psDecCtrl ); - } -} - -/**************************************************/ -/* Update state of PLC */ -/**************************************************/ -static inline void silk_PLC_update( - silk_decoder_state *psDec, /* I/O Decoder state */ - silk_decoder_control *psDecCtrl /* I/O Decoder control */ -) -{ - opus_int32 LTP_Gain_Q14, temp_LTP_Gain_Q14; - opus_int i, j; - silk_PLC_struct *psPLC; - - psPLC = &psDec->sPLC; - - /* Update parameters used in case of packet loss */ - psDec->prevSignalType = psDec->indices.signalType; - LTP_Gain_Q14 = 0; - if( psDec->indices.signalType == TYPE_VOICED ) { - /* Find the parameters for the last subframe which contains a pitch pulse */ - for( j = 0; j * psDec->subfr_length < psDecCtrl->pitchL[ psDec->nb_subfr - 1 ]; j++ ) { - if( j == psDec->nb_subfr ) { - break; - } - temp_LTP_Gain_Q14 = 0; - for( i = 0; i < LTP_ORDER; i++ ) { - temp_LTP_Gain_Q14 += psDecCtrl->LTPCoef_Q14[ ( psDec->nb_subfr - 1 - j ) * LTP_ORDER + i ]; - } - if( temp_LTP_Gain_Q14 > LTP_Gain_Q14 ) { - LTP_Gain_Q14 = temp_LTP_Gain_Q14; - silk_memcpy( psPLC->LTPCoef_Q14, - &psDecCtrl->LTPCoef_Q14[ silk_SMULBB( psDec->nb_subfr - 1 - j, LTP_ORDER ) ], - LTP_ORDER * sizeof( opus_int16 ) ); - - psPLC->pitchL_Q8 = silk_LSHIFT( psDecCtrl->pitchL[ psDec->nb_subfr - 1 - j ], 8 ); - } - } - - silk_memset( psPLC->LTPCoef_Q14, 0, LTP_ORDER * sizeof( opus_int16 ) ); - psPLC->LTPCoef_Q14[ LTP_ORDER / 2 ] = LTP_Gain_Q14; - - /* Limit LT coefs */ - if( LTP_Gain_Q14 < V_PITCH_GAIN_START_MIN_Q14 ) { - opus_int scale_Q10; - opus_int32 tmp; - - tmp = silk_LSHIFT( V_PITCH_GAIN_START_MIN_Q14, 10 ); - scale_Q10 = silk_DIV32( tmp, silk_max( LTP_Gain_Q14, 1 ) ); - for( i = 0; i < LTP_ORDER; i++ ) { - psPLC->LTPCoef_Q14[ i ] = silk_RSHIFT( silk_SMULBB( psPLC->LTPCoef_Q14[ i ], scale_Q10 ), 10 ); - } - } else if( LTP_Gain_Q14 > V_PITCH_GAIN_START_MAX_Q14 ) { - opus_int scale_Q14; - opus_int32 tmp; - - tmp = silk_LSHIFT( V_PITCH_GAIN_START_MAX_Q14, 14 ); - scale_Q14 = silk_DIV32( tmp, silk_max( LTP_Gain_Q14, 1 ) ); - for( i = 0; i < LTP_ORDER; i++ ) { - psPLC->LTPCoef_Q14[ i ] = silk_RSHIFT( silk_SMULBB( psPLC->LTPCoef_Q14[ i ], scale_Q14 ), 14 ); - } - } - } else { - psPLC->pitchL_Q8 = silk_LSHIFT( silk_SMULBB( psDec->fs_kHz, 18 ), 8 ); - silk_memset( psPLC->LTPCoef_Q14, 0, LTP_ORDER * sizeof( opus_int16 )); - } - - /* Save LPC coeficients */ - silk_memcpy( psPLC->prevLPC_Q12, psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order * sizeof( opus_int16 ) ); - psPLC->prevLTP_scale_Q14 = psDecCtrl->LTP_scale_Q14; - - /* Save last two gains */ - silk_memcpy( psPLC->prevGain_Q16, &psDecCtrl->Gains_Q16[ psDec->nb_subfr - 2 ], 2 * sizeof( opus_int32 ) ); - - psPLC->subfr_length = psDec->subfr_length; - psPLC->nb_subfr = psDec->nb_subfr; -} - -static inline void silk_PLC_conceal( - silk_decoder_state *psDec, /* I/O Decoder state */ - silk_decoder_control *psDecCtrl, /* I/O Decoder control */ - opus_int16 frame[] /* O LPC residual signal */ -) -{ - opus_int i, j, k; - opus_int lag, idx, sLTP_buf_idx, shift1, shift2; - opus_int32 rand_seed, harm_Gain_Q15, rand_Gain_Q15, inv_gain_Q30; - opus_int32 energy1, energy2, *rand_ptr, *pred_lag_ptr; - opus_int32 LPC_pred_Q10, LTP_pred_Q12; - opus_int16 rand_scale_Q14; - opus_int16 *B_Q14, *exc_buf_ptr; - opus_int32 *sLPC_Q14_ptr; - VARDECL( opus_int16, exc_buf ); - opus_int16 A_Q12[ MAX_LPC_ORDER ]; - VARDECL( opus_int16, sLTP ); - VARDECL( opus_int32, sLTP_Q14 ); - silk_PLC_struct *psPLC = &psDec->sPLC; - opus_int32 prevGain_Q10[2]; - SAVE_STACK; - - ALLOC( exc_buf, 2*psPLC->subfr_length, opus_int16 ); - ALLOC( sLTP, psDec->ltp_mem_length, opus_int16 ); - ALLOC( sLTP_Q14, psDec->ltp_mem_length + psDec->frame_length, opus_int32 ); - - prevGain_Q10[0] = silk_RSHIFT( psPLC->prevGain_Q16[ 0 ], 6); - prevGain_Q10[1] = silk_RSHIFT( psPLC->prevGain_Q16[ 1 ], 6); - - if( psDec->first_frame_after_reset ) { - silk_memset( psPLC->prevLPC_Q12, 0, sizeof( psPLC->prevLPC_Q12 ) ); - } - - /* Find random noise component */ - /* Scale previous excitation signal */ - exc_buf_ptr = exc_buf; - for( k = 0; k < 2; k++ ) { - for( i = 0; i < psPLC->subfr_length; i++ ) { - exc_buf_ptr[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT( - silk_SMULWW( psDec->exc_Q14[ i + ( k + psPLC->nb_subfr - 2 ) * psPLC->subfr_length ], prevGain_Q10[ k ] ), 8 ) ); - } - exc_buf_ptr += psPLC->subfr_length; - } - /* Find the subframe with lowest energy of the last two and use that as random noise generator */ - silk_sum_sqr_shift( &energy1, &shift1, exc_buf, psPLC->subfr_length ); - silk_sum_sqr_shift( &energy2, &shift2, &exc_buf[ psPLC->subfr_length ], psPLC->subfr_length ); - - if( silk_RSHIFT( energy1, shift2 ) < silk_RSHIFT( energy2, shift1 ) ) { - /* First sub-frame has lowest energy */ - rand_ptr = &psDec->exc_Q14[ silk_max_int( 0, ( psPLC->nb_subfr - 1 ) * psPLC->subfr_length - RAND_BUF_SIZE ) ]; - } else { - /* Second sub-frame has lowest energy */ - rand_ptr = &psDec->exc_Q14[ silk_max_int( 0, psPLC->nb_subfr * psPLC->subfr_length - RAND_BUF_SIZE ) ]; - } - - /* Set up Gain to random noise component */ - B_Q14 = psPLC->LTPCoef_Q14; - rand_scale_Q14 = psPLC->randScale_Q14; - - /* Set up attenuation gains */ - harm_Gain_Q15 = HARM_ATT_Q15[ silk_min_int( NB_ATT - 1, psDec->lossCnt ) ]; - if( psDec->prevSignalType == TYPE_VOICED ) { - rand_Gain_Q15 = PLC_RAND_ATTENUATE_V_Q15[ silk_min_int( NB_ATT - 1, psDec->lossCnt ) ]; - } else { - rand_Gain_Q15 = PLC_RAND_ATTENUATE_UV_Q15[ silk_min_int( NB_ATT - 1, psDec->lossCnt ) ]; - } - - /* LPC concealment. Apply BWE to previous LPC */ - silk_bwexpander( psPLC->prevLPC_Q12, psDec->LPC_order, SILK_FIX_CONST( BWE_COEF, 16 ) ); - - /* Preload LPC coeficients to array on stack. Gives small performance gain */ - silk_memcpy( A_Q12, psPLC->prevLPC_Q12, psDec->LPC_order * sizeof( opus_int16 ) ); - - /* First Lost frame */ - if( psDec->lossCnt == 0 ) { - rand_scale_Q14 = 1 << 14; - - /* Reduce random noise Gain for voiced frames */ - if( psDec->prevSignalType == TYPE_VOICED ) { - for( i = 0; i < LTP_ORDER; i++ ) { - rand_scale_Q14 -= B_Q14[ i ]; - } - rand_scale_Q14 = silk_max_16( 3277, rand_scale_Q14 ); /* 0.2 */ - rand_scale_Q14 = (opus_int16)silk_RSHIFT( silk_SMULBB( rand_scale_Q14, psPLC->prevLTP_scale_Q14 ), 14 ); - } else { - /* Reduce random noise for unvoiced frames with high LPC gain */ - opus_int32 invGain_Q30, down_scale_Q30; - - invGain_Q30 = silk_LPC_inverse_pred_gain( psPLC->prevLPC_Q12, psDec->LPC_order ); - - down_scale_Q30 = silk_min_32( silk_RSHIFT( (opus_int32)1 << 30, LOG2_INV_LPC_GAIN_HIGH_THRES ), invGain_Q30 ); - down_scale_Q30 = silk_max_32( silk_RSHIFT( (opus_int32)1 << 30, LOG2_INV_LPC_GAIN_LOW_THRES ), down_scale_Q30 ); - down_scale_Q30 = silk_LSHIFT( down_scale_Q30, LOG2_INV_LPC_GAIN_HIGH_THRES ); - - rand_Gain_Q15 = silk_RSHIFT( silk_SMULWB( down_scale_Q30, rand_Gain_Q15 ), 14 ); - } - } - - rand_seed = psPLC->rand_seed; - lag = silk_RSHIFT_ROUND( psPLC->pitchL_Q8, 8 ); - sLTP_buf_idx = psDec->ltp_mem_length; - - /* Rewhiten LTP state */ - idx = psDec->ltp_mem_length - lag - psDec->LPC_order - LTP_ORDER / 2; - silk_assert( idx > 0 ); - silk_LPC_analysis_filter( &sLTP[ idx ], &psDec->outBuf[ idx ], A_Q12, psDec->ltp_mem_length - idx, psDec->LPC_order ); - /* Scale LTP state */ - inv_gain_Q30 = silk_INVERSE32_varQ( psPLC->prevGain_Q16[ 1 ], 46 ); - inv_gain_Q30 = silk_min( inv_gain_Q30, silk_int32_MAX >> 1 ); - for( i = idx + psDec->LPC_order; i < psDec->ltp_mem_length; i++ ) { - sLTP_Q14[ i ] = silk_SMULWB( inv_gain_Q30, sLTP[ i ] ); - } - - /***************************/ - /* LTP synthesis filtering */ - /***************************/ - for( k = 0; k < psDec->nb_subfr; k++ ) { - /* Set up pointer */ - pred_lag_ptr = &sLTP_Q14[ sLTP_buf_idx - lag + LTP_ORDER / 2 ]; - for( i = 0; i < psDec->subfr_length; i++ ) { - /* Unrolled loop */ - /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ - LTP_pred_Q12 = 2; - LTP_pred_Q12 = silk_SMLAWB( LTP_pred_Q12, pred_lag_ptr[ 0 ], B_Q14[ 0 ] ); - LTP_pred_Q12 = silk_SMLAWB( LTP_pred_Q12, pred_lag_ptr[ -1 ], B_Q14[ 1 ] ); - LTP_pred_Q12 = silk_SMLAWB( LTP_pred_Q12, pred_lag_ptr[ -2 ], B_Q14[ 2 ] ); - LTP_pred_Q12 = silk_SMLAWB( LTP_pred_Q12, pred_lag_ptr[ -3 ], B_Q14[ 3 ] ); - LTP_pred_Q12 = silk_SMLAWB( LTP_pred_Q12, pred_lag_ptr[ -4 ], B_Q14[ 4 ] ); - pred_lag_ptr++; - - /* Generate LPC excitation */ - rand_seed = silk_RAND( rand_seed ); - idx = silk_RSHIFT( rand_seed, 25 ) & RAND_BUF_MASK; - sLTP_Q14[ sLTP_buf_idx ] = silk_LSHIFT32( silk_SMLAWB( LTP_pred_Q12, rand_ptr[ idx ], rand_scale_Q14 ), 2 ); - sLTP_buf_idx++; - } - - /* Gradually reduce LTP gain */ - for( j = 0; j < LTP_ORDER; j++ ) { - B_Q14[ j ] = silk_RSHIFT( silk_SMULBB( harm_Gain_Q15, B_Q14[ j ] ), 15 ); - } - /* Gradually reduce excitation gain */ - rand_scale_Q14 = silk_RSHIFT( silk_SMULBB( rand_scale_Q14, rand_Gain_Q15 ), 15 ); - - /* Slowly increase pitch lag */ - psPLC->pitchL_Q8 = silk_SMLAWB( psPLC->pitchL_Q8, psPLC->pitchL_Q8, PITCH_DRIFT_FAC_Q16 ); - psPLC->pitchL_Q8 = silk_min_32( psPLC->pitchL_Q8, silk_LSHIFT( silk_SMULBB( MAX_PITCH_LAG_MS, psDec->fs_kHz ), 8 ) ); - lag = silk_RSHIFT_ROUND( psPLC->pitchL_Q8, 8 ); - } - - /***************************/ - /* LPC synthesis filtering */ - /***************************/ - sLPC_Q14_ptr = &sLTP_Q14[ psDec->ltp_mem_length - MAX_LPC_ORDER ]; - - /* Copy LPC state */ - silk_memcpy( sLPC_Q14_ptr, psDec->sLPC_Q14_buf, MAX_LPC_ORDER * sizeof( opus_int32 ) ); - - silk_assert( psDec->LPC_order >= 10 ); /* check that unrolling works */ - for( i = 0; i < psDec->frame_length; i++ ) { - /* partly unrolled */ - /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ - LPC_pred_Q10 = silk_RSHIFT( psDec->LPC_order, 1 ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 1 ], A_Q12[ 0 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 2 ], A_Q12[ 1 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 3 ], A_Q12[ 2 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 4 ], A_Q12[ 3 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 5 ], A_Q12[ 4 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 6 ], A_Q12[ 5 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 7 ], A_Q12[ 6 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 8 ], A_Q12[ 7 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 9 ], A_Q12[ 8 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 10 ], A_Q12[ 9 ] ); - for( j = 10; j < psDec->LPC_order; j++ ) { - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - j - 1 ], A_Q12[ j ] ); - } - - /* Add prediction to LPC excitation */ - sLPC_Q14_ptr[ MAX_LPC_ORDER + i ] = silk_ADD_LSHIFT32( sLPC_Q14_ptr[ MAX_LPC_ORDER + i ], LPC_pred_Q10, 4 ); - - /* Scale with Gain */ - frame[ i ] = (opus_int16)silk_SAT16( silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( sLPC_Q14_ptr[ MAX_LPC_ORDER + i ], prevGain_Q10[ 1 ] ), 8 ) ) ); - } - - /* Save LPC state */ - silk_memcpy( psDec->sLPC_Q14_buf, &sLPC_Q14_ptr[ psDec->frame_length ], MAX_LPC_ORDER * sizeof( opus_int32 ) ); - - /**************************************/ - /* Update states */ - /**************************************/ - psPLC->rand_seed = rand_seed; - psPLC->randScale_Q14 = rand_scale_Q14; - for( i = 0; i < MAX_NB_SUBFR; i++ ) { - psDecCtrl->pitchL[ i ] = lag; - } - RESTORE_STACK; -} - -/* Glues concealed frames with new good received frames */ -void silk_PLC_glue_frames( - silk_decoder_state *psDec, /* I/O decoder state */ - opus_int16 frame[], /* I/O signal */ - opus_int length /* I length of signal */ -) -{ - opus_int i, energy_shift; - opus_int32 energy; - silk_PLC_struct *psPLC; - psPLC = &psDec->sPLC; - - if( psDec->lossCnt ) { - /* Calculate energy in concealed residual */ - silk_sum_sqr_shift( &psPLC->conc_energy, &psPLC->conc_energy_shift, frame, length ); - - psPLC->last_frame_lost = 1; - } else { - if( psDec->sPLC.last_frame_lost ) { - /* Calculate residual in decoded signal if last frame was lost */ - silk_sum_sqr_shift( &energy, &energy_shift, frame, length ); - - /* Normalize energies */ - if( energy_shift > psPLC->conc_energy_shift ) { - psPLC->conc_energy = silk_RSHIFT( psPLC->conc_energy, energy_shift - psPLC->conc_energy_shift ); - } else if( energy_shift < psPLC->conc_energy_shift ) { - energy = silk_RSHIFT( energy, psPLC->conc_energy_shift - energy_shift ); - } - - /* Fade in the energy difference */ - if( energy > psPLC->conc_energy ) { - opus_int32 frac_Q24, LZ; - opus_int32 gain_Q16, slope_Q16; - - LZ = silk_CLZ32( psPLC->conc_energy ); - LZ = LZ - 1; - psPLC->conc_energy = silk_LSHIFT( psPLC->conc_energy, LZ ); - energy = silk_RSHIFT( energy, silk_max_32( 24 - LZ, 0 ) ); - - frac_Q24 = silk_DIV32( psPLC->conc_energy, silk_max( energy, 1 ) ); - - gain_Q16 = silk_LSHIFT( silk_SQRT_APPROX( frac_Q24 ), 4 ); - slope_Q16 = silk_DIV32_16( ( (opus_int32)1 << 16 ) - gain_Q16, length ); - /* Make slope 4x steeper to avoid missing onsets after DTX */ - slope_Q16 = silk_LSHIFT( slope_Q16, 2 ); - - for( i = 0; i < length; i++ ) { - frame[ i ] = silk_SMULWB( gain_Q16, frame[ i ] ); - gain_Q16 += slope_Q16; - if( gain_Q16 > (opus_int32)1 << 16 ) { - break; - } - } - } - } - psPLC->last_frame_lost = 0; - } -} diff --git a/src/opus-1.0.2/silk/PLC.h b/src/opus-1.0.2/silk/PLC.h deleted file mode 100644 index 1d2d9061..00000000 --- a/src/opus-1.0.2/silk/PLC.h +++ /dev/null @@ -1,61 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifndef SILK_PLC_H -#define SILK_PLC_H - -#include "main.h" - -#define BWE_COEF 0.99 -#define V_PITCH_GAIN_START_MIN_Q14 11469 /* 0.7 in Q14 */ -#define V_PITCH_GAIN_START_MAX_Q14 15565 /* 0.95 in Q14 */ -#define MAX_PITCH_LAG_MS 18 -#define RAND_BUF_SIZE 128 -#define RAND_BUF_MASK ( RAND_BUF_SIZE - 1 ) -#define LOG2_INV_LPC_GAIN_HIGH_THRES 3 /* 2^3 = 8 dB LPC gain */ -#define LOG2_INV_LPC_GAIN_LOW_THRES 8 /* 2^8 = 24 dB LPC gain */ -#define PITCH_DRIFT_FAC_Q16 655 /* 0.01 in Q16 */ - -void silk_PLC_Reset( - silk_decoder_state *psDec /* I/O Decoder state */ -); - -void silk_PLC( - silk_decoder_state *psDec, /* I/O Decoder state */ - silk_decoder_control *psDecCtrl, /* I/O Decoder control */ - opus_int16 frame[], /* I/O signal */ - opus_int lost /* I Loss flag */ -); - -void silk_PLC_glue_frames( - silk_decoder_state *psDec, /* I/O decoder state */ - opus_int16 frame[], /* I/O signal */ - opus_int length /* I length of signal */ -); - -#endif - diff --git a/src/opus-1.0.2/silk/SigProc_FIX.h b/src/opus-1.0.2/silk/SigProc_FIX.h deleted file mode 100644 index daa5fd04..00000000 --- a/src/opus-1.0.2/silk/SigProc_FIX.h +++ /dev/null @@ -1,589 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifndef SILK_SIGPROC_FIX_H -#define SILK_SIGPROC_FIX_H - -#ifdef __cplusplus -extern "C" -{ -#endif - -/*#define silk_MACRO_COUNT */ /* Used to enable WMOPS counting */ - -#define SILK_MAX_ORDER_LPC 16 /* max order of the LPC analysis in schur() and k2a() */ - -#include /* for memset(), memcpy(), memmove() */ -#include "typedef.h" -#include "resampler_structs.h" -#include "macros.h" - - -/********************************************************************/ -/* SIGNAL PROCESSING FUNCTIONS */ -/********************************************************************/ - -/*! - * Initialize/reset the resampler state for a given pair of input/output sampling rates -*/ -opus_int silk_resampler_init( - silk_resampler_state_struct *S, /* I/O Resampler state */ - opus_int32 Fs_Hz_in, /* I Input sampling rate (Hz) */ - opus_int32 Fs_Hz_out, /* I Output sampling rate (Hz) */ - opus_int forEnc /* I If 1: encoder; if 0: decoder */ -); - -/*! - * Resampler: convert from one sampling rate to another - */ -opus_int silk_resampler( - silk_resampler_state_struct *S, /* I/O Resampler state */ - opus_int16 out[], /* O Output signal */ - const opus_int16 in[], /* I Input signal */ - opus_int32 inLen /* I Number of input samples */ -); - -/*! -* Downsample 2x, mediocre quality -*/ -void silk_resampler_down2( - opus_int32 *S, /* I/O State vector [ 2 ] */ - opus_int16 *out, /* O Output signal [ len ] */ - const opus_int16 *in, /* I Input signal [ floor(len/2) ] */ - opus_int32 inLen /* I Number of input samples */ -); - -/*! - * Downsample by a factor 2/3, low quality -*/ -void silk_resampler_down2_3( - opus_int32 *S, /* I/O State vector [ 6 ] */ - opus_int16 *out, /* O Output signal [ floor(2*inLen/3) ] */ - const opus_int16 *in, /* I Input signal [ inLen ] */ - opus_int32 inLen /* I Number of input samples */ -); - -/*! - * second order ARMA filter; - * slower than biquad() but uses more precise coefficients - * can handle (slowly) varying coefficients - */ -void silk_biquad_alt( - const opus_int16 *in, /* I input signal */ - const opus_int32 *B_Q28, /* I MA coefficients [3] */ - const opus_int32 *A_Q28, /* I AR coefficients [2] */ - opus_int32 *S, /* I/O State vector [2] */ - opus_int16 *out, /* O output signal */ - const opus_int32 len, /* I signal length (must be even) */ - opus_int stride /* I Operate on interleaved signal if > 1 */ -); - -/* Variable order MA prediction error filter. */ -void silk_LPC_analysis_filter( - opus_int16 *out, /* O Output signal */ - const opus_int16 *in, /* I Input signal */ - const opus_int16 *B, /* I MA prediction coefficients, Q12 [order] */ - const opus_int32 len, /* I Signal length */ - const opus_int32 d /* I Filter order */ -); - -/* Chirp (bandwidth expand) LP AR filter */ -void silk_bwexpander( - opus_int16 *ar, /* I/O AR filter to be expanded (without leading 1) */ - const opus_int d, /* I Length of ar */ - opus_int32 chirp_Q16 /* I Chirp factor (typically in the range 0 to 1) */ -); - -/* Chirp (bandwidth expand) LP AR filter */ -void silk_bwexpander_32( - opus_int32 *ar, /* I/O AR filter to be expanded (without leading 1) */ - const opus_int d, /* I Length of ar */ - opus_int32 chirp_Q16 /* I Chirp factor in Q16 */ -); - -/* Compute inverse of LPC prediction gain, and */ -/* test if LPC coefficients are stable (all poles within unit circle) */ -opus_int32 silk_LPC_inverse_pred_gain( /* O Returns inverse prediction gain in energy domain, Q30 */ - const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */ - const opus_int order /* I Prediction order */ -); - -/* For input in Q24 domain */ -opus_int32 silk_LPC_inverse_pred_gain_Q24( /* O Returns inverse prediction gain in energy domain, Q30 */ - const opus_int32 *A_Q24, /* I Prediction coefficients [order] */ - const opus_int order /* I Prediction order */ -); - -/* Split signal in two decimated bands using first-order allpass filters */ -void silk_ana_filt_bank_1( - const opus_int16 *in, /* I Input signal [N] */ - opus_int32 *S, /* I/O State vector [2] */ - opus_int16 *outL, /* O Low band [N/2] */ - opus_int16 *outH, /* O High band [N/2] */ - const opus_int32 N /* I Number of input samples */ -); - -/********************************************************************/ -/* SCALAR FUNCTIONS */ -/********************************************************************/ - -/* Approximation of 128 * log2() (exact inverse of approx 2^() below) */ -/* Convert input to a log scale */ -opus_int32 silk_lin2log( - const opus_int32 inLin /* I input in linear scale */ -); - -/* Approximation of a sigmoid function */ -opus_int silk_sigm_Q15( - opus_int in_Q5 /* I */ -); - -/* Approximation of 2^() (exact inverse of approx log2() above) */ -/* Convert input to a linear scale */ -opus_int32 silk_log2lin( - const opus_int32 inLog_Q7 /* I input on log scale */ -); - -/* Function that returns the maximum absolut value of the input vector */ -opus_int16 silk_int16_array_maxabs( /* O Maximum absolute value, max: 2^15-1 */ - const opus_int16 *vec, /* I Input vector [len] */ - const opus_int32 len /* I Length of input vector */ -); - -/* Compute number of bits to right shift the sum of squares of a vector */ -/* of int16s to make it fit in an int32 */ -void silk_sum_sqr_shift( - opus_int32 *energy, /* O Energy of x, after shifting to the right */ - opus_int *shift, /* O Number of bits right shift applied to energy */ - const opus_int16 *x, /* I Input vector */ - opus_int len /* I Length of input vector */ -); - -/* Calculates the reflection coefficients from the correlation sequence */ -/* Faster than schur64(), but much less accurate. */ -/* uses SMLAWB(), requiring armv5E and higher. */ -opus_int32 silk_schur( /* O Returns residual energy */ - opus_int16 *rc_Q15, /* O reflection coefficients [order] Q15 */ - const opus_int32 *c, /* I correlations [order+1] */ - const opus_int32 order /* I prediction order */ -); - -/* Calculates the reflection coefficients from the correlation sequence */ -/* Slower than schur(), but more accurate. */ -/* Uses SMULL(), available on armv4 */ -opus_int32 silk_schur64( /* O returns residual energy */ - opus_int32 rc_Q16[], /* O Reflection coefficients [order] Q16 */ - const opus_int32 c[], /* I Correlations [order+1] */ - opus_int32 order /* I Prediction order */ -); - -/* Step up function, converts reflection coefficients to prediction coefficients */ -void silk_k2a( - opus_int32 *A_Q24, /* O Prediction coefficients [order] Q24 */ - const opus_int16 *rc_Q15, /* I Reflection coefficients [order] Q15 */ - const opus_int32 order /* I Prediction order */ -); - -/* Step up function, converts reflection coefficients to prediction coefficients */ -void silk_k2a_Q16( - opus_int32 *A_Q24, /* O Prediction coefficients [order] Q24 */ - const opus_int32 *rc_Q16, /* I Reflection coefficients [order] Q16 */ - const opus_int32 order /* I Prediction order */ -); - -/* Apply sine window to signal vector. */ -/* Window types: */ -/* 1 -> sine window from 0 to pi/2 */ -/* 2 -> sine window from pi/2 to pi */ -/* every other sample of window is linearly interpolated, for speed */ -void silk_apply_sine_window( - opus_int16 px_win[], /* O Pointer to windowed signal */ - const opus_int16 px[], /* I Pointer to input signal */ - const opus_int win_type, /* I Selects a window type */ - const opus_int length /* I Window length, multiple of 4 */ -); - -/* Compute autocorrelation */ -void silk_autocorr( - opus_int32 *results, /* O Result (length correlationCount) */ - opus_int *scale, /* O Scaling of the correlation vector */ - const opus_int16 *inputData, /* I Input data to correlate */ - const opus_int inputDataSize, /* I Length of input */ - const opus_int correlationCount /* I Number of correlation taps to compute */ -); - -void silk_decode_pitch( - opus_int16 lagIndex, /* I */ - opus_int8 contourIndex, /* O */ - opus_int pitch_lags[], /* O 4 pitch values */ - const opus_int Fs_kHz, /* I sampling frequency (kHz) */ - const opus_int nb_subfr /* I number of sub frames */ -); - -opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0 voiced, 1 unvoiced */ - const opus_int16 *frame, /* I Signal of length PE_FRAME_LENGTH_MS*Fs_kHz */ - opus_int *pitch_out, /* O 4 pitch lag values */ - opus_int16 *lagIndex, /* O Lag Index */ - opus_int8 *contourIndex, /* O Pitch contour Index */ - opus_int *LTPCorr_Q15, /* I/O Normalized correlation; input: value from previous frame */ - opus_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */ - const opus_int32 search_thres1_Q16, /* I First stage threshold for lag candidates 0 - 1 */ - const opus_int search_thres2_Q15, /* I Final threshold for lag candidates 0 - 1 */ - const opus_int Fs_kHz, /* I Sample frequency (kHz) */ - const opus_int complexity, /* I Complexity setting, 0-2, where 2 is highest */ - const opus_int nb_subfr /* I number of 5 ms subframes */ -); - -/* Compute Normalized Line Spectral Frequencies (NLSFs) from whitening filter coefficients */ -/* If not all roots are found, the a_Q16 coefficients are bandwidth expanded until convergence. */ -void silk_A2NLSF( - opus_int16 *NLSF, /* O Normalized Line Spectral Frequencies in Q15 (0..2^15-1) [d] */ - opus_int32 *a_Q16, /* I/O Monic whitening filter coefficients in Q16 [d] */ - const opus_int d /* I Filter order (must be even) */ -); - -/* compute whitening filter coefficients from normalized line spectral frequencies */ -void silk_NLSF2A( - opus_int16 *a_Q12, /* O monic whitening filter coefficients in Q12, [ d ] */ - const opus_int16 *NLSF, /* I normalized line spectral frequencies in Q15, [ d ] */ - const opus_int d /* I filter order (should be even) */ -); - -void silk_insertion_sort_increasing( - opus_int32 *a, /* I/O Unsorted / Sorted vector */ - opus_int *idx, /* O Index vector for the sorted elements */ - const opus_int L, /* I Vector length */ - const opus_int K /* I Number of correctly sorted positions */ -); - -void silk_insertion_sort_decreasing_int16( - opus_int16 *a, /* I/O Unsorted / Sorted vector */ - opus_int *idx, /* O Index vector for the sorted elements */ - const opus_int L, /* I Vector length */ - const opus_int K /* I Number of correctly sorted positions */ -); - -void silk_insertion_sort_increasing_all_values_int16( - opus_int16 *a, /* I/O Unsorted / Sorted vector */ - const opus_int L /* I Vector length */ -); - -/* NLSF stabilizer, for a single input data vector */ -void silk_NLSF_stabilize( - opus_int16 *NLSF_Q15, /* I/O Unstable/stabilized normalized LSF vector in Q15 [L] */ - const opus_int16 *NDeltaMin_Q15, /* I Min distance vector, NDeltaMin_Q15[L] must be >= 1 [L+1] */ - const opus_int L /* I Number of NLSF parameters in the input vector */ -); - -/* Laroia low complexity NLSF weights */ -void silk_NLSF_VQ_weights_laroia( - opus_int16 *pNLSFW_Q_OUT, /* O Pointer to input vector weights [D] */ - const opus_int16 *pNLSF_Q15, /* I Pointer to input vector [D] */ - const opus_int D /* I Input vector dimension (even) */ -); - -/* Compute reflection coefficients from input signal */ -void silk_burg_modified( - opus_int32 *res_nrg, /* O Residual energy */ - opus_int *res_nrg_Q, /* O Residual energy Q value */ - opus_int32 A_Q16[], /* O Prediction coefficients (length order) */ - const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */ - const opus_int32 minInvGain_Q30, /* I Inverse of max prediction gain */ - const opus_int subfr_length, /* I Input signal subframe length (incl. D preceding samples) */ - const opus_int nb_subfr, /* I Number of subframes stacked in x */ - const opus_int D /* I Order */ -); - -/* Copy and multiply a vector by a constant */ -void silk_scale_copy_vector16( - opus_int16 *data_out, - const opus_int16 *data_in, - opus_int32 gain_Q16, /* I Gain in Q16 */ - const opus_int dataSize /* I Length */ -); - -/* Some for the LTP related function requires Q26 to work.*/ -void silk_scale_vector32_Q26_lshift_18( - opus_int32 *data1, /* I/O Q0/Q18 */ - opus_int32 gain_Q26, /* I Q26 */ - opus_int dataSize /* I length */ -); - -/********************************************************************/ -/* INLINE ARM MATH */ -/********************************************************************/ - -/* return sum( inVec1[i] * inVec2[i] ) */ -opus_int32 silk_inner_prod_aligned( - const opus_int16 *const inVec1, /* I input vector 1 */ - const opus_int16 *const inVec2, /* I input vector 2 */ - const opus_int len /* I vector lengths */ -); - -opus_int32 silk_inner_prod_aligned_scale( - const opus_int16 *const inVec1, /* I input vector 1 */ - const opus_int16 *const inVec2, /* I input vector 2 */ - const opus_int scale, /* I number of bits to shift */ - const opus_int len /* I vector lengths */ -); - -opus_int64 silk_inner_prod16_aligned_64( - const opus_int16 *inVec1, /* I input vector 1 */ - const opus_int16 *inVec2, /* I input vector 2 */ - const opus_int len /* I vector lengths */ -); - -/********************************************************************/ -/* MACROS */ -/********************************************************************/ - -/* Rotate a32 right by 'rot' bits. Negative rot values result in rotating - left. Output is 32bit int. - Note: contemporary compilers recognize the C expression below and - compile it into a 'ror' instruction if available. No need for inline ASM! */ -static inline opus_int32 silk_ROR32( opus_int32 a32, opus_int rot ) -{ - opus_uint32 x = (opus_uint32) a32; - opus_uint32 r = (opus_uint32) rot; - opus_uint32 m = (opus_uint32) -rot; - if( rot == 0 ) { - return a32; - } else if( rot < 0 ) { - return (opus_int32) ((x << m) | (x >> (32 - m))); - } else { - return (opus_int32) ((x << (32 - r)) | (x >> r)); - } -} - -/* Allocate opus_int16 aligned to 4-byte memory address */ -#if EMBEDDED_ARM -#define silk_DWORD_ALIGN __attribute__((aligned(4))) -#else -#define silk_DWORD_ALIGN -#endif - -/* Useful Macros that can be adjusted to other platforms */ -#define silk_memcpy(dest, src, size) memcpy((dest), (src), (size)) -#define silk_memset(dest, src, size) memset((dest), (src), (size)) -#define silk_memmove(dest, src, size) memmove((dest), (src), (size)) - -/* Fixed point macros */ - -/* (a32 * b32) output have to be 32bit int */ -#define silk_MUL(a32, b32) ((a32) * (b32)) - -/* (a32 * b32) output have to be 32bit uint */ -#define silk_MUL_uint(a32, b32) silk_MUL(a32, b32) - -/* a32 + (b32 * c32) output have to be 32bit int */ -#define silk_MLA(a32, b32, c32) silk_ADD32((a32),((b32) * (c32))) - -/* a32 + (b32 * c32) output have to be 32bit uint */ -#define silk_MLA_uint(a32, b32, c32) silk_MLA(a32, b32, c32) - -/* ((a32 >> 16) * (b32 >> 16)) output have to be 32bit int */ -#define silk_SMULTT(a32, b32) (((a32) >> 16) * ((b32) >> 16)) - -/* a32 + ((a32 >> 16) * (b32 >> 16)) output have to be 32bit int */ -#define silk_SMLATT(a32, b32, c32) silk_ADD32((a32),((b32) >> 16) * ((c32) >> 16)) - -#define silk_SMLALBB(a64, b16, c16) silk_ADD64((a64),(opus_int64)((opus_int32)(b16) * (opus_int32)(c16))) - -/* (a32 * b32) */ -#define silk_SMULL(a32, b32) ((opus_int64)(a32) * /*(opus_int64)*/(b32)) - -/* Adds two signed 32-bit values in a way that can overflow, while not relying on undefined behaviour - (just standard two's complement implementation-specific behaviour) */ -#define silk_ADD32_ovflw(a, b) ((opus_int32)((opus_uint32)(a) + (opus_uint32)(b))) -/* Subtractss two signed 32-bit values in a way that can overflow, while not relying on undefined behaviour - (just standard two's complement implementation-specific behaviour) */ -#define silk_SUB32_ovflw(a, b) ((opus_int32)((opus_uint32)(a) - (opus_uint32)(b))) - -/* Multiply-accumulate macros that allow overflow in the addition (ie, no asserts in debug mode) */ -#define silk_MLA_ovflw(a32, b32, c32) silk_ADD32_ovflw((a32), (opus_uint32)(b32) * (opus_uint32)(c32)) -#define silk_SMLABB_ovflw(a32, b32, c32) (silk_ADD32_ovflw((a32) , ((opus_int32)((opus_int16)(b32))) * (opus_int32)((opus_int16)(c32)))) - -#define silk_DIV32_16(a32, b16) ((opus_int32)((a32) / (b16))) -#define silk_DIV32(a32, b32) ((opus_int32)((a32) / (b32))) - -/* These macros enables checking for overflow in silk_API_Debug.h*/ -#define silk_ADD16(a, b) ((a) + (b)) -#define silk_ADD32(a, b) ((a) + (b)) -#define silk_ADD64(a, b) ((a) + (b)) - -#define silk_SUB16(a, b) ((a) - (b)) -#define silk_SUB32(a, b) ((a) - (b)) -#define silk_SUB64(a, b) ((a) - (b)) - -#define silk_SAT8(a) ((a) > silk_int8_MAX ? silk_int8_MAX : \ - ((a) < silk_int8_MIN ? silk_int8_MIN : (a))) -#define silk_SAT16(a) ((a) > silk_int16_MAX ? silk_int16_MAX : \ - ((a) < silk_int16_MIN ? silk_int16_MIN : (a))) -#define silk_SAT32(a) ((a) > silk_int32_MAX ? silk_int32_MAX : \ - ((a) < silk_int32_MIN ? silk_int32_MIN : (a))) - -#define silk_CHECK_FIT8(a) (a) -#define silk_CHECK_FIT16(a) (a) -#define silk_CHECK_FIT32(a) (a) - -#define silk_ADD_SAT16(a, b) (opus_int16)silk_SAT16( silk_ADD32( (opus_int32)(a), (b) ) ) -#define silk_ADD_SAT64(a, b) ((((a) + (b)) & 0x8000000000000000LL) == 0 ? \ - ((((a) & (b)) & 0x8000000000000000LL) != 0 ? silk_int64_MIN : (a)+(b)) : \ - ((((a) | (b)) & 0x8000000000000000LL) == 0 ? silk_int64_MAX : (a)+(b)) ) - -#define silk_SUB_SAT16(a, b) (opus_int16)silk_SAT16( silk_SUB32( (opus_int32)(a), (b) ) ) -#define silk_SUB_SAT64(a, b) ((((a)-(b)) & 0x8000000000000000LL) == 0 ? \ - (( (a) & ((b)^0x8000000000000000LL) & 0x8000000000000000LL) ? silk_int64_MIN : (a)-(b)) : \ - ((((a)^0x8000000000000000LL) & (b) & 0x8000000000000000LL) ? silk_int64_MAX : (a)-(b)) ) - -/* Saturation for positive input values */ -#define silk_POS_SAT32(a) ((a) > silk_int32_MAX ? silk_int32_MAX : (a)) - -/* Add with saturation for positive input values */ -#define silk_ADD_POS_SAT8(a, b) ((((a)+(b)) & 0x80) ? silk_int8_MAX : ((a)+(b))) -#define silk_ADD_POS_SAT16(a, b) ((((a)+(b)) & 0x8000) ? silk_int16_MAX : ((a)+(b))) -#define silk_ADD_POS_SAT32(a, b) ((((a)+(b)) & 0x80000000) ? silk_int32_MAX : ((a)+(b))) -#define silk_ADD_POS_SAT64(a, b) ((((a)+(b)) & 0x8000000000000000LL) ? silk_int64_MAX : ((a)+(b))) - -#define silk_LSHIFT8(a, shift) ((opus_int8)((opus_uint8)(a)<<(shift))) /* shift >= 0, shift < 8 */ -#define silk_LSHIFT16(a, shift) ((opus_int16)((opus_uint16)(a)<<(shift))) /* shift >= 0, shift < 16 */ -#define silk_LSHIFT32(a, shift) ((opus_int32)((opus_uint32)(a)<<(shift))) /* shift >= 0, shift < 32 */ -#define silk_LSHIFT64(a, shift) ((opus_int64)((opus_uint64)(a)<<(shift))) /* shift >= 0, shift < 64 */ -#define silk_LSHIFT(a, shift) silk_LSHIFT32(a, shift) /* shift >= 0, shift < 32 */ - -#define silk_RSHIFT8(a, shift) ((a)>>(shift)) /* shift >= 0, shift < 8 */ -#define silk_RSHIFT16(a, shift) ((a)>>(shift)) /* shift >= 0, shift < 16 */ -#define silk_RSHIFT32(a, shift) ((a)>>(shift)) /* shift >= 0, shift < 32 */ -#define silk_RSHIFT64(a, shift) ((a)>>(shift)) /* shift >= 0, shift < 64 */ -#define silk_RSHIFT(a, shift) silk_RSHIFT32(a, shift) /* shift >= 0, shift < 32 */ - -/* saturates before shifting */ -#define silk_LSHIFT_SAT32(a, shift) (silk_LSHIFT32( silk_LIMIT( (a), silk_RSHIFT32( silk_int32_MIN, (shift) ), \ - silk_RSHIFT32( silk_int32_MAX, (shift) ) ), (shift) )) - -#define silk_LSHIFT_ovflw(a, shift) ((opus_int32)((opus_uint32)(a) << (shift))) /* shift >= 0, allowed to overflow */ -#define silk_LSHIFT_uint(a, shift) ((a) << (shift)) /* shift >= 0 */ -#define silk_RSHIFT_uint(a, shift) ((a) >> (shift)) /* shift >= 0 */ - -#define silk_ADD_LSHIFT(a, b, shift) ((a) + silk_LSHIFT((b), (shift))) /* shift >= 0 */ -#define silk_ADD_LSHIFT32(a, b, shift) silk_ADD32((a), silk_LSHIFT32((b), (shift))) /* shift >= 0 */ -#define silk_ADD_LSHIFT_uint(a, b, shift) ((a) + silk_LSHIFT_uint((b), (shift))) /* shift >= 0 */ -#define silk_ADD_RSHIFT(a, b, shift) ((a) + silk_RSHIFT((b), (shift))) /* shift >= 0 */ -#define silk_ADD_RSHIFT32(a, b, shift) silk_ADD32((a), silk_RSHIFT32((b), (shift))) /* shift >= 0 */ -#define silk_ADD_RSHIFT_uint(a, b, shift) ((a) + silk_RSHIFT_uint((b), (shift))) /* shift >= 0 */ -#define silk_SUB_LSHIFT32(a, b, shift) silk_SUB32((a), silk_LSHIFT32((b), (shift))) /* shift >= 0 */ -#define silk_SUB_RSHIFT32(a, b, shift) silk_SUB32((a), silk_RSHIFT32((b), (shift))) /* shift >= 0 */ - -/* Requires that shift > 0 */ -#define silk_RSHIFT_ROUND(a, shift) ((shift) == 1 ? ((a) >> 1) + ((a) & 1) : (((a) >> ((shift) - 1)) + 1) >> 1) -#define silk_RSHIFT_ROUND64(a, shift) ((shift) == 1 ? ((a) >> 1) + ((a) & 1) : (((a) >> ((shift) - 1)) + 1) >> 1) - -/* Number of rightshift required to fit the multiplication */ -#define silk_NSHIFT_MUL_32_32(a, b) ( -(31- (32-silk_CLZ32(silk_abs(a)) + (32-silk_CLZ32(silk_abs(b))))) ) -#define silk_NSHIFT_MUL_16_16(a, b) ( -(15- (16-silk_CLZ16(silk_abs(a)) + (16-silk_CLZ16(silk_abs(b))))) ) - - -#define silk_min(a, b) (((a) < (b)) ? (a) : (b)) -#define silk_max(a, b) (((a) > (b)) ? (a) : (b)) - -/* Macro to convert floating-point constants to fixed-point */ -#define SILK_FIX_CONST( C, Q ) ((opus_int32)((C) * ((opus_int64)1 << (Q)) + 0.5)) - -/* silk_min() versions with typecast in the function call */ -static inline opus_int silk_min_int(opus_int a, opus_int b) -{ - return (((a) < (b)) ? (a) : (b)); -} -static inline opus_int16 silk_min_16(opus_int16 a, opus_int16 b) -{ - return (((a) < (b)) ? (a) : (b)); -} -static inline opus_int32 silk_min_32(opus_int32 a, opus_int32 b) -{ - return (((a) < (b)) ? (a) : (b)); -} -static inline opus_int64 silk_min_64(opus_int64 a, opus_int64 b) -{ - return (((a) < (b)) ? (a) : (b)); -} - -/* silk_min() versions with typecast in the function call */ -static inline opus_int silk_max_int(opus_int a, opus_int b) -{ - return (((a) > (b)) ? (a) : (b)); -} -static inline opus_int16 silk_max_16(opus_int16 a, opus_int16 b) -{ - return (((a) > (b)) ? (a) : (b)); -} -static inline opus_int32 silk_max_32(opus_int32 a, opus_int32 b) -{ - return (((a) > (b)) ? (a) : (b)); -} -static inline opus_int64 silk_max_64(opus_int64 a, opus_int64 b) -{ - return (((a) > (b)) ? (a) : (b)); -} - -#define silk_LIMIT( a, limit1, limit2) ((limit1) > (limit2) ? ((a) > (limit1) ? (limit1) : ((a) < (limit2) ? (limit2) : (a))) \ - : ((a) > (limit2) ? (limit2) : ((a) < (limit1) ? (limit1) : (a)))) - -#define silk_LIMIT_int silk_LIMIT -#define silk_LIMIT_16 silk_LIMIT -#define silk_LIMIT_32 silk_LIMIT - -#define silk_abs(a) (((a) > 0) ? (a) : -(a)) /* Be careful, silk_abs returns wrong when input equals to silk_intXX_MIN */ -#define silk_abs_int(a) (((a) ^ ((a) >> (8 * sizeof(a) - 1))) - ((a) >> (8 * sizeof(a) - 1))) -#define silk_abs_int32(a) (((a) ^ ((a) >> 31)) - ((a) >> 31)) -#define silk_abs_int64(a) (((a) > 0) ? (a) : -(a)) - -#define silk_sign(a) ((a) > 0 ? 1 : ( (a) < 0 ? -1 : 0 )) - -/* PSEUDO-RANDOM GENERATOR */ -/* Make sure to store the result as the seed for the next call (also in between */ -/* frames), otherwise result won't be random at all. When only using some of the */ -/* bits, take the most significant bits by right-shifting. */ -#define silk_RAND(seed) (silk_MLA_ovflw(907633515, (seed), 196314165)) - -/* Add some multiplication functions that can be easily mapped to ARM. */ - -/* silk_SMMUL: Signed top word multiply. - ARMv6 2 instruction cycles. - ARMv3M+ 3 instruction cycles. use SMULL and ignore LSB registers.(except xM)*/ -/*#define silk_SMMUL(a32, b32) (opus_int32)silk_RSHIFT(silk_SMLAL(silk_SMULWB((a32), (b32)), (a32), silk_RSHIFT_ROUND((b32), 16)), 16)*/ -/* the following seems faster on x86 */ -#define silk_SMMUL(a32, b32) (opus_int32)silk_RSHIFT64(silk_SMULL((a32), (b32)), 32) - -#include "Inlines.h" -#include "MacroCount.h" -#include "MacroDebug.h" - -#ifdef __cplusplus -} -#endif - -#endif /* SILK_SIGPROC_FIX_H */ diff --git a/src/opus-1.0.2/silk/VAD.c b/src/opus-1.0.2/silk/VAD.c deleted file mode 100644 index bac89b44..00000000 --- a/src/opus-1.0.2/silk/VAD.c +++ /dev/null @@ -1,330 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main.h" - -/* Silk VAD noise level estimation */ -static inline void silk_VAD_GetNoiseLevels( - const opus_int32 pX[ VAD_N_BANDS ], /* I subband energies */ - silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */ -); - -/**********************************/ -/* Initialization of the Silk VAD */ -/**********************************/ -opus_int silk_VAD_Init( /* O Return value, 0 if success */ - silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */ -) -{ - opus_int b, ret = 0; - - /* reset state memory */ - silk_memset( psSilk_VAD, 0, sizeof( silk_VAD_state ) ); - - /* init noise levels */ - /* Initialize array with approx pink noise levels (psd proportional to inverse of frequency) */ - for( b = 0; b < VAD_N_BANDS; b++ ) { - psSilk_VAD->NoiseLevelBias[ b ] = silk_max_32( silk_DIV32_16( VAD_NOISE_LEVELS_BIAS, b + 1 ), 1 ); - } - - /* Initialize state */ - for( b = 0; b < VAD_N_BANDS; b++ ) { - psSilk_VAD->NL[ b ] = silk_MUL( 100, psSilk_VAD->NoiseLevelBias[ b ] ); - psSilk_VAD->inv_NL[ b ] = silk_DIV32( silk_int32_MAX, psSilk_VAD->NL[ b ] ); - } - psSilk_VAD->counter = 15; - - /* init smoothed energy-to-noise ratio*/ - for( b = 0; b < VAD_N_BANDS; b++ ) { - psSilk_VAD->NrgRatioSmth_Q8[ b ] = 100 * 256; /* 100 * 256 --> 20 dB SNR */ - } - - return( ret ); -} - -/* Weighting factors for tilt measure */ -static const opus_int32 tiltWeights[ VAD_N_BANDS ] = { 30000, 6000, -12000, -12000 }; - -/***************************************/ -/* Get the speech activity level in Q8 */ -/***************************************/ -opus_int silk_VAD_GetSA_Q8( /* O Return value, 0 if success */ - silk_encoder_state *psEncC, /* I/O Encoder state */ - const opus_int16 pIn[] /* I PCM input */ -) -{ - opus_int SA_Q15, pSNR_dB_Q7, input_tilt; - opus_int decimated_framelength, dec_subframe_length, dec_subframe_offset, SNR_Q7, i, b, s; - opus_int32 sumSquared, smooth_coef_Q16; - opus_int16 HPstateTmp; - opus_int16 X[ VAD_N_BANDS ][ MAX_FRAME_LENGTH / 2 ]; - opus_int32 Xnrg[ VAD_N_BANDS ]; - opus_int32 NrgToNoiseRatio_Q8[ VAD_N_BANDS ]; - opus_int32 speech_nrg, x_tmp; - opus_int ret = 0; - silk_VAD_state *psSilk_VAD = &psEncC->sVAD; - - /* Safety checks */ - silk_assert( VAD_N_BANDS == 4 ); - silk_assert( MAX_FRAME_LENGTH >= psEncC->frame_length ); - silk_assert( psEncC->frame_length <= 512 ); - silk_assert( psEncC->frame_length == 8 * silk_RSHIFT( psEncC->frame_length, 3 ) ); - - /***********************/ - /* Filter and Decimate */ - /***********************/ - /* 0-8 kHz to 0-4 kHz and 4-8 kHz */ - silk_ana_filt_bank_1( pIn, &psSilk_VAD->AnaState[ 0 ], &X[ 0 ][ 0 ], &X[ 3 ][ 0 ], psEncC->frame_length ); - - /* 0-4 kHz to 0-2 kHz and 2-4 kHz */ - silk_ana_filt_bank_1( &X[ 0 ][ 0 ], &psSilk_VAD->AnaState1[ 0 ], &X[ 0 ][ 0 ], &X[ 2 ][ 0 ], silk_RSHIFT( psEncC->frame_length, 1 ) ); - - /* 0-2 kHz to 0-1 kHz and 1-2 kHz */ - silk_ana_filt_bank_1( &X[ 0 ][ 0 ], &psSilk_VAD->AnaState2[ 0 ], &X[ 0 ][ 0 ], &X[ 1 ][ 0 ], silk_RSHIFT( psEncC->frame_length, 2 ) ); - - /*********************************************/ - /* HP filter on lowest band (differentiator) */ - /*********************************************/ - decimated_framelength = silk_RSHIFT( psEncC->frame_length, 3 ); - X[ 0 ][ decimated_framelength - 1 ] = silk_RSHIFT( X[ 0 ][ decimated_framelength - 1 ], 1 ); - HPstateTmp = X[ 0 ][ decimated_framelength - 1 ]; - for( i = decimated_framelength - 1; i > 0; i-- ) { - X[ 0 ][ i - 1 ] = silk_RSHIFT( X[ 0 ][ i - 1 ], 1 ); - X[ 0 ][ i ] -= X[ 0 ][ i - 1 ]; - } - X[ 0 ][ 0 ] -= psSilk_VAD->HPstate; - psSilk_VAD->HPstate = HPstateTmp; - - /*************************************/ - /* Calculate the energy in each band */ - /*************************************/ - for( b = 0; b < VAD_N_BANDS; b++ ) { - /* Find the decimated framelength in the non-uniformly divided bands */ - decimated_framelength = silk_RSHIFT( psEncC->frame_length, silk_min_int( VAD_N_BANDS - b, VAD_N_BANDS - 1 ) ); - - /* Split length into subframe lengths */ - dec_subframe_length = silk_RSHIFT( decimated_framelength, VAD_INTERNAL_SUBFRAMES_LOG2 ); - dec_subframe_offset = 0; - - /* Compute energy per sub-frame */ - /* initialize with summed energy of last subframe */ - Xnrg[ b ] = psSilk_VAD->XnrgSubfr[ b ]; - for( s = 0; s < VAD_INTERNAL_SUBFRAMES; s++ ) { - sumSquared = 0; - for( i = 0; i < dec_subframe_length; i++ ) { - /* The energy will be less than dec_subframe_length * ( silk_int16_MIN / 8 ) ^ 2. */ - /* Therefore we can accumulate with no risk of overflow (unless dec_subframe_length > 128) */ - x_tmp = silk_RSHIFT( X[ b ][ i + dec_subframe_offset ], 3 ); - sumSquared = silk_SMLABB( sumSquared, x_tmp, x_tmp ); - - /* Safety check */ - silk_assert( sumSquared >= 0 ); - } - - /* Add/saturate summed energy of current subframe */ - if( s < VAD_INTERNAL_SUBFRAMES - 1 ) { - Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], sumSquared ); - } else { - /* Look-ahead subframe */ - Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], silk_RSHIFT( sumSquared, 1 ) ); - } - - dec_subframe_offset += dec_subframe_length; - } - psSilk_VAD->XnrgSubfr[ b ] = sumSquared; - } - - /********************/ - /* Noise estimation */ - /********************/ - silk_VAD_GetNoiseLevels( &Xnrg[ 0 ], psSilk_VAD ); - - /***********************************************/ - /* Signal-plus-noise to noise ratio estimation */ - /***********************************************/ - sumSquared = 0; - input_tilt = 0; - for( b = 0; b < VAD_N_BANDS; b++ ) { - speech_nrg = Xnrg[ b ] - psSilk_VAD->NL[ b ]; - if( speech_nrg > 0 ) { - /* Divide, with sufficient resolution */ - if( ( Xnrg[ b ] & 0xFF800000 ) == 0 ) { - NrgToNoiseRatio_Q8[ b ] = silk_DIV32( silk_LSHIFT( Xnrg[ b ], 8 ), psSilk_VAD->NL[ b ] + 1 ); - } else { - NrgToNoiseRatio_Q8[ b ] = silk_DIV32( Xnrg[ b ], silk_RSHIFT( psSilk_VAD->NL[ b ], 8 ) + 1 ); - } - - /* Convert to log domain */ - SNR_Q7 = silk_lin2log( NrgToNoiseRatio_Q8[ b ] ) - 8 * 128; - - /* Sum-of-squares */ - sumSquared = silk_SMLABB( sumSquared, SNR_Q7, SNR_Q7 ); /* Q14 */ - - /* Tilt measure */ - if( speech_nrg < ( (opus_int32)1 << 20 ) ) { - /* Scale down SNR value for small subband speech energies */ - SNR_Q7 = silk_SMULWB( silk_LSHIFT( silk_SQRT_APPROX( speech_nrg ), 6 ), SNR_Q7 ); - } - input_tilt = silk_SMLAWB( input_tilt, tiltWeights[ b ], SNR_Q7 ); - } else { - NrgToNoiseRatio_Q8[ b ] = 256; - } - } - - /* Mean-of-squares */ - sumSquared = silk_DIV32_16( sumSquared, VAD_N_BANDS ); /* Q14 */ - - /* Root-mean-square approximation, scale to dBs, and write to output pointer */ - pSNR_dB_Q7 = (opus_int16)( 3 * silk_SQRT_APPROX( sumSquared ) ); /* Q7 */ - - /*********************************/ - /* Speech Probability Estimation */ - /*********************************/ - SA_Q15 = silk_sigm_Q15( silk_SMULWB( VAD_SNR_FACTOR_Q16, pSNR_dB_Q7 ) - VAD_NEGATIVE_OFFSET_Q5 ); - - /**************************/ - /* Frequency Tilt Measure */ - /**************************/ - psEncC->input_tilt_Q15 = silk_LSHIFT( silk_sigm_Q15( input_tilt ) - 16384, 1 ); - - /**************************************************/ - /* Scale the sigmoid output based on power levels */ - /**************************************************/ - speech_nrg = 0; - for( b = 0; b < VAD_N_BANDS; b++ ) { - /* Accumulate signal-without-noise energies, higher frequency bands have more weight */ - speech_nrg += ( b + 1 ) * silk_RSHIFT( Xnrg[ b ] - psSilk_VAD->NL[ b ], 4 ); - } - - /* Power scaling */ - if( speech_nrg <= 0 ) { - SA_Q15 = silk_RSHIFT( SA_Q15, 1 ); - } else if( speech_nrg < 32768 ) { - if( psEncC->frame_length == 10 * psEncC->fs_kHz ) { - speech_nrg = silk_LSHIFT_SAT32( speech_nrg, 16 ); - } else { - speech_nrg = silk_LSHIFT_SAT32( speech_nrg, 15 ); - } - - /* square-root */ - speech_nrg = silk_SQRT_APPROX( speech_nrg ); - SA_Q15 = silk_SMULWB( 32768 + speech_nrg, SA_Q15 ); - } - - /* Copy the resulting speech activity in Q8 */ - psEncC->speech_activity_Q8 = silk_min_int( silk_RSHIFT( SA_Q15, 7 ), silk_uint8_MAX ); - - /***********************************/ - /* Energy Level and SNR estimation */ - /***********************************/ - /* Smoothing coefficient */ - smooth_coef_Q16 = silk_SMULWB( VAD_SNR_SMOOTH_COEF_Q18, silk_SMULWB( (opus_int32)SA_Q15, SA_Q15 ) ); - - if( psEncC->frame_length == 10 * psEncC->fs_kHz ) { - smooth_coef_Q16 >>= 1; - } - - for( b = 0; b < VAD_N_BANDS; b++ ) { - /* compute smoothed energy-to-noise ratio per band */ - psSilk_VAD->NrgRatioSmth_Q8[ b ] = silk_SMLAWB( psSilk_VAD->NrgRatioSmth_Q8[ b ], - NrgToNoiseRatio_Q8[ b ] - psSilk_VAD->NrgRatioSmth_Q8[ b ], smooth_coef_Q16 ); - - /* signal to noise ratio in dB per band */ - SNR_Q7 = 3 * ( silk_lin2log( psSilk_VAD->NrgRatioSmth_Q8[b] ) - 8 * 128 ); - /* quality = sigmoid( 0.25 * ( SNR_dB - 16 ) ); */ - psEncC->input_quality_bands_Q15[ b ] = silk_sigm_Q15( silk_RSHIFT( SNR_Q7 - 16 * 128, 4 ) ); - } - - return( ret ); -} - -/**************************/ -/* Noise level estimation */ -/**************************/ -static inline void silk_VAD_GetNoiseLevels( - const opus_int32 pX[ VAD_N_BANDS ], /* I subband energies */ - silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */ -) -{ - opus_int k; - opus_int32 nl, nrg, inv_nrg; - opus_int coef, min_coef; - - /* Initially faster smoothing */ - if( psSilk_VAD->counter < 1000 ) { /* 1000 = 20 sec */ - min_coef = silk_DIV32_16( silk_int16_MAX, silk_RSHIFT( psSilk_VAD->counter, 4 ) + 1 ); - } else { - min_coef = 0; - } - - for( k = 0; k < VAD_N_BANDS; k++ ) { - /* Get old noise level estimate for current band */ - nl = psSilk_VAD->NL[ k ]; - silk_assert( nl >= 0 ); - - /* Add bias */ - nrg = silk_ADD_POS_SAT32( pX[ k ], psSilk_VAD->NoiseLevelBias[ k ] ); - silk_assert( nrg > 0 ); - - /* Invert energies */ - inv_nrg = silk_DIV32( silk_int32_MAX, nrg ); - silk_assert( inv_nrg >= 0 ); - - /* Less update when subband energy is high */ - if( nrg > silk_LSHIFT( nl, 3 ) ) { - coef = VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 >> 3; - } else if( nrg < nl ) { - coef = VAD_NOISE_LEVEL_SMOOTH_COEF_Q16; - } else { - coef = silk_SMULWB( silk_SMULWW( inv_nrg, nl ), VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 << 1 ); - } - - /* Initially faster smoothing */ - coef = silk_max_int( coef, min_coef ); - - /* Smooth inverse energies */ - psSilk_VAD->inv_NL[ k ] = silk_SMLAWB( psSilk_VAD->inv_NL[ k ], inv_nrg - psSilk_VAD->inv_NL[ k ], coef ); - silk_assert( psSilk_VAD->inv_NL[ k ] >= 0 ); - - /* Compute noise level by inverting again */ - nl = silk_DIV32( silk_int32_MAX, psSilk_VAD->inv_NL[ k ] ); - silk_assert( nl >= 0 ); - - /* Limit noise levels (guarantee 7 bits of head room) */ - nl = silk_min( nl, 0x00FFFFFF ); - - /* Store as part of state */ - psSilk_VAD->NL[ k ] = nl; - } - - /* Increment frame counter */ - psSilk_VAD->counter++; -} diff --git a/src/opus-1.0.2/silk/VQ_WMat_EC.c b/src/opus-1.0.2/silk/VQ_WMat_EC.c deleted file mode 100644 index a308cfbf..00000000 --- a/src/opus-1.0.2/silk/VQ_WMat_EC.c +++ /dev/null @@ -1,111 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main.h" - -/* Entropy constrained matrix-weighted VQ, hard-coded to 5-element vectors, for a single input data vector */ -void silk_VQ_WMat_EC( - opus_int8 *ind, /* O index of best codebook vector */ - opus_int32 *rate_dist_Q14, /* O best weighted quant error + mu * rate */ - const opus_int16 *in_Q14, /* I input vector to be quantized */ - const opus_int32 *W_Q18, /* I weighting matrix */ - const opus_int8 *cb_Q7, /* I codebook */ - const opus_uint8 *cl_Q5, /* I code length for each codebook vector */ - const opus_int mu_Q9, /* I tradeoff betw. weighted error and rate */ - opus_int L /* I number of vectors in codebook */ -) -{ - opus_int k; - const opus_int8 *cb_row_Q7; - opus_int16 diff_Q14[ 5 ]; - opus_int32 sum1_Q14, sum2_Q16; - - /* Loop over codebook */ - *rate_dist_Q14 = silk_int32_MAX; - cb_row_Q7 = cb_Q7; - for( k = 0; k < L; k++ ) { - diff_Q14[ 0 ] = in_Q14[ 0 ] - silk_LSHIFT( cb_row_Q7[ 0 ], 7 ); - diff_Q14[ 1 ] = in_Q14[ 1 ] - silk_LSHIFT( cb_row_Q7[ 1 ], 7 ); - diff_Q14[ 2 ] = in_Q14[ 2 ] - silk_LSHIFT( cb_row_Q7[ 2 ], 7 ); - diff_Q14[ 3 ] = in_Q14[ 3 ] - silk_LSHIFT( cb_row_Q7[ 3 ], 7 ); - diff_Q14[ 4 ] = in_Q14[ 4 ] - silk_LSHIFT( cb_row_Q7[ 4 ], 7 ); - - /* Weighted rate */ - sum1_Q14 = silk_SMULBB( mu_Q9, cl_Q5[ k ] ); - - silk_assert( sum1_Q14 >= 0 ); - - /* first row of W_Q18 */ - sum2_Q16 = silk_SMULWB( W_Q18[ 1 ], diff_Q14[ 1 ] ); - sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 2 ], diff_Q14[ 2 ] ); - sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 3 ], diff_Q14[ 3 ] ); - sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 4 ], diff_Q14[ 4 ] ); - sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 ); - sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 0 ], diff_Q14[ 0 ] ); - sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 0 ] ); - - /* second row of W_Q18 */ - sum2_Q16 = silk_SMULWB( W_Q18[ 7 ], diff_Q14[ 2 ] ); - sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 8 ], diff_Q14[ 3 ] ); - sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 9 ], diff_Q14[ 4 ] ); - sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 ); - sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 6 ], diff_Q14[ 1 ] ); - sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 1 ] ); - - /* third row of W_Q18 */ - sum2_Q16 = silk_SMULWB( W_Q18[ 13 ], diff_Q14[ 3 ] ); - sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 14 ], diff_Q14[ 4 ] ); - sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 ); - sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 12 ], diff_Q14[ 2 ] ); - sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 2 ] ); - - /* fourth row of W_Q18 */ - sum2_Q16 = silk_SMULWB( W_Q18[ 19 ], diff_Q14[ 4 ] ); - sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 ); - sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 18 ], diff_Q14[ 3 ] ); - sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 3 ] ); - - /* last row of W_Q18 */ - sum2_Q16 = silk_SMULWB( W_Q18[ 24 ], diff_Q14[ 4 ] ); - sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 4 ] ); - - silk_assert( sum1_Q14 >= 0 ); - - /* find best */ - if( sum1_Q14 < *rate_dist_Q14 ) { - *rate_dist_Q14 = sum1_Q14; - *ind = (opus_int8)k; - } - - /* Go to next cbk vector */ - cb_row_Q7 += LTP_ORDER; - } -} diff --git a/src/opus-1.0.2/silk/ana_filt_bank_1.c b/src/opus-1.0.2/silk/ana_filt_bank_1.c deleted file mode 100644 index 4e04bef3..00000000 --- a/src/opus-1.0.2/silk/ana_filt_bank_1.c +++ /dev/null @@ -1,74 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "SigProc_FIX.h" - -/* Coefficients for 2-band filter bank based on first-order allpass filters */ -static opus_int16 A_fb1_20 = 5394 << 1; -static opus_int16 A_fb1_21 = -24290; /* (opus_int16)(20623 << 1) */ - -/* Split signal into two decimated bands using first-order allpass filters */ -void silk_ana_filt_bank_1( - const opus_int16 *in, /* I Input signal [N] */ - opus_int32 *S, /* I/O State vector [2] */ - opus_int16 *outL, /* O Low band [N/2] */ - opus_int16 *outH, /* O High band [N/2] */ - const opus_int32 N /* I Number of input samples */ -) -{ - opus_int k, N2 = silk_RSHIFT( N, 1 ); - opus_int32 in32, X, Y, out_1, out_2; - - /* Internal variables and state are in Q10 format */ - for( k = 0; k < N2; k++ ) { - /* Convert to Q10 */ - in32 = silk_LSHIFT( (opus_int32)in[ 2 * k ], 10 ); - - /* All-pass section for even input sample */ - Y = silk_SUB32( in32, S[ 0 ] ); - X = silk_SMLAWB( Y, Y, A_fb1_21 ); - out_1 = silk_ADD32( S[ 0 ], X ); - S[ 0 ] = silk_ADD32( in32, X ); - - /* Convert to Q10 */ - in32 = silk_LSHIFT( (opus_int32)in[ 2 * k + 1 ], 10 ); - - /* All-pass section for odd input sample, and add to output of previous section */ - Y = silk_SUB32( in32, S[ 1 ] ); - X = silk_SMULWB( Y, A_fb1_20 ); - out_2 = silk_ADD32( S[ 1 ], X ); - S[ 1 ] = silk_ADD32( in32, X ); - - /* Add/subtract, convert back to int16 and store to output */ - outL[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_ADD32( out_2, out_1 ), 11 ) ); - outH[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SUB32( out_2, out_1 ), 11 ) ); - } -} diff --git a/src/opus-1.0.2/silk/biquad_alt.c b/src/opus-1.0.2/silk/biquad_alt.c deleted file mode 100644 index a639e21a..00000000 --- a/src/opus-1.0.2/silk/biquad_alt.c +++ /dev/null @@ -1,78 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -/* * - * silk_biquad_alt.c * - * * - * Second order ARMA filter * - * Can handle slowly varying filter coefficients * - * */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "SigProc_FIX.h" - -/* Second order ARMA filter, alternative implementation */ -void silk_biquad_alt( - const opus_int16 *in, /* I input signal */ - const opus_int32 *B_Q28, /* I MA coefficients [3] */ - const opus_int32 *A_Q28, /* I AR coefficients [2] */ - opus_int32 *S, /* I/O State vector [2] */ - opus_int16 *out, /* O output signal */ - const opus_int32 len, /* I signal length (must be even) */ - opus_int stride /* I Operate on interleaved signal if > 1 */ -) -{ - /* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */ - opus_int k; - opus_int32 inval, A0_U_Q28, A0_L_Q28, A1_U_Q28, A1_L_Q28, out32_Q14; - - /* Negate A_Q28 values and split in two parts */ - A0_L_Q28 = ( -A_Q28[ 0 ] ) & 0x00003FFF; /* lower part */ - A0_U_Q28 = silk_RSHIFT( -A_Q28[ 0 ], 14 ); /* upper part */ - A1_L_Q28 = ( -A_Q28[ 1 ] ) & 0x00003FFF; /* lower part */ - A1_U_Q28 = silk_RSHIFT( -A_Q28[ 1 ], 14 ); /* upper part */ - - for( k = 0; k < len; k++ ) { - /* S[ 0 ], S[ 1 ]: Q12 */ - inval = in[ k * stride ]; - out32_Q14 = silk_LSHIFT( silk_SMLAWB( S[ 0 ], B_Q28[ 0 ], inval ), 2 ); - - S[ 0 ] = S[1] + silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14, A0_L_Q28 ), 14 ); - S[ 0 ] = silk_SMLAWB( S[ 0 ], out32_Q14, A0_U_Q28 ); - S[ 0 ] = silk_SMLAWB( S[ 0 ], B_Q28[ 1 ], inval); - - S[ 1 ] = silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14, A1_L_Q28 ), 14 ); - S[ 1 ] = silk_SMLAWB( S[ 1 ], out32_Q14, A1_U_Q28 ); - S[ 1 ] = silk_SMLAWB( S[ 1 ], B_Q28[ 2 ], inval ); - - /* Scale back to Q0 and saturate */ - out[ k * stride ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14 + (1<<14) - 1, 14 ) ); - } -} diff --git a/src/opus-1.0.2/silk/bwexpander.c b/src/opus-1.0.2/silk/bwexpander.c deleted file mode 100644 index 77ea1163..00000000 --- a/src/opus-1.0.2/silk/bwexpander.c +++ /dev/null @@ -1,51 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "SigProc_FIX.h" - -/* Chirp (bandwidth expand) LP AR filter */ -void silk_bwexpander( - opus_int16 *ar, /* I/O AR filter to be expanded (without leading 1) */ - const opus_int d, /* I Length of ar */ - opus_int32 chirp_Q16 /* I Chirp factor (typically in the range 0 to 1) */ -) -{ - opus_int i; - opus_int32 chirp_minus_one_Q16 = chirp_Q16 - 65536; - - /* NB: Dont use silk_SMULWB, instead of silk_RSHIFT_ROUND( silk_MUL(), 16 ), below. */ - /* Bias in silk_SMULWB can lead to unstable filters */ - for( i = 0; i < d - 1; i++ ) { - ar[ i ] = (opus_int16)silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, ar[ i ] ), 16 ); - chirp_Q16 += silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, chirp_minus_one_Q16 ), 16 ); - } - ar[ d - 1 ] = (opus_int16)silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, ar[ d - 1 ] ), 16 ); -} diff --git a/src/opus-1.0.2/silk/bwexpander_32.c b/src/opus-1.0.2/silk/bwexpander_32.c deleted file mode 100644 index 5ad92dd4..00000000 --- a/src/opus-1.0.2/silk/bwexpander_32.c +++ /dev/null @@ -1,50 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "SigProc_FIX.h" - -/* Chirp (bandwidth expand) LP AR filter */ -void silk_bwexpander_32( - opus_int32 *ar, /* I/O AR filter to be expanded (without leading 1) */ - const opus_int d, /* I Length of ar */ - opus_int32 chirp_Q16 /* I Chirp factor in Q16 */ -) -{ - opus_int i; - opus_int32 chirp_minus_one_Q16 = chirp_Q16 - 65536; - - for( i = 0; i < d - 1; i++ ) { - ar[ i ] = silk_SMULWW( chirp_Q16, ar[ i ] ); - chirp_Q16 += silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, chirp_minus_one_Q16 ), 16 ); - } - ar[ d - 1 ] = silk_SMULWW( chirp_Q16, ar[ d - 1 ] ); -} - diff --git a/src/opus-1.0.2/silk/check_control_input.c b/src/opus-1.0.2/silk/check_control_input.c deleted file mode 100644 index 972a480d..00000000 --- a/src/opus-1.0.2/silk/check_control_input.c +++ /dev/null @@ -1,106 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main.h" -#include "control.h" -#include "errors.h" - -/* Check encoder control struct */ -opus_int check_control_input( - silk_EncControlStruct *encControl /* I Control structure */ -) -{ - silk_assert( encControl != NULL ); - - if( ( ( encControl->API_sampleRate != 8000 ) && - ( encControl->API_sampleRate != 12000 ) && - ( encControl->API_sampleRate != 16000 ) && - ( encControl->API_sampleRate != 24000 ) && - ( encControl->API_sampleRate != 32000 ) && - ( encControl->API_sampleRate != 44100 ) && - ( encControl->API_sampleRate != 48000 ) ) || - ( ( encControl->desiredInternalSampleRate != 8000 ) && - ( encControl->desiredInternalSampleRate != 12000 ) && - ( encControl->desiredInternalSampleRate != 16000 ) ) || - ( ( encControl->maxInternalSampleRate != 8000 ) && - ( encControl->maxInternalSampleRate != 12000 ) && - ( encControl->maxInternalSampleRate != 16000 ) ) || - ( ( encControl->minInternalSampleRate != 8000 ) && - ( encControl->minInternalSampleRate != 12000 ) && - ( encControl->minInternalSampleRate != 16000 ) ) || - ( encControl->minInternalSampleRate > encControl->desiredInternalSampleRate ) || - ( encControl->maxInternalSampleRate < encControl->desiredInternalSampleRate ) || - ( encControl->minInternalSampleRate > encControl->maxInternalSampleRate ) ) { - silk_assert( 0 ); - return SILK_ENC_FS_NOT_SUPPORTED; - } - if( encControl->payloadSize_ms != 10 && - encControl->payloadSize_ms != 20 && - encControl->payloadSize_ms != 40 && - encControl->payloadSize_ms != 60 ) { - silk_assert( 0 ); - return SILK_ENC_PACKET_SIZE_NOT_SUPPORTED; - } - if( encControl->packetLossPercentage < 0 || encControl->packetLossPercentage > 100 ) { - silk_assert( 0 ); - return SILK_ENC_INVALID_LOSS_RATE; - } - if( encControl->useDTX < 0 || encControl->useDTX > 1 ) { - silk_assert( 0 ); - return SILK_ENC_INVALID_DTX_SETTING; - } - if( encControl->useCBR < 0 || encControl->useCBR > 1 ) { - silk_assert( 0 ); - return SILK_ENC_INVALID_CBR_SETTING; - } - if( encControl->useInBandFEC < 0 || encControl->useInBandFEC > 1 ) { - silk_assert( 0 ); - return SILK_ENC_INVALID_INBAND_FEC_SETTING; - } - if( encControl->nChannelsAPI < 1 || encControl->nChannelsAPI > ENCODER_NUM_CHANNELS ) { - silk_assert( 0 ); - return SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR; - } - if( encControl->nChannelsInternal < 1 || encControl->nChannelsInternal > ENCODER_NUM_CHANNELS ) { - silk_assert( 0 ); - return SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR; - } - if( encControl->nChannelsInternal > encControl->nChannelsAPI ) { - silk_assert( 0 ); - return SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR; - } - if( encControl->complexity < 0 || encControl->complexity > 10 ) { - silk_assert( 0 ); - return SILK_ENC_INVALID_COMPLEXITY_SETTING; - } - - return SILK_NO_ERROR; -} diff --git a/src/opus-1.0.2/silk/code_signs.c b/src/opus-1.0.2/silk/code_signs.c deleted file mode 100644 index 9893cdd8..00000000 --- a/src/opus-1.0.2/silk/code_signs.c +++ /dev/null @@ -1,115 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main.h" - -/*#define silk_enc_map(a) ((a) > 0 ? 1 : 0)*/ -/*#define silk_dec_map(a) ((a) > 0 ? 1 : -1)*/ -/* shifting avoids if-statement */ -#define silk_enc_map(a) ( silk_RSHIFT( (a), 15 ) + 1 ) -#define silk_dec_map(a) ( silk_LSHIFT( (a), 1 ) - 1 ) - -/* Encodes signs of excitation */ -void silk_encode_signs( - ec_enc *psRangeEnc, /* I/O Compressor data structure */ - const opus_int8 pulses[], /* I pulse signal */ - opus_int length, /* I length of input */ - const opus_int signalType, /* I Signal type */ - const opus_int quantOffsetType, /* I Quantization offset type */ - const opus_int sum_pulses[ MAX_NB_SHELL_BLOCKS ] /* I Sum of absolute pulses per block */ -) -{ - opus_int i, j, p; - opus_uint8 icdf[ 2 ]; - const opus_int8 *q_ptr; - const opus_uint8 *icdf_ptr; - - icdf[ 1 ] = 0; - q_ptr = pulses; - i = silk_SMULBB( 7, silk_ADD_LSHIFT( quantOffsetType, signalType, 1 ) ); - icdf_ptr = &silk_sign_iCDF[ i ]; - length = silk_RSHIFT( length + SHELL_CODEC_FRAME_LENGTH/2, LOG2_SHELL_CODEC_FRAME_LENGTH ); - for( i = 0; i < length; i++ ) { - p = sum_pulses[ i ]; - if( p > 0 ) { - icdf[ 0 ] = icdf_ptr[ silk_min( p & 0x1F, 6 ) ]; - for( j = 0; j < SHELL_CODEC_FRAME_LENGTH; j++ ) { - if( q_ptr[ j ] != 0 ) { - ec_enc_icdf( psRangeEnc, silk_enc_map( q_ptr[ j ]), icdf, 8 ); - } - } - } - q_ptr += SHELL_CODEC_FRAME_LENGTH; - } -} - -/* Decodes signs of excitation */ -void silk_decode_signs( - ec_dec *psRangeDec, /* I/O Compressor data structure */ - opus_int pulses[], /* I/O pulse signal */ - opus_int length, /* I length of input */ - const opus_int signalType, /* I Signal type */ - const opus_int quantOffsetType, /* I Quantization offset type */ - const opus_int sum_pulses[ MAX_NB_SHELL_BLOCKS ] /* I Sum of absolute pulses per block */ -) -{ - opus_int i, j, p; - opus_uint8 icdf[ 2 ]; - opus_int *q_ptr; - const opus_uint8 *icdf_ptr; - - icdf[ 1 ] = 0; - q_ptr = pulses; - i = silk_SMULBB( 7, silk_ADD_LSHIFT( quantOffsetType, signalType, 1 ) ); - icdf_ptr = &silk_sign_iCDF[ i ]; - length = silk_RSHIFT( length + SHELL_CODEC_FRAME_LENGTH/2, LOG2_SHELL_CODEC_FRAME_LENGTH ); - for( i = 0; i < length; i++ ) { - p = sum_pulses[ i ]; - if( p > 0 ) { - icdf[ 0 ] = icdf_ptr[ silk_min( p & 0x1F, 6 ) ]; - for( j = 0; j < SHELL_CODEC_FRAME_LENGTH; j++ ) { - if( q_ptr[ j ] > 0 ) { - /* attach sign */ -#if 0 - /* conditional implementation */ - if( ec_dec_icdf( psRangeDec, icdf, 8 ) == 0 ) { - q_ptr[ j ] = -q_ptr[ j ]; - } -#else - /* implementation with shift, subtraction, multiplication */ - q_ptr[ j ] *= silk_dec_map( ec_dec_icdf( psRangeDec, icdf, 8 ) ); -#endif - } - } - } - q_ptr += SHELL_CODEC_FRAME_LENGTH; - } -} diff --git a/src/opus-1.0.2/silk/control.h b/src/opus-1.0.2/silk/control.h deleted file mode 100644 index c52ec3fe..00000000 --- a/src/opus-1.0.2/silk/control.h +++ /dev/null @@ -1,139 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifndef SILK_CONTROL_H -#define SILK_CONTROL_H - -#include "typedef.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -/* Decoder API flags */ -#define FLAG_DECODE_NORMAL 0 -#define FLAG_PACKET_LOST 1 -#define FLAG_DECODE_LBRR 2 - -/***********************************************/ -/* Structure for controlling encoder operation */ -/***********************************************/ -typedef struct { - /* I: Number of channels; 1/2 */ - opus_int32 nChannelsAPI; - - /* I: Number of channels; 1/2 */ - opus_int32 nChannelsInternal; - - /* I: Input signal sampling rate in Hertz; 8000/12000/16000/24000/32000/44100/48000 */ - opus_int32 API_sampleRate; - - /* I: Maximum internal sampling rate in Hertz; 8000/12000/16000 */ - opus_int32 maxInternalSampleRate; - - /* I: Minimum internal sampling rate in Hertz; 8000/12000/16000 */ - opus_int32 minInternalSampleRate; - - /* I: Soft request for internal sampling rate in Hertz; 8000/12000/16000 */ - opus_int32 desiredInternalSampleRate; - - /* I: Number of samples per packet in milliseconds; 10/20/40/60 */ - opus_int payloadSize_ms; - - /* I: Bitrate during active speech in bits/second; internally limited */ - opus_int32 bitRate; - - /* I: Uplink packet loss in percent (0-100) */ - opus_int packetLossPercentage; - - /* I: Complexity mode; 0 is lowest, 10 is highest complexity */ - opus_int complexity; - - /* I: Flag to enable in-band Forward Error Correction (FEC); 0/1 */ - opus_int useInBandFEC; - - /* I: Flag to enable discontinuous transmission (DTX); 0/1 */ - opus_int useDTX; - - /* I: Flag to use constant bitrate */ - opus_int useCBR; - - /* I: Maximum number of bits allowed for the frame */ - opus_int maxBits; - - /* I: Causes a smooth downmix to mono */ - opus_int toMono; - - /* I: Opus encoder is allowing us to switch bandwidth */ - opus_int opusCanSwitch; - - /* O: Internal sampling rate used, in Hertz; 8000/12000/16000 */ - opus_int32 internalSampleRate; - - /* O: Flag that bandwidth switching is allowed (because low voice activity) */ - opus_int allowBandwidthSwitch; - - /* O: Flag that SILK runs in WB mode without variable LP filter (use for switching between WB/SWB/FB) */ - opus_int inWBmodeWithoutVariableLP; - - /* O: Stereo width */ - opus_int stereoWidth_Q14; - - /* O: Tells the Opus encoder we're ready to switch */ - opus_int switchReady; - -} silk_EncControlStruct; - -/**************************************************************************/ -/* Structure for controlling decoder operation and reading decoder status */ -/**************************************************************************/ -typedef struct { - /* I: Number of channels; 1/2 */ - opus_int32 nChannelsAPI; - - /* I: Number of channels; 1/2 */ - opus_int32 nChannelsInternal; - - /* I: Output signal sampling rate in Hertz; 8000/12000/16000/24000/32000/44100/48000 */ - opus_int32 API_sampleRate; - - /* I: Internal sampling rate used, in Hertz; 8000/12000/16000 */ - opus_int32 internalSampleRate; - - /* I: Number of samples per packet in milliseconds; 10/20/40/60 */ - opus_int payloadSize_ms; - - /* O: Pitch lag of previous frame (0 if unvoiced), measured in samples at 48 kHz */ - opus_int prevPitchLag; -} silk_DecControlStruct; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/opus-1.0.2/silk/control_SNR.c b/src/opus-1.0.2/silk/control_SNR.c deleted file mode 100644 index 08e4e1a1..00000000 --- a/src/opus-1.0.2/silk/control_SNR.c +++ /dev/null @@ -1,81 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main.h" -#include "tuning_parameters.h" - -/* Control SNR of redidual quantizer */ -opus_int silk_control_SNR( - silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */ - opus_int32 TargetRate_bps /* I Target max bitrate (bps) */ -) -{ - opus_int k, ret = SILK_NO_ERROR; - opus_int32 frac_Q6; - const opus_int32 *rateTable; - - /* Set bitrate/coding quality */ - TargetRate_bps = silk_LIMIT( TargetRate_bps, MIN_TARGET_RATE_BPS, MAX_TARGET_RATE_BPS ); - if( TargetRate_bps != psEncC->TargetRate_bps ) { - psEncC->TargetRate_bps = TargetRate_bps; - - /* If new TargetRate_bps, translate to SNR_dB value */ - if( psEncC->fs_kHz == 8 ) { - rateTable = silk_TargetRate_table_NB; - } else if( psEncC->fs_kHz == 12 ) { - rateTable = silk_TargetRate_table_MB; - } else { - rateTable = silk_TargetRate_table_WB; - } - - /* Reduce bitrate for 10 ms modes in these calculations */ - if( psEncC->nb_subfr == 2 ) { - TargetRate_bps -= REDUCE_BITRATE_10_MS_BPS; - } - - /* Find bitrate interval in table and interpolate */ - for( k = 1; k < TARGET_RATE_TAB_SZ; k++ ) { - if( TargetRate_bps <= rateTable[ k ] ) { - frac_Q6 = silk_DIV32( silk_LSHIFT( TargetRate_bps - rateTable[ k - 1 ], 6 ), - rateTable[ k ] - rateTable[ k - 1 ] ); - psEncC->SNR_dB_Q7 = silk_LSHIFT( silk_SNR_table_Q1[ k - 1 ], 6 ) + silk_MUL( frac_Q6, silk_SNR_table_Q1[ k ] - silk_SNR_table_Q1[ k - 1 ] ); - break; - } - } - - /* Reduce coding quality whenever LBRR is enabled, to free up some bits */ - if( psEncC->LBRR_enabled ) { - psEncC->SNR_dB_Q7 = silk_SMLABB( psEncC->SNR_dB_Q7, 12 - psEncC->LBRR_GainIncreases, SILK_FIX_CONST( -0.25, 7 ) ); - } - } - - return ret; -} diff --git a/src/opus-1.0.2/silk/control_audio_bandwidth.c b/src/opus-1.0.2/silk/control_audio_bandwidth.c deleted file mode 100644 index b645dd57..00000000 --- a/src/opus-1.0.2/silk/control_audio_bandwidth.c +++ /dev/null @@ -1,123 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main.h" -#include "tuning_parameters.h" - -/* Control internal sampling rate */ -opus_int silk_control_audio_bandwidth( - silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */ - silk_EncControlStruct *encControl /* I Control structure */ -) -{ - opus_int fs_kHz; - opus_int32 fs_Hz; - - fs_kHz = psEncC->fs_kHz; - fs_Hz = silk_SMULBB( fs_kHz, 1000 ); - if( fs_Hz == 0 ) { - /* Encoder has just been initialized */ - fs_Hz = silk_min( psEncC->desiredInternal_fs_Hz, psEncC->API_fs_Hz ); - fs_kHz = silk_DIV32_16( fs_Hz, 1000 ); - } else if( fs_Hz > psEncC->API_fs_Hz || fs_Hz > psEncC->maxInternal_fs_Hz || fs_Hz < psEncC->minInternal_fs_Hz ) { - /* Make sure internal rate is not higher than external rate or maximum allowed, or lower than minimum allowed */ - fs_Hz = psEncC->API_fs_Hz; - fs_Hz = silk_min( fs_Hz, psEncC->maxInternal_fs_Hz ); - fs_Hz = silk_max( fs_Hz, psEncC->minInternal_fs_Hz ); - fs_kHz = silk_DIV32_16( fs_Hz, 1000 ); - } else { - /* State machine for the internal sampling rate switching */ - if( psEncC->sLP.transition_frame_no >= TRANSITION_FRAMES ) { - /* Stop transition phase */ - psEncC->sLP.mode = 0; - } - if( psEncC->allow_bandwidth_switch || encControl->opusCanSwitch ) { - /* Check if we should switch down */ - if( silk_SMULBB( psEncC->fs_kHz, 1000 ) > psEncC->desiredInternal_fs_Hz ) - { - /* Switch down */ - if( psEncC->sLP.mode == 0 ) { - /* New transition */ - psEncC->sLP.transition_frame_no = TRANSITION_FRAMES; - - /* Reset transition filter state */ - silk_memset( psEncC->sLP.In_LP_State, 0, sizeof( psEncC->sLP.In_LP_State ) ); - } - if( encControl->opusCanSwitch ) { - /* Stop transition phase */ - psEncC->sLP.mode = 0; - - /* Switch to a lower sample frequency */ - fs_kHz = psEncC->fs_kHz == 16 ? 12 : 8; - } else { - if( psEncC->sLP.transition_frame_no <= 0 ) { - encControl->switchReady = 1; - /* Make room for redundancy */ - encControl->maxBits -= encControl->maxBits * 5 / ( encControl->payloadSize_ms + 5 ); - } else { - /* Direction: down (at double speed) */ - psEncC->sLP.mode = -2; - } - } - } - else - /* Check if we should switch up */ - if( silk_SMULBB( psEncC->fs_kHz, 1000 ) < psEncC->desiredInternal_fs_Hz ) - { - /* Switch up */ - if( encControl->opusCanSwitch ) { - /* Switch to a higher sample frequency */ - fs_kHz = psEncC->fs_kHz == 8 ? 12 : 16; - - /* New transition */ - psEncC->sLP.transition_frame_no = 0; - - /* Reset transition filter state */ - silk_memset( psEncC->sLP.In_LP_State, 0, sizeof( psEncC->sLP.In_LP_State ) ); - - /* Direction: up */ - psEncC->sLP.mode = 1; - } else { - if( psEncC->sLP.mode == 0 ) { - encControl->switchReady = 1; - /* Make room for redundancy */ - encControl->maxBits -= encControl->maxBits * 5 / ( encControl->payloadSize_ms + 5 ); - } else { - /* Direction: up */ - psEncC->sLP.mode = 1; - } - } - } - } - } - - return fs_kHz; -} diff --git a/src/opus-1.0.2/silk/control_codec.c b/src/opus-1.0.2/silk/control_codec.c deleted file mode 100644 index ecc338ce..00000000 --- a/src/opus-1.0.2/silk/control_codec.c +++ /dev/null @@ -1,411 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#ifdef FIXED_POINT -#include "main_FIX.h" -#define silk_encoder_state_Fxx silk_encoder_state_FIX -#else -#include "main_FLP.h" -#define silk_encoder_state_Fxx silk_encoder_state_FLP -#endif -#include "tuning_parameters.h" -#include "pitch_est_defines.h" - -static opus_int silk_setup_resamplers( - silk_encoder_state_Fxx *psEnc, /* I/O */ - opus_int fs_kHz /* I */ -); - -static opus_int silk_setup_fs( - silk_encoder_state_Fxx *psEnc, /* I/O */ - opus_int fs_kHz, /* I */ - opus_int PacketSize_ms /* I */ -); - -static opus_int silk_setup_complexity( - silk_encoder_state *psEncC, /* I/O */ - opus_int Complexity /* I */ -); - -static inline opus_int silk_setup_LBRR( - silk_encoder_state *psEncC, /* I/O */ - const opus_int32 TargetRate_bps /* I */ -); - - -/* Control encoder */ -opus_int silk_control_encoder( - silk_encoder_state_Fxx *psEnc, /* I/O Pointer to Silk encoder state */ - silk_EncControlStruct *encControl, /* I Control structure */ - const opus_int32 TargetRate_bps, /* I Target max bitrate (bps) */ - const opus_int allow_bw_switch, /* I Flag to allow switching audio bandwidth */ - const opus_int channelNb, /* I Channel number */ - const opus_int force_fs_kHz -) -{ - opus_int fs_kHz, ret = 0; - - psEnc->sCmn.useDTX = encControl->useDTX; - psEnc->sCmn.useCBR = encControl->useCBR; - psEnc->sCmn.API_fs_Hz = encControl->API_sampleRate; - psEnc->sCmn.maxInternal_fs_Hz = encControl->maxInternalSampleRate; - psEnc->sCmn.minInternal_fs_Hz = encControl->minInternalSampleRate; - psEnc->sCmn.desiredInternal_fs_Hz = encControl->desiredInternalSampleRate; - psEnc->sCmn.useInBandFEC = encControl->useInBandFEC; - psEnc->sCmn.nChannelsAPI = encControl->nChannelsAPI; - psEnc->sCmn.nChannelsInternal = encControl->nChannelsInternal; - psEnc->sCmn.allow_bandwidth_switch = allow_bw_switch; - psEnc->sCmn.channelNb = channelNb; - - if( psEnc->sCmn.controlled_since_last_payload != 0 && psEnc->sCmn.prefillFlag == 0 ) { - if( psEnc->sCmn.API_fs_Hz != psEnc->sCmn.prev_API_fs_Hz && psEnc->sCmn.fs_kHz > 0 ) { - /* Change in API sampling rate in the middle of encoding a packet */ - ret += silk_setup_resamplers( psEnc, psEnc->sCmn.fs_kHz ); - } - return ret; - } - - /* Beyond this point we know that there are no previously coded frames in the payload buffer */ - - /********************************************/ - /* Determine internal sampling rate */ - /********************************************/ - fs_kHz = silk_control_audio_bandwidth( &psEnc->sCmn, encControl ); - if( force_fs_kHz ) { - fs_kHz = force_fs_kHz; - } - /********************************************/ - /* Prepare resampler and buffered data */ - /********************************************/ - ret += silk_setup_resamplers( psEnc, fs_kHz ); - - /********************************************/ - /* Set internal sampling frequency */ - /********************************************/ - ret += silk_setup_fs( psEnc, fs_kHz, encControl->payloadSize_ms ); - - /********************************************/ - /* Set encoding complexity */ - /********************************************/ - ret += silk_setup_complexity( &psEnc->sCmn, encControl->complexity ); - - /********************************************/ - /* Set packet loss rate measured by farend */ - /********************************************/ - psEnc->sCmn.PacketLoss_perc = encControl->packetLossPercentage; - - /********************************************/ - /* Set LBRR usage */ - /********************************************/ - ret += silk_setup_LBRR( &psEnc->sCmn, TargetRate_bps ); - - psEnc->sCmn.controlled_since_last_payload = 1; - - return ret; -} - -static opus_int silk_setup_resamplers( - silk_encoder_state_Fxx *psEnc, /* I/O */ - opus_int fs_kHz /* I */ -) -{ - opus_int ret = SILK_NO_ERROR; - opus_int32 nSamples_temp; - - if( psEnc->sCmn.fs_kHz != fs_kHz || psEnc->sCmn.prev_API_fs_Hz != psEnc->sCmn.API_fs_Hz ) - { - if( psEnc->sCmn.fs_kHz == 0 ) { - /* Initialize the resampler for enc_API.c preparing resampling from API_fs_Hz to fs_kHz */ - ret += silk_resampler_init( &psEnc->sCmn.resampler_state, psEnc->sCmn.API_fs_Hz, fs_kHz * 1000, 1 ); - } else { - /* Allocate worst case space for temporary upsampling, 8 to 48 kHz, so a factor 6 */ - opus_int16 x_buf_API_fs_Hz[ ( 2 * MAX_FRAME_LENGTH_MS + LA_SHAPE_MS ) * MAX_API_FS_KHZ ]; - silk_resampler_state_struct temp_resampler_state; -#ifdef FIXED_POINT - opus_int16 *x_bufFIX = psEnc->x_buf; -#else - opus_int16 x_bufFIX[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ]; -#endif - - nSamples_temp = silk_LSHIFT( psEnc->sCmn.frame_length, 1 ) + LA_SHAPE_MS * psEnc->sCmn.fs_kHz; - -#ifndef FIXED_POINT - silk_float2short_array( x_bufFIX, psEnc->x_buf, nSamples_temp ); -#endif - - /* Initialize resampler for temporary resampling of x_buf data to API_fs_Hz */ - ret += silk_resampler_init( &temp_resampler_state, silk_SMULBB( psEnc->sCmn.fs_kHz, 1000 ), psEnc->sCmn.API_fs_Hz, 0 ); - - /* Temporary resampling of x_buf data to API_fs_Hz */ - ret += silk_resampler( &temp_resampler_state, x_buf_API_fs_Hz, x_bufFIX, nSamples_temp ); - - /* Calculate number of samples that has been temporarily upsampled */ - nSamples_temp = silk_DIV32_16( nSamples_temp * psEnc->sCmn.API_fs_Hz, silk_SMULBB( psEnc->sCmn.fs_kHz, 1000 ) ); - - /* Initialize the resampler for enc_API.c preparing resampling from API_fs_Hz to fs_kHz */ - ret += silk_resampler_init( &psEnc->sCmn.resampler_state, psEnc->sCmn.API_fs_Hz, silk_SMULBB( fs_kHz, 1000 ), 1 ); - - /* Correct resampler state by resampling buffered data from API_fs_Hz to fs_kHz */ - ret += silk_resampler( &psEnc->sCmn.resampler_state, x_bufFIX, x_buf_API_fs_Hz, nSamples_temp ); - -#ifndef FIXED_POINT - silk_short2float_array( psEnc->x_buf, x_bufFIX, ( 2 * MAX_FRAME_LENGTH_MS + LA_SHAPE_MS ) * fs_kHz ); -#endif - } - } - - psEnc->sCmn.prev_API_fs_Hz = psEnc->sCmn.API_fs_Hz; - - return ret; -} - -static opus_int silk_setup_fs( - silk_encoder_state_Fxx *psEnc, /* I/O */ - opus_int fs_kHz, /* I */ - opus_int PacketSize_ms /* I */ -) -{ - opus_int ret = SILK_NO_ERROR; - - /* Set packet size */ - if( PacketSize_ms != psEnc->sCmn.PacketSize_ms ) { - if( ( PacketSize_ms != 10 ) && - ( PacketSize_ms != 20 ) && - ( PacketSize_ms != 40 ) && - ( PacketSize_ms != 60 ) ) { - ret = SILK_ENC_PACKET_SIZE_NOT_SUPPORTED; - } - if( PacketSize_ms <= 10 ) { - psEnc->sCmn.nFramesPerPacket = 1; - psEnc->sCmn.nb_subfr = PacketSize_ms == 10 ? 2 : 1; - psEnc->sCmn.frame_length = silk_SMULBB( PacketSize_ms, fs_kHz ); - psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS_2_SF, fs_kHz ); - if( psEnc->sCmn.fs_kHz == 8 ) { - psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_10_ms_NB_iCDF; - } else { - psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_10_ms_iCDF; - } - } else { - psEnc->sCmn.nFramesPerPacket = silk_DIV32_16( PacketSize_ms, MAX_FRAME_LENGTH_MS ); - psEnc->sCmn.nb_subfr = MAX_NB_SUBFR; - psEnc->sCmn.frame_length = silk_SMULBB( 20, fs_kHz ); - psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS, fs_kHz ); - if( psEnc->sCmn.fs_kHz == 8 ) { - psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_NB_iCDF; - } else { - psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_iCDF; - } - } - psEnc->sCmn.PacketSize_ms = PacketSize_ms; - psEnc->sCmn.TargetRate_bps = 0; /* trigger new SNR computation */ - } - - /* Set internal sampling frequency */ - silk_assert( fs_kHz == 8 || fs_kHz == 12 || fs_kHz == 16 ); - silk_assert( psEnc->sCmn.nb_subfr == 2 || psEnc->sCmn.nb_subfr == 4 ); - if( psEnc->sCmn.fs_kHz != fs_kHz ) { - /* reset part of the state */ - silk_memset( &psEnc->sShape, 0, sizeof( psEnc->sShape ) ); - silk_memset( &psEnc->sPrefilt, 0, sizeof( psEnc->sPrefilt ) ); - silk_memset( &psEnc->sCmn.sNSQ, 0, sizeof( psEnc->sCmn.sNSQ ) ); - silk_memset( psEnc->sCmn.prev_NLSFq_Q15, 0, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) ); - silk_memset( &psEnc->sCmn.sLP.In_LP_State, 0, sizeof( psEnc->sCmn.sLP.In_LP_State ) ); - psEnc->sCmn.inputBufIx = 0; - psEnc->sCmn.nFramesEncoded = 0; - psEnc->sCmn.TargetRate_bps = 0; /* trigger new SNR computation */ - - /* Initialize non-zero parameters */ - psEnc->sCmn.prevLag = 100; - psEnc->sCmn.first_frame_after_reset = 1; - psEnc->sPrefilt.lagPrev = 100; - psEnc->sShape.LastGainIndex = 10; - psEnc->sCmn.sNSQ.lagPrev = 100; - psEnc->sCmn.sNSQ.prev_gain_Q16 = 65536; - psEnc->sCmn.prevSignalType = TYPE_NO_VOICE_ACTIVITY; - - psEnc->sCmn.fs_kHz = fs_kHz; - if( psEnc->sCmn.fs_kHz == 8 ) { - if( psEnc->sCmn.nb_subfr == MAX_NB_SUBFR ) { - psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_NB_iCDF; - } else { - psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_10_ms_NB_iCDF; - } - } else { - if( psEnc->sCmn.nb_subfr == MAX_NB_SUBFR ) { - psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_iCDF; - } else { - psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_10_ms_iCDF; - } - } - if( psEnc->sCmn.fs_kHz == 8 || psEnc->sCmn.fs_kHz == 12 ) { - psEnc->sCmn.predictLPCOrder = MIN_LPC_ORDER; - psEnc->sCmn.psNLSF_CB = &silk_NLSF_CB_NB_MB; - } else { - psEnc->sCmn.predictLPCOrder = MAX_LPC_ORDER; - psEnc->sCmn.psNLSF_CB = &silk_NLSF_CB_WB; - } - psEnc->sCmn.subfr_length = SUB_FRAME_LENGTH_MS * fs_kHz; - psEnc->sCmn.frame_length = silk_SMULBB( psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr ); - psEnc->sCmn.ltp_mem_length = silk_SMULBB( LTP_MEM_LENGTH_MS, fs_kHz ); - psEnc->sCmn.la_pitch = silk_SMULBB( LA_PITCH_MS, fs_kHz ); - psEnc->sCmn.max_pitch_lag = silk_SMULBB( 18, fs_kHz ); - if( psEnc->sCmn.nb_subfr == MAX_NB_SUBFR ) { - psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS, fs_kHz ); - } else { - psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS_2_SF, fs_kHz ); - } - if( psEnc->sCmn.fs_kHz == 16 ) { - psEnc->sCmn.mu_LTP_Q9 = SILK_FIX_CONST( MU_LTP_QUANT_WB, 9 ); - psEnc->sCmn.pitch_lag_low_bits_iCDF = silk_uniform8_iCDF; - } else if( psEnc->sCmn.fs_kHz == 12 ) { - psEnc->sCmn.mu_LTP_Q9 = SILK_FIX_CONST( MU_LTP_QUANT_MB, 9 ); - psEnc->sCmn.pitch_lag_low_bits_iCDF = silk_uniform6_iCDF; - } else { - psEnc->sCmn.mu_LTP_Q9 = SILK_FIX_CONST( MU_LTP_QUANT_NB, 9 ); - psEnc->sCmn.pitch_lag_low_bits_iCDF = silk_uniform4_iCDF; - } - } - - /* Check that settings are valid */ - silk_assert( ( psEnc->sCmn.subfr_length * psEnc->sCmn.nb_subfr ) == psEnc->sCmn.frame_length ); - - return ret; -} - -static opus_int silk_setup_complexity( - silk_encoder_state *psEncC, /* I/O */ - opus_int Complexity /* I */ -) -{ - opus_int ret = 0; - - /* Set encoding complexity */ - silk_assert( Complexity >= 0 && Complexity <= 10 ); - if( Complexity < 2 ) { - psEncC->pitchEstimationComplexity = SILK_PE_MIN_COMPLEX; - psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.8, 16 ); - psEncC->pitchEstimationLPCOrder = 6; - psEncC->shapingLPCOrder = 8; - psEncC->la_shape = 3 * psEncC->fs_kHz; - psEncC->nStatesDelayedDecision = 1; - psEncC->useInterpolatedNLSFs = 0; - psEncC->LTPQuantLowComplexity = 1; - psEncC->NLSF_MSVQ_Survivors = 2; - psEncC->warping_Q16 = 0; - } else if( Complexity < 4 ) { - psEncC->pitchEstimationComplexity = SILK_PE_MID_COMPLEX; - psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.76, 16 ); - psEncC->pitchEstimationLPCOrder = 8; - psEncC->shapingLPCOrder = 10; - psEncC->la_shape = 5 * psEncC->fs_kHz; - psEncC->nStatesDelayedDecision = 1; - psEncC->useInterpolatedNLSFs = 0; - psEncC->LTPQuantLowComplexity = 0; - psEncC->NLSF_MSVQ_Survivors = 4; - psEncC->warping_Q16 = 0; - } else if( Complexity < 6 ) { - psEncC->pitchEstimationComplexity = SILK_PE_MID_COMPLEX; - psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.74, 16 ); - psEncC->pitchEstimationLPCOrder = 10; - psEncC->shapingLPCOrder = 12; - psEncC->la_shape = 5 * psEncC->fs_kHz; - psEncC->nStatesDelayedDecision = 2; - psEncC->useInterpolatedNLSFs = 1; - psEncC->LTPQuantLowComplexity = 0; - psEncC->NLSF_MSVQ_Survivors = 8; - psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 ); - } else if( Complexity < 8 ) { - psEncC->pitchEstimationComplexity = SILK_PE_MID_COMPLEX; - psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.72, 16 ); - psEncC->pitchEstimationLPCOrder = 12; - psEncC->shapingLPCOrder = 14; - psEncC->la_shape = 5 * psEncC->fs_kHz; - psEncC->nStatesDelayedDecision = 3; - psEncC->useInterpolatedNLSFs = 1; - psEncC->LTPQuantLowComplexity = 0; - psEncC->NLSF_MSVQ_Survivors = 16; - psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 ); - } else { - psEncC->pitchEstimationComplexity = SILK_PE_MAX_COMPLEX; - psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.7, 16 ); - psEncC->pitchEstimationLPCOrder = 16; - psEncC->shapingLPCOrder = 16; - psEncC->la_shape = 5 * psEncC->fs_kHz; - psEncC->nStatesDelayedDecision = MAX_DEL_DEC_STATES; - psEncC->useInterpolatedNLSFs = 1; - psEncC->LTPQuantLowComplexity = 0; - psEncC->NLSF_MSVQ_Survivors = 32; - psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 ); - } - - /* Do not allow higher pitch estimation LPC order than predict LPC order */ - psEncC->pitchEstimationLPCOrder = silk_min_int( psEncC->pitchEstimationLPCOrder, psEncC->predictLPCOrder ); - psEncC->shapeWinLength = SUB_FRAME_LENGTH_MS * psEncC->fs_kHz + 2 * psEncC->la_shape; - psEncC->Complexity = Complexity; - - silk_assert( psEncC->pitchEstimationLPCOrder <= MAX_FIND_PITCH_LPC_ORDER ); - silk_assert( psEncC->shapingLPCOrder <= MAX_SHAPE_LPC_ORDER ); - silk_assert( psEncC->nStatesDelayedDecision <= MAX_DEL_DEC_STATES ); - silk_assert( psEncC->warping_Q16 <= 32767 ); - silk_assert( psEncC->la_shape <= LA_SHAPE_MAX ); - silk_assert( psEncC->shapeWinLength <= SHAPE_LPC_WIN_MAX ); - silk_assert( psEncC->NLSF_MSVQ_Survivors <= NLSF_VQ_MAX_SURVIVORS ); - - return ret; -} - -static inline opus_int silk_setup_LBRR( - silk_encoder_state *psEncC, /* I/O */ - const opus_int32 TargetRate_bps /* I */ -) -{ - opus_int ret = SILK_NO_ERROR; - opus_int32 LBRR_rate_thres_bps; - - psEncC->LBRR_enabled = 0; - if( psEncC->useInBandFEC && psEncC->PacketLoss_perc > 0 ) { - if( psEncC->fs_kHz == 8 ) { - LBRR_rate_thres_bps = LBRR_NB_MIN_RATE_BPS; - } else if( psEncC->fs_kHz == 12 ) { - LBRR_rate_thres_bps = LBRR_MB_MIN_RATE_BPS; - } else { - LBRR_rate_thres_bps = LBRR_WB_MIN_RATE_BPS; - } - LBRR_rate_thres_bps = silk_SMULWB( silk_MUL( LBRR_rate_thres_bps, 125 - silk_min( psEncC->PacketLoss_perc, 25 ) ), SILK_FIX_CONST( 0.01, 16 ) ); - - if( TargetRate_bps > LBRR_rate_thres_bps ) { - /* Set gain increase for coding LBRR excitation */ - psEncC->LBRR_enabled = 1; - psEncC->LBRR_GainIncreases = silk_max_int( 7 - silk_SMULWB( (opus_int32)psEncC->PacketLoss_perc, SILK_FIX_CONST( 0.4, 16 ) ), 2 ); - } - } - - return ret; -} diff --git a/src/opus-1.0.2/silk/debug.c b/src/opus-1.0.2/silk/debug.c deleted file mode 100644 index 9aa16cc8..00000000 --- a/src/opus-1.0.2/silk/debug.c +++ /dev/null @@ -1,170 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "debug.h" -#include "SigProc_FIX.h" - -#if SILK_TIC_TOC - -#ifdef _WIN32 - -#if (defined(_WIN32) || defined(_WINCE)) -#include /* timer */ -#else /* Linux or Mac*/ -#include -#endif - -unsigned long silk_GetHighResolutionTime(void) /* O time in usec*/ -{ - /* Returns a time counter in microsec */ - /* the resolution is platform dependent */ - /* but is typically 1.62 us resolution */ - LARGE_INTEGER lpPerformanceCount; - LARGE_INTEGER lpFrequency; - QueryPerformanceCounter(&lpPerformanceCount); - QueryPerformanceFrequency(&lpFrequency); - return (unsigned long)((1000000*(lpPerformanceCount.QuadPart)) / lpFrequency.QuadPart); -} -#else /* Linux or Mac*/ -unsigned long GetHighResolutionTime(void) /* O time in usec*/ -{ - struct timeval tv; - gettimeofday(&tv, 0); - return((tv.tv_sec*1000000)+(tv.tv_usec)); -} -#endif - -int silk_Timer_nTimers = 0; -int silk_Timer_depth_ctr = 0; -char silk_Timer_tags[silk_NUM_TIMERS_MAX][silk_NUM_TIMERS_MAX_TAG_LEN]; -#ifdef WIN32 -LARGE_INTEGER silk_Timer_start[silk_NUM_TIMERS_MAX]; -#else -unsigned long silk_Timer_start[silk_NUM_TIMERS_MAX]; -#endif -unsigned int silk_Timer_cnt[silk_NUM_TIMERS_MAX]; -opus_int64 silk_Timer_min[silk_NUM_TIMERS_MAX]; -opus_int64 silk_Timer_sum[silk_NUM_TIMERS_MAX]; -opus_int64 silk_Timer_max[silk_NUM_TIMERS_MAX]; -opus_int64 silk_Timer_depth[silk_NUM_TIMERS_MAX]; - -#ifdef WIN32 -void silk_TimerSave(char *file_name) -{ - if( silk_Timer_nTimers > 0 ) - { - int k; - FILE *fp; - LARGE_INTEGER lpFrequency; - LARGE_INTEGER lpPerformanceCount1, lpPerformanceCount2; - int del = 0x7FFFFFFF; - double avg, sum_avg; - /* estimate overhead of calling performance counters */ - for( k = 0; k < 1000; k++ ) { - QueryPerformanceCounter(&lpPerformanceCount1); - QueryPerformanceCounter(&lpPerformanceCount2); - lpPerformanceCount2.QuadPart -= lpPerformanceCount1.QuadPart; - if( (int)lpPerformanceCount2.LowPart < del ) - del = lpPerformanceCount2.LowPart; - } - QueryPerformanceFrequency(&lpFrequency); - /* print results to file */ - sum_avg = 0.0f; - for( k = 0; k < silk_Timer_nTimers; k++ ) { - if (silk_Timer_depth[k] == 0) { - sum_avg += (1e6 * silk_Timer_sum[k] / silk_Timer_cnt[k] - del) / lpFrequency.QuadPart * silk_Timer_cnt[k]; - } - } - fp = fopen(file_name, "w"); - fprintf(fp, " min avg %% max count\n"); - for( k = 0; k < silk_Timer_nTimers; k++ ) { - if (silk_Timer_depth[k] == 0) { - fprintf(fp, "%-28s", silk_Timer_tags[k]); - } else if (silk_Timer_depth[k] == 1) { - fprintf(fp, " %-27s", silk_Timer_tags[k]); - } else if (silk_Timer_depth[k] == 2) { - fprintf(fp, " %-26s", silk_Timer_tags[k]); - } else if (silk_Timer_depth[k] == 3) { - fprintf(fp, " %-25s", silk_Timer_tags[k]); - } else { - fprintf(fp, " %-24s", silk_Timer_tags[k]); - } - avg = (1e6 * silk_Timer_sum[k] / silk_Timer_cnt[k] - del) / lpFrequency.QuadPart; - fprintf(fp, "%8.2f", (1e6 * (silk_max_64(silk_Timer_min[k] - del, 0))) / lpFrequency.QuadPart); - fprintf(fp, "%12.2f %6.2f", avg, 100.0 * avg / sum_avg * silk_Timer_cnt[k]); - fprintf(fp, "%12.2f", (1e6 * (silk_max_64(silk_Timer_max[k] - del, 0))) / lpFrequency.QuadPart); - fprintf(fp, "%10d\n", silk_Timer_cnt[k]); - } - fprintf(fp, " microseconds\n"); - fclose(fp); - } -} -#else -void silk_TimerSave(char *file_name) -{ - if( silk_Timer_nTimers > 0 ) - { - int k; - FILE *fp; - /* print results to file */ - fp = fopen(file_name, "w"); - fprintf(fp, " min avg max count\n"); - for( k = 0; k < silk_Timer_nTimers; k++ ) - { - if (silk_Timer_depth[k] == 0) { - fprintf(fp, "%-28s", silk_Timer_tags[k]); - } else if (silk_Timer_depth[k] == 1) { - fprintf(fp, " %-27s", silk_Timer_tags[k]); - } else if (silk_Timer_depth[k] == 2) { - fprintf(fp, " %-26s", silk_Timer_tags[k]); - } else if (silk_Timer_depth[k] == 3) { - fprintf(fp, " %-25s", silk_Timer_tags[k]); - } else { - fprintf(fp, " %-24s", silk_Timer_tags[k]); - } - fprintf(fp, "%d ", silk_Timer_min[k]); - fprintf(fp, "%f ", (double)silk_Timer_sum[k] / (double)silk_Timer_cnt[k]); - fprintf(fp, "%d ", silk_Timer_max[k]); - fprintf(fp, "%10d\n", silk_Timer_cnt[k]); - } - fprintf(fp, " microseconds\n"); - fclose(fp); - } -} -#endif - -#endif /* SILK_TIC_TOC */ - -#if SILK_DEBUG -FILE *silk_debug_store_fp[ silk_NUM_STORES_MAX ]; -int silk_debug_store_count = 0; -#endif /* SILK_DEBUG */ - diff --git a/src/opus-1.0.2/silk/debug.h b/src/opus-1.0.2/silk/debug.h deleted file mode 100644 index 8ae7094f..00000000 --- a/src/opus-1.0.2/silk/debug.h +++ /dev/null @@ -1,284 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifndef SILK_DEBUG_H -#define SILK_DEBUG_H - -#ifdef _WIN32 -#define _CRT_SECURE_NO_DEPRECATE 1 -#endif - -#include "typedef.h" -#include /* file writing */ -#include /* strcpy, strcmp */ - -#ifdef __cplusplus -extern "C" -{ -#endif - -unsigned long GetHighResolutionTime(void); /* O time in usec*/ - -/* make SILK_DEBUG dependent on compiler's _DEBUG */ -#if defined _WIN32 - #ifdef _DEBUG - #define SILK_DEBUG 1 - #else - #define SILK_DEBUG 0 - #endif - - /* overrule the above */ - #if 0 - /* #define NO_ASSERTS*/ - #undef SILK_DEBUG - #define SILK_DEBUG 1 - #endif -#else - #define SILK_DEBUG 0 -#endif - -/* Flag for using timers */ -#define SILK_TIC_TOC 0 - - -#if SILK_TIC_TOC - -#if (defined(_WIN32) || defined(_WINCE)) -#include /* timer */ -#pragma warning( disable : 4996 ) /* stop bitching about strcpy in TIC()*/ -#else /* Linux or Mac*/ -#include -#endif - -/*********************************/ -/* timer functions for profiling */ -/*********************************/ -/* example: */ -/* */ -/* TIC(LPC) */ -/* do_LPC(in_vec, order, acoef); // do LPC analysis */ -/* TOC(LPC) */ -/* */ -/* and call the following just before exiting (from main) */ -/* */ -/* silk_TimerSave("silk_TimingData.txt"); */ -/* */ -/* results are now in silk_TimingData.txt */ - -void silk_TimerSave(char *file_name); - -/* max number of timers (in different locations) */ -#define silk_NUM_TIMERS_MAX 50 -/* max length of name tags in TIC(..), TOC(..) */ -#define silk_NUM_TIMERS_MAX_TAG_LEN 30 - -extern int silk_Timer_nTimers; -extern int silk_Timer_depth_ctr; -extern char silk_Timer_tags[silk_NUM_TIMERS_MAX][silk_NUM_TIMERS_MAX_TAG_LEN]; -#ifdef _WIN32 -extern LARGE_INTEGER silk_Timer_start[silk_NUM_TIMERS_MAX]; -#else -extern unsigned long silk_Timer_start[silk_NUM_TIMERS_MAX]; -#endif -extern unsigned int silk_Timer_cnt[silk_NUM_TIMERS_MAX]; -extern opus_int64 silk_Timer_sum[silk_NUM_TIMERS_MAX]; -extern opus_int64 silk_Timer_max[silk_NUM_TIMERS_MAX]; -extern opus_int64 silk_Timer_min[silk_NUM_TIMERS_MAX]; -extern opus_int64 silk_Timer_depth[silk_NUM_TIMERS_MAX]; - -/* WARNING: TIC()/TOC can measure only up to 0.1 seconds at a time */ -#ifdef _WIN32 -#define TIC(TAG_NAME) { \ - static int init = 0; \ - static int ID = -1; \ - if( init == 0 ) \ - { \ - int k; \ - init = 1; \ - for( k = 0; k < silk_Timer_nTimers; k++ ) { \ - if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \ - ID = k; \ - break; \ - } \ - } \ - if (ID == -1) { \ - ID = silk_Timer_nTimers; \ - silk_Timer_nTimers++; \ - silk_Timer_depth[ID] = silk_Timer_depth_ctr; \ - strcpy(silk_Timer_tags[ID], #TAG_NAME); \ - silk_Timer_cnt[ID] = 0; \ - silk_Timer_sum[ID] = 0; \ - silk_Timer_min[ID] = 0xFFFFFFFF; \ - silk_Timer_max[ID] = 0; \ - } \ - } \ - silk_Timer_depth_ctr++; \ - QueryPerformanceCounter(&silk_Timer_start[ID]); \ -} -#else -#define TIC(TAG_NAME) { \ - static int init = 0; \ - static int ID = -1; \ - if( init == 0 ) \ - { \ - int k; \ - init = 1; \ - for( k = 0; k < silk_Timer_nTimers; k++ ) { \ - if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \ - ID = k; \ - break; \ - } \ - } \ - if (ID == -1) { \ - ID = silk_Timer_nTimers; \ - silk_Timer_nTimers++; \ - silk_Timer_depth[ID] = silk_Timer_depth_ctr; \ - strcpy(silk_Timer_tags[ID], #TAG_NAME); \ - silk_Timer_cnt[ID] = 0; \ - silk_Timer_sum[ID] = 0; \ - silk_Timer_min[ID] = 0xFFFFFFFF; \ - silk_Timer_max[ID] = 0; \ - } \ - } \ - silk_Timer_depth_ctr++; \ - silk_Timer_start[ID] = GetHighResolutionTime(); \ -} -#endif - -#ifdef _WIN32 -#define TOC(TAG_NAME) { \ - LARGE_INTEGER lpPerformanceCount; \ - static int init = 0; \ - static int ID = 0; \ - if( init == 0 ) \ - { \ - int k; \ - init = 1; \ - for( k = 0; k < silk_Timer_nTimers; k++ ) { \ - if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \ - ID = k; \ - break; \ - } \ - } \ - } \ - QueryPerformanceCounter(&lpPerformanceCount); \ - lpPerformanceCount.QuadPart -= silk_Timer_start[ID].QuadPart; \ - if((lpPerformanceCount.QuadPart < 100000000) && \ - (lpPerformanceCount.QuadPart >= 0)) { \ - silk_Timer_cnt[ID]++; \ - silk_Timer_sum[ID] += lpPerformanceCount.QuadPart; \ - if( lpPerformanceCount.QuadPart > silk_Timer_max[ID] ) \ - silk_Timer_max[ID] = lpPerformanceCount.QuadPart; \ - if( lpPerformanceCount.QuadPart < silk_Timer_min[ID] ) \ - silk_Timer_min[ID] = lpPerformanceCount.QuadPart; \ - } \ - silk_Timer_depth_ctr--; \ -} -#else -#define TOC(TAG_NAME) { \ - unsigned long endTime; \ - static int init = 0; \ - static int ID = 0; \ - if( init == 0 ) \ - { \ - int k; \ - init = 1; \ - for( k = 0; k < silk_Timer_nTimers; k++ ) { \ - if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \ - ID = k; \ - break; \ - } \ - } \ - } \ - endTime = GetHighResolutionTime(); \ - endTime -= silk_Timer_start[ID]; \ - if((endTime < 100000000) && \ - (endTime >= 0)) { \ - silk_Timer_cnt[ID]++; \ - silk_Timer_sum[ID] += endTime; \ - if( endTime > silk_Timer_max[ID] ) \ - silk_Timer_max[ID] = endTime; \ - if( endTime < silk_Timer_min[ID] ) \ - silk_Timer_min[ID] = endTime; \ - } \ - silk_Timer_depth_ctr--; \ -} -#endif - -#else /* SILK_TIC_TOC */ - -/* define macros as empty strings */ -#define TIC(TAG_NAME) -#define TOC(TAG_NAME) -#define silk_TimerSave(FILE_NAME) - -#endif /* SILK_TIC_TOC */ - - -#if SILK_DEBUG -/************************************/ -/* write data to file for debugging */ -/************************************/ -/* Example: DEBUG_STORE_DATA(testfile.pcm, &RIN[0], 160*sizeof(opus_int16)); */ - -#define silk_NUM_STORES_MAX 100 -extern FILE *silk_debug_store_fp[ silk_NUM_STORES_MAX ]; -extern int silk_debug_store_count; - -/* Faster way of storing the data */ -#define DEBUG_STORE_DATA( FILE_NAME, DATA_PTR, N_BYTES ) { \ - static opus_int init = 0, cnt = 0; \ - static FILE **fp; \ - if (init == 0) { \ - init = 1; \ - cnt = silk_debug_store_count++; \ - silk_debug_store_fp[ cnt ] = fopen(#FILE_NAME, "wb"); \ - } \ - fwrite((DATA_PTR), (N_BYTES), 1, silk_debug_store_fp[ cnt ]); \ -} - -/* Call this at the end of main() */ -#define SILK_DEBUG_STORE_CLOSE_FILES { \ - opus_int i; \ - for( i = 0; i < silk_debug_store_count; i++ ) { \ - fclose( silk_debug_store_fp[ i ] ); \ - } \ -} - -#else /* SILK_DEBUG */ - -/* define macros as empty strings */ -#define DEBUG_STORE_DATA(FILE_NAME, DATA_PTR, N_BYTES) -#define SILK_DEBUG_STORE_CLOSE_FILES - -#endif /* SILK_DEBUG */ - -#ifdef __cplusplus -} -#endif - -#endif /* SILK_DEBUG_H */ diff --git a/src/opus-1.0.2/silk/dec_API.c b/src/opus-1.0.2/silk/dec_API.c deleted file mode 100644 index 68403b7c..00000000 --- a/src/opus-1.0.2/silk/dec_API.c +++ /dev/null @@ -1,392 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include "API.h" -#include "main.h" -#include "stack_alloc.h" - -/************************/ -/* Decoder Super Struct */ -/************************/ -typedef struct { - silk_decoder_state channel_state[ DECODER_NUM_CHANNELS ]; - stereo_dec_state sStereo; - opus_int nChannelsAPI; - opus_int nChannelsInternal; - opus_int prev_decode_only_middle; -} silk_decoder; - -/*********************/ -/* Decoder functions */ -/*********************/ - -opus_int silk_Get_Decoder_Size( /* O Returns error code */ - opus_int *decSizeBytes /* O Number of bytes in SILK decoder state */ -) -{ - opus_int ret = SILK_NO_ERROR; - - *decSizeBytes = sizeof( silk_decoder ); - - return ret; -} - -/* Reset decoder state */ -opus_int silk_InitDecoder( /* O Returns error code */ - void *decState /* I/O State */ -) -{ - opus_int n, ret = SILK_NO_ERROR; - silk_decoder_state *channel_state = ((silk_decoder *)decState)->channel_state; - - for( n = 0; n < DECODER_NUM_CHANNELS; n++ ) { - ret = silk_init_decoder( &channel_state[ n ] ); - } - - return ret; -} - -/* Decode a frame */ -opus_int silk_Decode( /* O Returns error code */ - void* decState, /* I/O State */ - silk_DecControlStruct* decControl, /* I/O Control Structure */ - opus_int lostFlag, /* I 0: no loss, 1 loss, 2 decode fec */ - opus_int newPacketFlag, /* I Indicates first decoder call for this packet */ - ec_dec *psRangeDec, /* I/O Compressor data structure */ - opus_int16 *samplesOut, /* O Decoded output speech vector */ - opus_int32 *nSamplesOut /* O Number of samples decoded */ -) -{ - opus_int i, n, decode_only_middle = 0, ret = SILK_NO_ERROR; - opus_int32 nSamplesOutDec, LBRR_symbol; - opus_int16 *samplesOut1_tmp[ 2 ]; - VARDECL( opus_int16, samplesOut1_tmp_storage ); - VARDECL( opus_int16, samplesOut2_tmp ); - opus_int32 MS_pred_Q13[ 2 ] = { 0 }; - opus_int16 *resample_out_ptr; - silk_decoder *psDec = ( silk_decoder * )decState; - silk_decoder_state *channel_state = psDec->channel_state; - opus_int has_side; - opus_int stereo_to_mono; - SAVE_STACK; - - /**********************************/ - /* Test if first frame in payload */ - /**********************************/ - if( newPacketFlag ) { - for( n = 0; n < decControl->nChannelsInternal; n++ ) { - channel_state[ n ].nFramesDecoded = 0; /* Used to count frames in packet */ - } - } - - /* If Mono -> Stereo transition in bitstream: init state of second channel */ - if( decControl->nChannelsInternal > psDec->nChannelsInternal ) { - ret += silk_init_decoder( &channel_state[ 1 ] ); - } - - stereo_to_mono = decControl->nChannelsInternal == 1 && psDec->nChannelsInternal == 2 && - ( decControl->internalSampleRate == 1000*channel_state[ 0 ].fs_kHz ); - - if( channel_state[ 0 ].nFramesDecoded == 0 ) { - for( n = 0; n < decControl->nChannelsInternal; n++ ) { - opus_int fs_kHz_dec; - if( decControl->payloadSize_ms == 0 ) { - /* Assuming packet loss, use 10 ms */ - channel_state[ n ].nFramesPerPacket = 1; - channel_state[ n ].nb_subfr = 2; - } else if( decControl->payloadSize_ms == 10 ) { - channel_state[ n ].nFramesPerPacket = 1; - channel_state[ n ].nb_subfr = 2; - } else if( decControl->payloadSize_ms == 20 ) { - channel_state[ n ].nFramesPerPacket = 1; - channel_state[ n ].nb_subfr = 4; - } else if( decControl->payloadSize_ms == 40 ) { - channel_state[ n ].nFramesPerPacket = 2; - channel_state[ n ].nb_subfr = 4; - } else if( decControl->payloadSize_ms == 60 ) { - channel_state[ n ].nFramesPerPacket = 3; - channel_state[ n ].nb_subfr = 4; - } else { - silk_assert( 0 ); - RESTORE_STACK; - return SILK_DEC_INVALID_FRAME_SIZE; - } - fs_kHz_dec = ( decControl->internalSampleRate >> 10 ) + 1; - if( fs_kHz_dec != 8 && fs_kHz_dec != 12 && fs_kHz_dec != 16 ) { - silk_assert( 0 ); - RESTORE_STACK; - return SILK_DEC_INVALID_SAMPLING_FREQUENCY; - } - ret += silk_decoder_set_fs( &channel_state[ n ], fs_kHz_dec, decControl->API_sampleRate ); - } - } - - if( decControl->nChannelsAPI == 2 && decControl->nChannelsInternal == 2 && ( psDec->nChannelsAPI == 1 || psDec->nChannelsInternal == 1 ) ) { - silk_memset( psDec->sStereo.pred_prev_Q13, 0, sizeof( psDec->sStereo.pred_prev_Q13 ) ); - silk_memset( psDec->sStereo.sSide, 0, sizeof( psDec->sStereo.sSide ) ); - silk_memcpy( &channel_state[ 1 ].resampler_state, &channel_state[ 0 ].resampler_state, sizeof( silk_resampler_state_struct ) ); - } - psDec->nChannelsAPI = decControl->nChannelsAPI; - psDec->nChannelsInternal = decControl->nChannelsInternal; - - if( decControl->API_sampleRate > (opus_int32)MAX_API_FS_KHZ * 1000 || decControl->API_sampleRate < 8000 ) { - ret = SILK_DEC_INVALID_SAMPLING_FREQUENCY; - RESTORE_STACK; - return( ret ); - } - - if( lostFlag != FLAG_PACKET_LOST && channel_state[ 0 ].nFramesDecoded == 0 ) { - /* First decoder call for this payload */ - /* Decode VAD flags and LBRR flag */ - for( n = 0; n < decControl->nChannelsInternal; n++ ) { - for( i = 0; i < channel_state[ n ].nFramesPerPacket; i++ ) { - channel_state[ n ].VAD_flags[ i ] = ec_dec_bit_logp(psRangeDec, 1); - } - channel_state[ n ].LBRR_flag = ec_dec_bit_logp(psRangeDec, 1); - } - /* Decode LBRR flags */ - for( n = 0; n < decControl->nChannelsInternal; n++ ) { - silk_memset( channel_state[ n ].LBRR_flags, 0, sizeof( channel_state[ n ].LBRR_flags ) ); - if( channel_state[ n ].LBRR_flag ) { - if( channel_state[ n ].nFramesPerPacket == 1 ) { - channel_state[ n ].LBRR_flags[ 0 ] = 1; - } else { - LBRR_symbol = ec_dec_icdf( psRangeDec, silk_LBRR_flags_iCDF_ptr[ channel_state[ n ].nFramesPerPacket - 2 ], 8 ) + 1; - for( i = 0; i < channel_state[ n ].nFramesPerPacket; i++ ) { - channel_state[ n ].LBRR_flags[ i ] = silk_RSHIFT( LBRR_symbol, i ) & 1; - } - } - } - } - - if( lostFlag == FLAG_DECODE_NORMAL ) { - /* Regular decoding: skip all LBRR data */ - for( i = 0; i < channel_state[ 0 ].nFramesPerPacket; i++ ) { - for( n = 0; n < decControl->nChannelsInternal; n++ ) { - if( channel_state[ n ].LBRR_flags[ i ] ) { - opus_int pulses[ MAX_FRAME_LENGTH ]; - opus_int condCoding; - - if( decControl->nChannelsInternal == 2 && n == 0 ) { - silk_stereo_decode_pred( psRangeDec, MS_pred_Q13 ); - if( channel_state[ 1 ].LBRR_flags[ i ] == 0 ) { - silk_stereo_decode_mid_only( psRangeDec, &decode_only_middle ); - } - } - /* Use conditional coding if previous frame available */ - if( i > 0 && channel_state[ n ].LBRR_flags[ i - 1 ] ) { - condCoding = CODE_CONDITIONALLY; - } else { - condCoding = CODE_INDEPENDENTLY; - } - silk_decode_indices( &channel_state[ n ], psRangeDec, i, 1, condCoding ); - silk_decode_pulses( psRangeDec, pulses, channel_state[ n ].indices.signalType, - channel_state[ n ].indices.quantOffsetType, channel_state[ n ].frame_length ); - } - } - } - } - } - - /* Get MS predictor index */ - if( decControl->nChannelsInternal == 2 ) { - if( lostFlag == FLAG_DECODE_NORMAL || - ( lostFlag == FLAG_DECODE_LBRR && channel_state[ 0 ].LBRR_flags[ channel_state[ 0 ].nFramesDecoded ] == 1 ) ) - { - silk_stereo_decode_pred( psRangeDec, MS_pred_Q13 ); - /* For LBRR data, decode mid-only flag only if side-channel's LBRR flag is false */ - if( ( lostFlag == FLAG_DECODE_NORMAL && channel_state[ 1 ].VAD_flags[ channel_state[ 0 ].nFramesDecoded ] == 0 ) || - ( lostFlag == FLAG_DECODE_LBRR && channel_state[ 1 ].LBRR_flags[ channel_state[ 0 ].nFramesDecoded ] == 0 ) ) - { - silk_stereo_decode_mid_only( psRangeDec, &decode_only_middle ); - } else { - decode_only_middle = 0; - } - } else { - for( n = 0; n < 2; n++ ) { - MS_pred_Q13[ n ] = psDec->sStereo.pred_prev_Q13[ n ]; - } - } - } - - /* Reset side channel decoder prediction memory for first frame with side coding */ - if( decControl->nChannelsInternal == 2 && decode_only_middle == 0 && psDec->prev_decode_only_middle == 1 ) { - silk_memset( psDec->channel_state[ 1 ].outBuf, 0, sizeof(psDec->channel_state[ 1 ].outBuf) ); - silk_memset( psDec->channel_state[ 1 ].sLPC_Q14_buf, 0, sizeof(psDec->channel_state[ 1 ].sLPC_Q14_buf) ); - psDec->channel_state[ 1 ].lagPrev = 100; - psDec->channel_state[ 1 ].LastGainIndex = 10; - psDec->channel_state[ 1 ].prevSignalType = TYPE_NO_VOICE_ACTIVITY; - psDec->channel_state[ 1 ].first_frame_after_reset = 1; - } - - ALLOC( samplesOut1_tmp_storage, - decControl->nChannelsInternal*( - channel_state[ 0 ].frame_length + 2 ), - opus_int16 ); - samplesOut1_tmp[ 0 ] = samplesOut1_tmp_storage; - samplesOut1_tmp[ 1 ] = samplesOut1_tmp_storage - + channel_state[ 0 ].frame_length + 2; - - if( lostFlag == FLAG_DECODE_NORMAL ) { - has_side = !decode_only_middle; - } else { - has_side = !psDec->prev_decode_only_middle - || (decControl->nChannelsInternal == 2 && lostFlag == FLAG_DECODE_LBRR && channel_state[1].LBRR_flags[ channel_state[1].nFramesDecoded ] == 1 ); - } - /* Call decoder for one frame */ - for( n = 0; n < decControl->nChannelsInternal; n++ ) { - if( n == 0 || has_side ) { - opus_int FrameIndex; - opus_int condCoding; - - FrameIndex = channel_state[ 0 ].nFramesDecoded - n; - /* Use independent coding if no previous frame available */ - if( FrameIndex <= 0 ) { - condCoding = CODE_INDEPENDENTLY; - } else if( lostFlag == FLAG_DECODE_LBRR ) { - condCoding = channel_state[ n ].LBRR_flags[ FrameIndex - 1 ] ? CODE_CONDITIONALLY : CODE_INDEPENDENTLY; - } else if( n > 0 && psDec->prev_decode_only_middle ) { - /* If we skipped a side frame in this packet, we don't - need LTP scaling; the LTP state is well-defined. */ - condCoding = CODE_INDEPENDENTLY_NO_LTP_SCALING; - } else { - condCoding = CODE_CONDITIONALLY; - } - ret += silk_decode_frame( &channel_state[ n ], psRangeDec, &samplesOut1_tmp[ n ][ 2 ], &nSamplesOutDec, lostFlag, condCoding); - } else { - silk_memset( &samplesOut1_tmp[ n ][ 2 ], 0, nSamplesOutDec * sizeof( opus_int16 ) ); - } - channel_state[ n ].nFramesDecoded++; - } - - if( decControl->nChannelsAPI == 2 && decControl->nChannelsInternal == 2 ) { - /* Convert Mid/Side to Left/Right */ - silk_stereo_MS_to_LR( &psDec->sStereo, samplesOut1_tmp[ 0 ], samplesOut1_tmp[ 1 ], MS_pred_Q13, channel_state[ 0 ].fs_kHz, nSamplesOutDec ); - } else { - /* Buffering */ - silk_memcpy( samplesOut1_tmp[ 0 ], psDec->sStereo.sMid, 2 * sizeof( opus_int16 ) ); - silk_memcpy( psDec->sStereo.sMid, &samplesOut1_tmp[ 0 ][ nSamplesOutDec ], 2 * sizeof( opus_int16 ) ); - } - - /* Number of output samples */ - *nSamplesOut = silk_DIV32( nSamplesOutDec * decControl->API_sampleRate, silk_SMULBB( channel_state[ 0 ].fs_kHz, 1000 ) ); - - /* Set up pointers to temp buffers */ - ALLOC( samplesOut2_tmp, - decControl->nChannelsAPI == 2 ? *nSamplesOut : 0, opus_int16 ); - if( decControl->nChannelsAPI == 2 ) { - resample_out_ptr = samplesOut2_tmp; - } else { - resample_out_ptr = samplesOut; - } - - for( n = 0; n < silk_min( decControl->nChannelsAPI, decControl->nChannelsInternal ); n++ ) { - - /* Resample decoded signal to API_sampleRate */ - ret += silk_resampler( &channel_state[ n ].resampler_state, resample_out_ptr, &samplesOut1_tmp[ n ][ 1 ], nSamplesOutDec ); - - /* Interleave if stereo output and stereo stream */ - if( decControl->nChannelsAPI == 2 ) { - for( i = 0; i < *nSamplesOut; i++ ) { - samplesOut[ n + 2 * i ] = resample_out_ptr[ i ]; - } - } - } - - /* Create two channel output from mono stream */ - if( decControl->nChannelsAPI == 2 && decControl->nChannelsInternal == 1 ) { - if ( stereo_to_mono ){ - /* Resample right channel for newly collapsed stereo just in case - we weren't doing collapsing when switching to mono */ - ret += silk_resampler( &channel_state[ 1 ].resampler_state, resample_out_ptr, &samplesOut1_tmp[ 0 ][ 1 ], nSamplesOutDec ); - - for( i = 0; i < *nSamplesOut; i++ ) { - samplesOut[ 1 + 2 * i ] = resample_out_ptr[ i ]; - } - } else { - for( i = 0; i < *nSamplesOut; i++ ) { - samplesOut[ 1 + 2 * i ] = samplesOut[ 0 + 2 * i ]; - } - } - } - - /* Export pitch lag, measured at 48 kHz sampling rate */ - if( channel_state[ 0 ].prevSignalType == TYPE_VOICED ) { - int mult_tab[ 3 ] = { 6, 4, 3 }; - decControl->prevPitchLag = channel_state[ 0 ].lagPrev * mult_tab[ ( channel_state[ 0 ].fs_kHz - 8 ) >> 2 ]; - } else { - decControl->prevPitchLag = 0; - } - - if( lostFlag == FLAG_PACKET_LOST ) { - /* On packet loss, remove the gain clamping to prevent having the energy "bounce back" - if we lose packets when the energy is going down */ - for ( i = 0; i < psDec->nChannelsInternal; i++ ) - psDec->channel_state[ i ].LastGainIndex = 10; - } else { - psDec->prev_decode_only_middle = decode_only_middle; - } - RESTORE_STACK; - return ret; -} - -#if 0 -/* Getting table of contents for a packet */ -opus_int silk_get_TOC( - const opus_uint8 *payload, /* I Payload data */ - const opus_int nBytesIn, /* I Number of input bytes */ - const opus_int nFramesPerPayload, /* I Number of SILK frames per payload */ - silk_TOC_struct *Silk_TOC /* O Type of content */ -) -{ - opus_int i, flags, ret = SILK_NO_ERROR; - - if( nBytesIn < 1 ) { - return -1; - } - if( nFramesPerPayload < 0 || nFramesPerPayload > 3 ) { - return -1; - } - - silk_memset( Silk_TOC, 0, sizeof( *Silk_TOC ) ); - - /* For stereo, extract the flags for the mid channel */ - flags = silk_RSHIFT( payload[ 0 ], 7 - nFramesPerPayload ) & ( silk_LSHIFT( 1, nFramesPerPayload + 1 ) - 1 ); - - Silk_TOC->inbandFECFlag = flags & 1; - for( i = nFramesPerPayload - 1; i >= 0 ; i-- ) { - flags = silk_RSHIFT( flags, 1 ); - Silk_TOC->VADFlags[ i ] = flags & 1; - Silk_TOC->VADFlag |= flags & 1; - } - - return ret; -} -#endif diff --git a/src/opus-1.0.2/silk/decode_core.c b/src/opus-1.0.2/silk/decode_core.c deleted file mode 100644 index 0365ffdf..00000000 --- a/src/opus-1.0.2/silk/decode_core.c +++ /dev/null @@ -1,238 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main.h" -#include "stack_alloc.h" - -/**********************************************************/ -/* Core decoder. Performs inverse NSQ operation LTP + LPC */ -/**********************************************************/ -void silk_decode_core( - silk_decoder_state *psDec, /* I/O Decoder state */ - silk_decoder_control *psDecCtrl, /* I Decoder control */ - opus_int16 xq[], /* O Decoded speech */ - const opus_int pulses[ MAX_FRAME_LENGTH ] /* I Pulse signal */ -) -{ - opus_int i, k, lag = 0, start_idx, sLTP_buf_idx, NLSF_interpolation_flag, signalType; - opus_int16 *A_Q12, *B_Q14, *pxq, A_Q12_tmp[ MAX_LPC_ORDER ]; - VARDECL( opus_int16, sLTP ); - VARDECL( opus_int32, sLTP_Q15 ); - opus_int32 LTP_pred_Q13, LPC_pred_Q10, Gain_Q10, inv_gain_Q31, gain_adj_Q16, rand_seed, offset_Q10; - opus_int32 *pred_lag_ptr, *pexc_Q14, *pres_Q14; - VARDECL( opus_int32, res_Q14 ); - VARDECL( opus_int32, sLPC_Q14 ); - SAVE_STACK; - - silk_assert( psDec->prev_gain_Q16 != 0 ); - - ALLOC( sLTP, psDec->ltp_mem_length, opus_int16 ); - ALLOC( sLTP_Q15, psDec->ltp_mem_length + psDec->frame_length, opus_int32 ); - ALLOC( res_Q14, psDec->subfr_length, opus_int32 ); - ALLOC( sLPC_Q14, psDec->subfr_length + MAX_LPC_ORDER, opus_int32 ); - - offset_Q10 = silk_Quantization_Offsets_Q10[ psDec->indices.signalType >> 1 ][ psDec->indices.quantOffsetType ]; - - if( psDec->indices.NLSFInterpCoef_Q2 < 1 << 2 ) { - NLSF_interpolation_flag = 1; - } else { - NLSF_interpolation_flag = 0; - } - - /* Decode excitation */ - rand_seed = psDec->indices.Seed; - for( i = 0; i < psDec->frame_length; i++ ) { - rand_seed = silk_RAND( rand_seed ); - psDec->exc_Q14[ i ] = silk_LSHIFT( (opus_int32)pulses[ i ], 14 ); - if( psDec->exc_Q14[ i ] > 0 ) { - psDec->exc_Q14[ i ] -= QUANT_LEVEL_ADJUST_Q10 << 4; - } else - if( psDec->exc_Q14[ i ] < 0 ) { - psDec->exc_Q14[ i ] += QUANT_LEVEL_ADJUST_Q10 << 4; - } - psDec->exc_Q14[ i ] += offset_Q10 << 4; - if( rand_seed < 0 ) { - psDec->exc_Q14[ i ] = -psDec->exc_Q14[ i ]; - } - - rand_seed = silk_ADD32_ovflw( rand_seed, pulses[ i ] ); - } - - /* Copy LPC state */ - silk_memcpy( sLPC_Q14, psDec->sLPC_Q14_buf, MAX_LPC_ORDER * sizeof( opus_int32 ) ); - - pexc_Q14 = psDec->exc_Q14; - pxq = xq; - sLTP_buf_idx = psDec->ltp_mem_length; - /* Loop over subframes */ - for( k = 0; k < psDec->nb_subfr; k++ ) { - pres_Q14 = res_Q14; - A_Q12 = psDecCtrl->PredCoef_Q12[ k >> 1 ]; - - /* Preload LPC coeficients to array on stack. Gives small performance gain */ - silk_memcpy( A_Q12_tmp, A_Q12, psDec->LPC_order * sizeof( opus_int16 ) ); - B_Q14 = &psDecCtrl->LTPCoef_Q14[ k * LTP_ORDER ]; - signalType = psDec->indices.signalType; - - Gain_Q10 = silk_RSHIFT( psDecCtrl->Gains_Q16[ k ], 6 ); - inv_gain_Q31 = silk_INVERSE32_varQ( psDecCtrl->Gains_Q16[ k ], 47 ); - - /* Calculate gain adjustment factor */ - if( psDecCtrl->Gains_Q16[ k ] != psDec->prev_gain_Q16 ) { - gain_adj_Q16 = silk_DIV32_varQ( psDec->prev_gain_Q16, psDecCtrl->Gains_Q16[ k ], 16 ); - - /* Scale short term state */ - for( i = 0; i < MAX_LPC_ORDER; i++ ) { - sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, sLPC_Q14[ i ] ); - } - } else { - gain_adj_Q16 = (opus_int32)1 << 16; - } - - /* Save inv_gain */ - silk_assert( inv_gain_Q31 != 0 ); - psDec->prev_gain_Q16 = psDecCtrl->Gains_Q16[ k ]; - - /* Avoid abrupt transition from voiced PLC to unvoiced normal decoding */ - if( psDec->lossCnt && psDec->prevSignalType == TYPE_VOICED && - psDec->indices.signalType != TYPE_VOICED && k < MAX_NB_SUBFR/2 ) { - - silk_memset( B_Q14, 0, LTP_ORDER * sizeof( opus_int16 ) ); - B_Q14[ LTP_ORDER/2 ] = SILK_FIX_CONST( 0.25, 14 ); - - signalType = TYPE_VOICED; - psDecCtrl->pitchL[ k ] = psDec->lagPrev; - } - - if( signalType == TYPE_VOICED ) { - /* Voiced */ - lag = psDecCtrl->pitchL[ k ]; - - /* Re-whitening */ - if( k == 0 || ( k == 2 && NLSF_interpolation_flag ) ) { - /* Rewhiten with new A coefs */ - start_idx = psDec->ltp_mem_length - lag - psDec->LPC_order - LTP_ORDER / 2; - silk_assert( start_idx > 0 ); - - if( k == 2 ) { - silk_memcpy( &psDec->outBuf[ psDec->ltp_mem_length ], xq, 2 * psDec->subfr_length * sizeof( opus_int16 ) ); - } - - silk_LPC_analysis_filter( &sLTP[ start_idx ], &psDec->outBuf[ start_idx + k * psDec->subfr_length ], - A_Q12, psDec->ltp_mem_length - start_idx, psDec->LPC_order ); - - /* After rewhitening the LTP state is unscaled */ - if( k == 0 ) { - /* Do LTP downscaling to reduce inter-packet dependency */ - inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, psDecCtrl->LTP_scale_Q14 ), 2 ); - } - for( i = 0; i < lag + LTP_ORDER/2; i++ ) { - sLTP_Q15[ sLTP_buf_idx - i - 1 ] = silk_SMULWB( inv_gain_Q31, sLTP[ psDec->ltp_mem_length - i - 1 ] ); - } - } else { - /* Update LTP state when Gain changes */ - if( gain_adj_Q16 != (opus_int32)1 << 16 ) { - for( i = 0; i < lag + LTP_ORDER/2; i++ ) { - sLTP_Q15[ sLTP_buf_idx - i - 1 ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ sLTP_buf_idx - i - 1 ] ); - } - } - } - } - - /* Long-term prediction */ - if( signalType == TYPE_VOICED ) { - /* Set up pointer */ - pred_lag_ptr = &sLTP_Q15[ sLTP_buf_idx - lag + LTP_ORDER / 2 ]; - for( i = 0; i < psDec->subfr_length; i++ ) { - /* Unrolled loop */ - /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ - LTP_pred_Q13 = 2; - LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ 0 ], B_Q14[ 0 ] ); - LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -1 ], B_Q14[ 1 ] ); - LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -2 ], B_Q14[ 2 ] ); - LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -3 ], B_Q14[ 3 ] ); - LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -4 ], B_Q14[ 4 ] ); - pred_lag_ptr++; - - /* Generate LPC excitation */ - pres_Q14[ i ] = silk_ADD_LSHIFT32( pexc_Q14[ i ], LTP_pred_Q13, 1 ); - - /* Update states */ - sLTP_Q15[ sLTP_buf_idx ] = silk_LSHIFT( pres_Q14[ i ], 1 ); - sLTP_buf_idx++; - } - } else { - pres_Q14 = pexc_Q14; - } - - for( i = 0; i < psDec->subfr_length; i++ ) { - /* Short-term prediction */ - silk_assert( psDec->LPC_order == 10 || psDec->LPC_order == 16 ); - /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ - LPC_pred_Q10 = silk_RSHIFT( psDec->LPC_order, 1 ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 1 ], A_Q12_tmp[ 0 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 2 ], A_Q12_tmp[ 1 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 3 ], A_Q12_tmp[ 2 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 4 ], A_Q12_tmp[ 3 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 5 ], A_Q12_tmp[ 4 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 6 ], A_Q12_tmp[ 5 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 7 ], A_Q12_tmp[ 6 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 8 ], A_Q12_tmp[ 7 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 9 ], A_Q12_tmp[ 8 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 10 ], A_Q12_tmp[ 9 ] ); - if( psDec->LPC_order == 16 ) { - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 11 ], A_Q12_tmp[ 10 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 12 ], A_Q12_tmp[ 11 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 13 ], A_Q12_tmp[ 12 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 14 ], A_Q12_tmp[ 13 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 15 ], A_Q12_tmp[ 14 ] ); - LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 16 ], A_Q12_tmp[ 15 ] ); - } - - /* Add prediction to LPC excitation */ - sLPC_Q14[ MAX_LPC_ORDER + i ] = silk_ADD_LSHIFT32( pres_Q14[ i ], LPC_pred_Q10, 4 ); - - /* Scale with gain */ - pxq[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( sLPC_Q14[ MAX_LPC_ORDER + i ], Gain_Q10 ), 8 ) ); - } - - /* DEBUG_STORE_DATA( dec.pcm, pxq, psDec->subfr_length * sizeof( opus_int16 ) ) */ - - /* Update LPC filter state */ - silk_memcpy( sLPC_Q14, &sLPC_Q14[ psDec->subfr_length ], MAX_LPC_ORDER * sizeof( opus_int32 ) ); - pexc_Q14 += psDec->subfr_length; - pxq += psDec->subfr_length; - } - - /* Save LPC state */ - silk_memcpy( psDec->sLPC_Q14_buf, sLPC_Q14, MAX_LPC_ORDER * sizeof( opus_int32 ) ); - RESTORE_STACK; -} diff --git a/src/opus-1.0.2/silk/decode_frame.c b/src/opus-1.0.2/silk/decode_frame.c deleted file mode 100644 index 3e4a6e2b..00000000 --- a/src/opus-1.0.2/silk/decode_frame.c +++ /dev/null @@ -1,128 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main.h" -#include "stack_alloc.h" -#include "PLC.h" - -/****************/ -/* Decode frame */ -/****************/ -opus_int silk_decode_frame( - silk_decoder_state *psDec, /* I/O Pointer to Silk decoder state */ - ec_dec *psRangeDec, /* I/O Compressor data structure */ - opus_int16 pOut[], /* O Pointer to output speech frame */ - opus_int32 *pN, /* O Pointer to size of output frame */ - opus_int lostFlag, /* I 0: no loss, 1 loss, 2 decode fec */ - opus_int condCoding /* I The type of conditional coding to use */ -) -{ - VARDECL( silk_decoder_control, psDecCtrl ); - opus_int L, mv_len, ret = 0; - VARDECL( opus_int, pulses ); - SAVE_STACK; - - L = psDec->frame_length; - ALLOC( psDecCtrl, 1, silk_decoder_control ); - ALLOC( pulses, (L + SHELL_CODEC_FRAME_LENGTH - 1) & - ~(SHELL_CODEC_FRAME_LENGTH - 1), opus_int ); - psDecCtrl->LTP_scale_Q14 = 0; - - /* Safety checks */ - silk_assert( L > 0 && L <= MAX_FRAME_LENGTH ); - - if( lostFlag == FLAG_DECODE_NORMAL || - ( lostFlag == FLAG_DECODE_LBRR && psDec->LBRR_flags[ psDec->nFramesDecoded ] == 1 ) ) - { - /*********************************************/ - /* Decode quantization indices of side info */ - /*********************************************/ - silk_decode_indices( psDec, psRangeDec, psDec->nFramesDecoded, lostFlag, condCoding ); - - /*********************************************/ - /* Decode quantization indices of excitation */ - /*********************************************/ - silk_decode_pulses( psRangeDec, pulses, psDec->indices.signalType, - psDec->indices.quantOffsetType, psDec->frame_length ); - - /********************************************/ - /* Decode parameters and pulse signal */ - /********************************************/ - silk_decode_parameters( psDec, psDecCtrl, condCoding ); - - /********************************************************/ - /* Run inverse NSQ */ - /********************************************************/ - silk_decode_core( psDec, psDecCtrl, pOut, pulses ); - - /********************************************************/ - /* Update PLC state */ - /********************************************************/ - silk_PLC( psDec, psDecCtrl, pOut, 0 ); - - psDec->lossCnt = 0; - psDec->prevSignalType = psDec->indices.signalType; - silk_assert( psDec->prevSignalType >= 0 && psDec->prevSignalType <= 2 ); - - /* A frame has been decoded without errors */ - psDec->first_frame_after_reset = 0; - } else { - /* Handle packet loss by extrapolation */ - silk_PLC( psDec, psDecCtrl, pOut, 1 ); - } - - /*************************/ - /* Update output buffer. */ - /*************************/ - silk_assert( psDec->ltp_mem_length >= psDec->frame_length ); - mv_len = psDec->ltp_mem_length - psDec->frame_length; - silk_memmove( psDec->outBuf, &psDec->outBuf[ psDec->frame_length ], mv_len * sizeof(opus_int16) ); - silk_memcpy( &psDec->outBuf[ mv_len ], pOut, psDec->frame_length * sizeof( opus_int16 ) ); - - /****************************************************************/ - /* Ensure smooth connection of extrapolated and good frames */ - /****************************************************************/ - silk_PLC_glue_frames( psDec, pOut, L ); - - /************************************************/ - /* Comfort noise generation / estimation */ - /************************************************/ - silk_CNG( psDec, psDecCtrl, pOut, L ); - - /* Update some decoder state variables */ - psDec->lagPrev = psDecCtrl->pitchL[ psDec->nb_subfr - 1 ]; - - /* Set output frame length */ - *pN = L; - - RESTORE_STACK; - return ret; -} diff --git a/src/opus-1.0.2/silk/decode_indices.c b/src/opus-1.0.2/silk/decode_indices.c deleted file mode 100644 index 69172102..00000000 --- a/src/opus-1.0.2/silk/decode_indices.c +++ /dev/null @@ -1,151 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main.h" - -/* Decode side-information parameters from payload */ -void silk_decode_indices( - silk_decoder_state *psDec, /* I/O State */ - ec_dec *psRangeDec, /* I/O Compressor data structure */ - opus_int FrameIndex, /* I Frame number */ - opus_int decode_LBRR, /* I Flag indicating LBRR data is being decoded */ - opus_int condCoding /* I The type of conditional coding to use */ -) -{ - opus_int i, k, Ix; - opus_int decode_absolute_lagIndex, delta_lagIndex; - opus_int16 ec_ix[ MAX_LPC_ORDER ]; - opus_uint8 pred_Q8[ MAX_LPC_ORDER ]; - - /*******************************************/ - /* Decode signal type and quantizer offset */ - /*******************************************/ - if( decode_LBRR || psDec->VAD_flags[ FrameIndex ] ) { - Ix = ec_dec_icdf( psRangeDec, silk_type_offset_VAD_iCDF, 8 ) + 2; - } else { - Ix = ec_dec_icdf( psRangeDec, silk_type_offset_no_VAD_iCDF, 8 ); - } - psDec->indices.signalType = (opus_int8)silk_RSHIFT( Ix, 1 ); - psDec->indices.quantOffsetType = (opus_int8)( Ix & 1 ); - - /****************/ - /* Decode gains */ - /****************/ - /* First subframe */ - if( condCoding == CODE_CONDITIONALLY ) { - /* Conditional coding */ - psDec->indices.GainsIndices[ 0 ] = (opus_int8)ec_dec_icdf( psRangeDec, silk_delta_gain_iCDF, 8 ); - } else { - /* Independent coding, in two stages: MSB bits followed by 3 LSBs */ - psDec->indices.GainsIndices[ 0 ] = (opus_int8)silk_LSHIFT( ec_dec_icdf( psRangeDec, silk_gain_iCDF[ psDec->indices.signalType ], 8 ), 3 ); - psDec->indices.GainsIndices[ 0 ] += (opus_int8)ec_dec_icdf( psRangeDec, silk_uniform8_iCDF, 8 ); - } - - /* Remaining subframes */ - for( i = 1; i < psDec->nb_subfr; i++ ) { - psDec->indices.GainsIndices[ i ] = (opus_int8)ec_dec_icdf( psRangeDec, silk_delta_gain_iCDF, 8 ); - } - - /**********************/ - /* Decode LSF Indices */ - /**********************/ - psDec->indices.NLSFIndices[ 0 ] = (opus_int8)ec_dec_icdf( psRangeDec, &psDec->psNLSF_CB->CB1_iCDF[ ( psDec->indices.signalType >> 1 ) * psDec->psNLSF_CB->nVectors ], 8 ); - silk_NLSF_unpack( ec_ix, pred_Q8, psDec->psNLSF_CB, psDec->indices.NLSFIndices[ 0 ] ); - silk_assert( psDec->psNLSF_CB->order == psDec->LPC_order ); - for( i = 0; i < psDec->psNLSF_CB->order; i++ ) { - Ix = ec_dec_icdf( psRangeDec, &psDec->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 ); - if( Ix == 0 ) { - Ix -= ec_dec_icdf( psRangeDec, silk_NLSF_EXT_iCDF, 8 ); - } else if( Ix == 2 * NLSF_QUANT_MAX_AMPLITUDE ) { - Ix += ec_dec_icdf( psRangeDec, silk_NLSF_EXT_iCDF, 8 ); - } - psDec->indices.NLSFIndices[ i+1 ] = (opus_int8)( Ix - NLSF_QUANT_MAX_AMPLITUDE ); - } - - /* Decode LSF interpolation factor */ - if( psDec->nb_subfr == MAX_NB_SUBFR ) { - psDec->indices.NLSFInterpCoef_Q2 = (opus_int8)ec_dec_icdf( psRangeDec, silk_NLSF_interpolation_factor_iCDF, 8 ); - } else { - psDec->indices.NLSFInterpCoef_Q2 = 4; - } - - if( psDec->indices.signalType == TYPE_VOICED ) - { - /*********************/ - /* Decode pitch lags */ - /*********************/ - /* Get lag index */ - decode_absolute_lagIndex = 1; - if( condCoding == CODE_CONDITIONALLY && psDec->ec_prevSignalType == TYPE_VOICED ) { - /* Decode Delta index */ - delta_lagIndex = (opus_int16)ec_dec_icdf( psRangeDec, silk_pitch_delta_iCDF, 8 ); - if( delta_lagIndex > 0 ) { - delta_lagIndex = delta_lagIndex - 9; - psDec->indices.lagIndex = (opus_int16)( psDec->ec_prevLagIndex + delta_lagIndex ); - decode_absolute_lagIndex = 0; - } - } - if( decode_absolute_lagIndex ) { - /* Absolute decoding */ - psDec->indices.lagIndex = (opus_int16)ec_dec_icdf( psRangeDec, silk_pitch_lag_iCDF, 8 ) * silk_RSHIFT( psDec->fs_kHz, 1 ); - psDec->indices.lagIndex += (opus_int16)ec_dec_icdf( psRangeDec, psDec->pitch_lag_low_bits_iCDF, 8 ); - } - psDec->ec_prevLagIndex = psDec->indices.lagIndex; - - /* Get countour index */ - psDec->indices.contourIndex = (opus_int8)ec_dec_icdf( psRangeDec, psDec->pitch_contour_iCDF, 8 ); - - /********************/ - /* Decode LTP gains */ - /********************/ - /* Decode PERIndex value */ - psDec->indices.PERIndex = (opus_int8)ec_dec_icdf( psRangeDec, silk_LTP_per_index_iCDF, 8 ); - - for( k = 0; k < psDec->nb_subfr; k++ ) { - psDec->indices.LTPIndex[ k ] = (opus_int8)ec_dec_icdf( psRangeDec, silk_LTP_gain_iCDF_ptrs[ psDec->indices.PERIndex ], 8 ); - } - - /**********************/ - /* Decode LTP scaling */ - /**********************/ - if( condCoding == CODE_INDEPENDENTLY ) { - psDec->indices.LTP_scaleIndex = (opus_int8)ec_dec_icdf( psRangeDec, silk_LTPscale_iCDF, 8 ); - } else { - psDec->indices.LTP_scaleIndex = 0; - } - } - psDec->ec_prevSignalType = psDec->indices.signalType; - - /***************/ - /* Decode seed */ - /***************/ - psDec->indices.Seed = (opus_int8)ec_dec_icdf( psRangeDec, silk_uniform4_iCDF, 8 ); -} diff --git a/src/opus-1.0.2/silk/decode_parameters.c b/src/opus-1.0.2/silk/decode_parameters.c deleted file mode 100644 index e4c7e7a4..00000000 --- a/src/opus-1.0.2/silk/decode_parameters.c +++ /dev/null @@ -1,115 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main.h" - -/* Decode parameters from payload */ -void silk_decode_parameters( - silk_decoder_state *psDec, /* I/O State */ - silk_decoder_control *psDecCtrl, /* I/O Decoder control */ - opus_int condCoding /* I The type of conditional coding to use */ -) -{ - opus_int i, k, Ix; - opus_int16 pNLSF_Q15[ MAX_LPC_ORDER ], pNLSF0_Q15[ MAX_LPC_ORDER ]; - const opus_int8 *cbk_ptr_Q7; - - /* Dequant Gains */ - silk_gains_dequant( psDecCtrl->Gains_Q16, psDec->indices.GainsIndices, - &psDec->LastGainIndex, condCoding == CODE_CONDITIONALLY, psDec->nb_subfr ); - - /****************/ - /* Decode NLSFs */ - /****************/ - silk_NLSF_decode( pNLSF_Q15, psDec->indices.NLSFIndices, psDec->psNLSF_CB ); - - /* Convert NLSF parameters to AR prediction filter coefficients */ - silk_NLSF2A( psDecCtrl->PredCoef_Q12[ 1 ], pNLSF_Q15, psDec->LPC_order ); - - /* If just reset, e.g., because internal Fs changed, do not allow interpolation */ - /* improves the case of packet loss in the first frame after a switch */ - if( psDec->first_frame_after_reset == 1 ) { - psDec->indices.NLSFInterpCoef_Q2 = 4; - } - - if( psDec->indices.NLSFInterpCoef_Q2 < 4 ) { - /* Calculation of the interpolated NLSF0 vector from the interpolation factor, */ - /* the previous NLSF1, and the current NLSF1 */ - for( i = 0; i < psDec->LPC_order; i++ ) { - pNLSF0_Q15[ i ] = psDec->prevNLSF_Q15[ i ] + silk_RSHIFT( silk_MUL( psDec->indices.NLSFInterpCoef_Q2, - pNLSF_Q15[ i ] - psDec->prevNLSF_Q15[ i ] ), 2 ); - } - - /* Convert NLSF parameters to AR prediction filter coefficients */ - silk_NLSF2A( psDecCtrl->PredCoef_Q12[ 0 ], pNLSF0_Q15, psDec->LPC_order ); - } else { - /* Copy LPC coefficients for first half from second half */ - silk_memcpy( psDecCtrl->PredCoef_Q12[ 0 ], psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order * sizeof( opus_int16 ) ); - } - - silk_memcpy( psDec->prevNLSF_Q15, pNLSF_Q15, psDec->LPC_order * sizeof( opus_int16 ) ); - - /* After a packet loss do BWE of LPC coefs */ - if( psDec->lossCnt ) { - silk_bwexpander( psDecCtrl->PredCoef_Q12[ 0 ], psDec->LPC_order, BWE_AFTER_LOSS_Q16 ); - silk_bwexpander( psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order, BWE_AFTER_LOSS_Q16 ); - } - - if( psDec->indices.signalType == TYPE_VOICED ) { - /*********************/ - /* Decode pitch lags */ - /*********************/ - - /* Decode pitch values */ - silk_decode_pitch( psDec->indices.lagIndex, psDec->indices.contourIndex, psDecCtrl->pitchL, psDec->fs_kHz, psDec->nb_subfr ); - - /* Decode Codebook Index */ - cbk_ptr_Q7 = silk_LTP_vq_ptrs_Q7[ psDec->indices.PERIndex ]; /* set pointer to start of codebook */ - - for( k = 0; k < psDec->nb_subfr; k++ ) { - Ix = psDec->indices.LTPIndex[ k ]; - for( i = 0; i < LTP_ORDER; i++ ) { - psDecCtrl->LTPCoef_Q14[ k * LTP_ORDER + i ] = silk_LSHIFT( cbk_ptr_Q7[ Ix * LTP_ORDER + i ], 7 ); - } - } - - /**********************/ - /* Decode LTP scaling */ - /**********************/ - Ix = psDec->indices.LTP_scaleIndex; - psDecCtrl->LTP_scale_Q14 = silk_LTPScales_table_Q14[ Ix ]; - } else { - silk_memset( psDecCtrl->pitchL, 0, psDec->nb_subfr * sizeof( opus_int ) ); - silk_memset( psDecCtrl->LTPCoef_Q14, 0, LTP_ORDER * psDec->nb_subfr * sizeof( opus_int16 ) ); - psDec->indices.PERIndex = 0; - psDecCtrl->LTP_scale_Q14 = 0; - } -} diff --git a/src/opus-1.0.2/silk/decode_pitch.c b/src/opus-1.0.2/silk/decode_pitch.c deleted file mode 100644 index 80fb4d9f..00000000 --- a/src/opus-1.0.2/silk/decode_pitch.c +++ /dev/null @@ -1,77 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/*********************************************************** -* Pitch analyser function -********************************************************** */ -#include "SigProc_FIX.h" -#include "pitch_est_defines.h" - -void silk_decode_pitch( - opus_int16 lagIndex, /* I */ - opus_int8 contourIndex, /* O */ - opus_int pitch_lags[], /* O 4 pitch values */ - const opus_int Fs_kHz, /* I sampling frequency (kHz) */ - const opus_int nb_subfr /* I number of sub frames */ -) -{ - opus_int lag, k, min_lag, max_lag, cbk_size; - const opus_int8 *Lag_CB_ptr; - - if( Fs_kHz == 8 ) { - if( nb_subfr == PE_MAX_NB_SUBFR ) { - Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ]; - cbk_size = PE_NB_CBKS_STAGE2_EXT; - } else { - silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1 ); - Lag_CB_ptr = &silk_CB_lags_stage2_10_ms[ 0 ][ 0 ]; - cbk_size = PE_NB_CBKS_STAGE2_10MS; - } - } else { - if( nb_subfr == PE_MAX_NB_SUBFR ) { - Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ]; - cbk_size = PE_NB_CBKS_STAGE3_MAX; - } else { - silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1 ); - Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ]; - cbk_size = PE_NB_CBKS_STAGE3_10MS; - } - } - - min_lag = silk_SMULBB( PE_MIN_LAG_MS, Fs_kHz ); - max_lag = silk_SMULBB( PE_MAX_LAG_MS, Fs_kHz ); - lag = min_lag + lagIndex; - - for( k = 0; k < nb_subfr; k++ ) { - pitch_lags[ k ] = lag + matrix_ptr( Lag_CB_ptr, k, contourIndex, cbk_size ); - pitch_lags[ k ] = silk_LIMIT( pitch_lags[ k ], min_lag, max_lag ); - } -} diff --git a/src/opus-1.0.2/silk/decode_pulses.c b/src/opus-1.0.2/silk/decode_pulses.c deleted file mode 100644 index 1c781a0b..00000000 --- a/src/opus-1.0.2/silk/decode_pulses.c +++ /dev/null @@ -1,115 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main.h" - -/*********************************************/ -/* Decode quantization indices of excitation */ -/*********************************************/ -void silk_decode_pulses( - ec_dec *psRangeDec, /* I/O Compressor data structure */ - opus_int pulses[], /* O Excitation signal */ - const opus_int signalType, /* I Sigtype */ - const opus_int quantOffsetType, /* I quantOffsetType */ - const opus_int frame_length /* I Frame length */ -) -{ - opus_int i, j, k, iter, abs_q, nLS, RateLevelIndex; - opus_int sum_pulses[ MAX_NB_SHELL_BLOCKS ], nLshifts[ MAX_NB_SHELL_BLOCKS ]; - opus_int *pulses_ptr; - const opus_uint8 *cdf_ptr; - - /*********************/ - /* Decode rate level */ - /*********************/ - RateLevelIndex = ec_dec_icdf( psRangeDec, silk_rate_levels_iCDF[ signalType >> 1 ], 8 ); - - /* Calculate number of shell blocks */ - silk_assert( 1 << LOG2_SHELL_CODEC_FRAME_LENGTH == SHELL_CODEC_FRAME_LENGTH ); - iter = silk_RSHIFT( frame_length, LOG2_SHELL_CODEC_FRAME_LENGTH ); - if( iter * SHELL_CODEC_FRAME_LENGTH < frame_length ) { - silk_assert( frame_length == 12 * 10 ); /* Make sure only happens for 10 ms @ 12 kHz */ - iter++; - } - - /***************************************************/ - /* Sum-Weighted-Pulses Decoding */ - /***************************************************/ - cdf_ptr = silk_pulses_per_block_iCDF[ RateLevelIndex ]; - for( i = 0; i < iter; i++ ) { - nLshifts[ i ] = 0; - sum_pulses[ i ] = ec_dec_icdf( psRangeDec, cdf_ptr, 8 ); - - /* LSB indication */ - while( sum_pulses[ i ] == MAX_PULSES + 1 ) { - nLshifts[ i ]++; - /* When we've already got 10 LSBs, we shift the table to not allow (MAX_PULSES + 1) */ - sum_pulses[ i ] = ec_dec_icdf( psRangeDec, - silk_pulses_per_block_iCDF[ N_RATE_LEVELS - 1] + ( nLshifts[ i ] == 10 ), 8 ); - } - } - - /***************************************************/ - /* Shell decoding */ - /***************************************************/ - for( i = 0; i < iter; i++ ) { - if( sum_pulses[ i ] > 0 ) { - silk_shell_decoder( &pulses[ silk_SMULBB( i, SHELL_CODEC_FRAME_LENGTH ) ], psRangeDec, sum_pulses[ i ] ); - } else { - silk_memset( &pulses[ silk_SMULBB( i, SHELL_CODEC_FRAME_LENGTH ) ], 0, SHELL_CODEC_FRAME_LENGTH * sizeof( opus_int ) ); - } - } - - /***************************************************/ - /* LSB Decoding */ - /***************************************************/ - for( i = 0; i < iter; i++ ) { - if( nLshifts[ i ] > 0 ) { - nLS = nLshifts[ i ]; - pulses_ptr = &pulses[ silk_SMULBB( i, SHELL_CODEC_FRAME_LENGTH ) ]; - for( k = 0; k < SHELL_CODEC_FRAME_LENGTH; k++ ) { - abs_q = pulses_ptr[ k ]; - for( j = 0; j < nLS; j++ ) { - abs_q = silk_LSHIFT( abs_q, 1 ); - abs_q += ec_dec_icdf( psRangeDec, silk_lsb_iCDF, 8 ); - } - pulses_ptr[ k ] = abs_q; - } - /* Mark the number of pulses non-zero for sign decoding. */ - sum_pulses[ i ] |= nLS << 5; - } - } - - /****************************************/ - /* Decode and add signs to pulse signal */ - /****************************************/ - silk_decode_signs( psRangeDec, pulses, frame_length, signalType, quantOffsetType, sum_pulses ); -} diff --git a/src/opus-1.0.2/silk/decoder_set_fs.c b/src/opus-1.0.2/silk/decoder_set_fs.c deleted file mode 100644 index 38ac249c..00000000 --- a/src/opus-1.0.2/silk/decoder_set_fs.c +++ /dev/null @@ -1,108 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main.h" - -/* Set decoder sampling rate */ -opus_int silk_decoder_set_fs( - silk_decoder_state *psDec, /* I/O Decoder state pointer */ - opus_int fs_kHz, /* I Sampling frequency (kHz) */ - opus_int32 fs_API_Hz /* I API Sampling frequency (Hz) */ -) -{ - opus_int frame_length, ret = 0; - - silk_assert( fs_kHz == 8 || fs_kHz == 12 || fs_kHz == 16 ); - silk_assert( psDec->nb_subfr == MAX_NB_SUBFR || psDec->nb_subfr == MAX_NB_SUBFR/2 ); - - /* New (sub)frame length */ - psDec->subfr_length = silk_SMULBB( SUB_FRAME_LENGTH_MS, fs_kHz ); - frame_length = silk_SMULBB( psDec->nb_subfr, psDec->subfr_length ); - - /* Initialize resampler when switching internal or external sampling frequency */ - if( psDec->fs_kHz != fs_kHz || psDec->fs_API_hz != fs_API_Hz ) { - /* Initialize the resampler for dec_API.c preparing resampling from fs_kHz to API_fs_Hz */ - ret += silk_resampler_init( &psDec->resampler_state, silk_SMULBB( fs_kHz, 1000 ), fs_API_Hz, 0 ); - - psDec->fs_API_hz = fs_API_Hz; - } - - if( psDec->fs_kHz != fs_kHz || frame_length != psDec->frame_length ) { - if( fs_kHz == 8 ) { - if( psDec->nb_subfr == MAX_NB_SUBFR ) { - psDec->pitch_contour_iCDF = silk_pitch_contour_NB_iCDF; - } else { - psDec->pitch_contour_iCDF = silk_pitch_contour_10_ms_NB_iCDF; - } - } else { - if( psDec->nb_subfr == MAX_NB_SUBFR ) { - psDec->pitch_contour_iCDF = silk_pitch_contour_iCDF; - } else { - psDec->pitch_contour_iCDF = silk_pitch_contour_10_ms_iCDF; - } - } - if( psDec->fs_kHz != fs_kHz ) { - psDec->ltp_mem_length = silk_SMULBB( LTP_MEM_LENGTH_MS, fs_kHz ); - if( fs_kHz == 8 || fs_kHz == 12 ) { - psDec->LPC_order = MIN_LPC_ORDER; - psDec->psNLSF_CB = &silk_NLSF_CB_NB_MB; - } else { - psDec->LPC_order = MAX_LPC_ORDER; - psDec->psNLSF_CB = &silk_NLSF_CB_WB; - } - if( fs_kHz == 16 ) { - psDec->pitch_lag_low_bits_iCDF = silk_uniform8_iCDF; - } else if( fs_kHz == 12 ) { - psDec->pitch_lag_low_bits_iCDF = silk_uniform6_iCDF; - } else if( fs_kHz == 8 ) { - psDec->pitch_lag_low_bits_iCDF = silk_uniform4_iCDF; - } else { - /* unsupported sampling rate */ - silk_assert( 0 ); - } - psDec->first_frame_after_reset = 1; - psDec->lagPrev = 100; - psDec->LastGainIndex = 10; - psDec->prevSignalType = TYPE_NO_VOICE_ACTIVITY; - silk_memset( psDec->outBuf, 0, sizeof(psDec->outBuf)); - silk_memset( psDec->sLPC_Q14_buf, 0, sizeof(psDec->sLPC_Q14_buf) ); - } - - psDec->fs_kHz = fs_kHz; - psDec->frame_length = frame_length; - } - - /* Check that settings are valid */ - silk_assert( psDec->frame_length > 0 && psDec->frame_length <= MAX_FRAME_LENGTH ); - - return ret; -} - diff --git a/src/opus-1.0.2/silk/define.h b/src/opus-1.0.2/silk/define.h deleted file mode 100644 index f74f4869..00000000 --- a/src/opus-1.0.2/silk/define.h +++ /dev/null @@ -1,235 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifndef SILK_DEFINE_H -#define SILK_DEFINE_H - -#include "errors.h" -#include "typedef.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -/* Max number of encoder channels (1/2) */ -#define ENCODER_NUM_CHANNELS 2 -/* Number of decoder channels (1/2) */ -#define DECODER_NUM_CHANNELS 2 - -#define MAX_FRAMES_PER_PACKET 3 - -/* Limits on bitrate */ -#define MIN_TARGET_RATE_BPS 5000 -#define MAX_TARGET_RATE_BPS 80000 -#define TARGET_RATE_TAB_SZ 8 - -/* LBRR thresholds */ -#define LBRR_NB_MIN_RATE_BPS 12000 -#define LBRR_MB_MIN_RATE_BPS 14000 -#define LBRR_WB_MIN_RATE_BPS 16000 - -/* DTX settings */ -#define NB_SPEECH_FRAMES_BEFORE_DTX 10 /* eq 200 ms */ -#define MAX_CONSECUTIVE_DTX 20 /* eq 400 ms */ - -/* Maximum sampling frequency */ -#define MAX_FS_KHZ 16 -#define MAX_API_FS_KHZ 48 - -/* Signal types */ -#define TYPE_NO_VOICE_ACTIVITY 0 -#define TYPE_UNVOICED 1 -#define TYPE_VOICED 2 - -/* Conditional coding types */ -#define CODE_INDEPENDENTLY 0 -#define CODE_INDEPENDENTLY_NO_LTP_SCALING 1 -#define CODE_CONDITIONALLY 2 - -/* Settings for stereo processing */ -#define STEREO_QUANT_TAB_SIZE 16 -#define STEREO_QUANT_SUB_STEPS 5 -#define STEREO_INTERP_LEN_MS 8 /* must be even */ -#define STEREO_RATIO_SMOOTH_COEF 0.01 /* smoothing coef for signal norms and stereo width */ - -/* Range of pitch lag estimates */ -#define PITCH_EST_MIN_LAG_MS 2 /* 2 ms -> 500 Hz */ -#define PITCH_EST_MAX_LAG_MS 18 /* 18 ms -> 56 Hz */ - -/* Maximum number of subframes */ -#define MAX_NB_SUBFR 4 - -/* Number of samples per frame */ -#define LTP_MEM_LENGTH_MS 20 -#define SUB_FRAME_LENGTH_MS 5 -#define MAX_SUB_FRAME_LENGTH ( SUB_FRAME_LENGTH_MS * MAX_FS_KHZ ) -#define MAX_FRAME_LENGTH_MS ( SUB_FRAME_LENGTH_MS * MAX_NB_SUBFR ) -#define MAX_FRAME_LENGTH ( MAX_FRAME_LENGTH_MS * MAX_FS_KHZ ) - -/* Milliseconds of lookahead for pitch analysis */ -#define LA_PITCH_MS 2 -#define LA_PITCH_MAX ( LA_PITCH_MS * MAX_FS_KHZ ) - -/* Order of LPC used in find pitch */ -#define MAX_FIND_PITCH_LPC_ORDER 16 - -/* Length of LPC window used in find pitch */ -#define FIND_PITCH_LPC_WIN_MS ( 20 + (LA_PITCH_MS << 1) ) -#define FIND_PITCH_LPC_WIN_MS_2_SF ( 10 + (LA_PITCH_MS << 1) ) -#define FIND_PITCH_LPC_WIN_MAX ( FIND_PITCH_LPC_WIN_MS * MAX_FS_KHZ ) - -/* Milliseconds of lookahead for noise shape analysis */ -#define LA_SHAPE_MS 5 -#define LA_SHAPE_MAX ( LA_SHAPE_MS * MAX_FS_KHZ ) - -/* Maximum length of LPC window used in noise shape analysis */ -#define SHAPE_LPC_WIN_MAX ( 15 * MAX_FS_KHZ ) - -/* dB level of lowest gain quantization level */ -#define MIN_QGAIN_DB 2 -/* dB level of highest gain quantization level */ -#define MAX_QGAIN_DB 88 -/* Number of gain quantization levels */ -#define N_LEVELS_QGAIN 64 -/* Max increase in gain quantization index */ -#define MAX_DELTA_GAIN_QUANT 36 -/* Max decrease in gain quantization index */ -#define MIN_DELTA_GAIN_QUANT -4 - -/* Quantization offsets (multiples of 4) */ -#define OFFSET_VL_Q10 32 -#define OFFSET_VH_Q10 100 -#define OFFSET_UVL_Q10 100 -#define OFFSET_UVH_Q10 240 - -#define QUANT_LEVEL_ADJUST_Q10 80 - -/* Maximum numbers of iterations used to stabilize an LPC vector */ -#define MAX_LPC_STABILIZE_ITERATIONS 16 -#define MAX_PREDICTION_POWER_GAIN 1e4f -#define MAX_PREDICTION_POWER_GAIN_AFTER_RESET 1e2f - -#define MAX_LPC_ORDER 16 -#define MIN_LPC_ORDER 10 - -/* Find Pred Coef defines */ -#define LTP_ORDER 5 - -/* LTP quantization settings */ -#define NB_LTP_CBKS 3 - -/* Flag to use harmonic noise shaping */ -#define USE_HARM_SHAPING 1 - -/* Max LPC order of noise shaping filters */ -#define MAX_SHAPE_LPC_ORDER 16 - -#define HARM_SHAPE_FIR_TAPS 3 - -/* Maximum number of delayed decision states */ -#define MAX_DEL_DEC_STATES 4 - -#define LTP_BUF_LENGTH 512 -#define LTP_MASK ( LTP_BUF_LENGTH - 1 ) - -#define DECISION_DELAY 32 -#define DECISION_DELAY_MASK ( DECISION_DELAY - 1 ) - -/* Number of subframes for excitation entropy coding */ -#define SHELL_CODEC_FRAME_LENGTH 16 -#define LOG2_SHELL_CODEC_FRAME_LENGTH 4 -#define MAX_NB_SHELL_BLOCKS ( MAX_FRAME_LENGTH / SHELL_CODEC_FRAME_LENGTH ) - -/* Number of rate levels, for entropy coding of excitation */ -#define N_RATE_LEVELS 10 - -/* Maximum sum of pulses per shell coding frame */ -#define MAX_PULSES 16 - -#define MAX_MATRIX_SIZE MAX_LPC_ORDER /* Max of LPC Order and LTP order */ - -#if( MAX_LPC_ORDER > DECISION_DELAY ) -# define NSQ_LPC_BUF_LENGTH MAX_LPC_ORDER -#else -# define NSQ_LPC_BUF_LENGTH DECISION_DELAY -#endif - -/***************************/ -/* Voice activity detector */ -/***************************/ -#define VAD_N_BANDS 4 - -#define VAD_INTERNAL_SUBFRAMES_LOG2 2 -#define VAD_INTERNAL_SUBFRAMES ( 1 << VAD_INTERNAL_SUBFRAMES_LOG2 ) - -#define VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 1024 /* Must be < 4096 */ -#define VAD_NOISE_LEVELS_BIAS 50 - -/* Sigmoid settings */ -#define VAD_NEGATIVE_OFFSET_Q5 128 /* sigmoid is 0 at -128 */ -#define VAD_SNR_FACTOR_Q16 45000 - -/* smoothing for SNR measurement */ -#define VAD_SNR_SMOOTH_COEF_Q18 4096 - -/* Size of the piecewise linear cosine approximation table for the LSFs */ -#define LSF_COS_TAB_SZ_FIX 128 - -/******************/ -/* NLSF quantizer */ -/******************/ -#define NLSF_W_Q 2 -#define NLSF_VQ_MAX_VECTORS 32 -#define NLSF_VQ_MAX_SURVIVORS 32 -#define NLSF_QUANT_MAX_AMPLITUDE 4 -#define NLSF_QUANT_MAX_AMPLITUDE_EXT 10 -#define NLSF_QUANT_LEVEL_ADJ 0.1 -#define NLSF_QUANT_DEL_DEC_STATES_LOG2 2 -#define NLSF_QUANT_DEL_DEC_STATES ( 1 << NLSF_QUANT_DEL_DEC_STATES_LOG2 ) - -/* Transition filtering for mode switching */ -#define TRANSITION_TIME_MS 5120 /* 5120 = 64 * FRAME_LENGTH_MS * ( TRANSITION_INT_NUM - 1 ) = 64*(20*4)*/ -#define TRANSITION_NB 3 /* Hardcoded in tables */ -#define TRANSITION_NA 2 /* Hardcoded in tables */ -#define TRANSITION_INT_NUM 5 /* Hardcoded in tables */ -#define TRANSITION_FRAMES ( TRANSITION_TIME_MS / MAX_FRAME_LENGTH_MS ) -#define TRANSITION_INT_STEPS ( TRANSITION_FRAMES / ( TRANSITION_INT_NUM - 1 ) ) - -/* BWE factors to apply after packet loss */ -#define BWE_AFTER_LOSS_Q16 63570 - -/* Defines for CN generation */ -#define CNG_BUF_MASK_MAX 255 /* 2^floor(log2(MAX_FRAME_LENGTH))-1 */ -#define CNG_GAIN_SMTH_Q16 4634 /* 0.25^(1/4) */ -#define CNG_NLSF_SMTH_Q16 16348 /* 0.25 */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/opus-1.0.2/silk/enc_API.c b/src/opus-1.0.2/silk/enc_API.c deleted file mode 100644 index ec7915ce..00000000 --- a/src/opus-1.0.2/silk/enc_API.c +++ /dev/null @@ -1,538 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include "define.h" -#include "API.h" -#include "control.h" -#include "typedef.h" -#include "structs.h" -#include "tuning_parameters.h" -#ifdef FIXED_POINT -#include "main_FIX.h" -#else -#include "main_FLP.h" -#endif - -/***************************************/ -/* Read control structure from encoder */ -/***************************************/ -static opus_int silk_QueryEncoder( /* O Returns error code */ - const void *encState, /* I State */ - silk_EncControlStruct *encStatus /* O Encoder Status */ -); - -/****************************************/ -/* Encoder functions */ -/****************************************/ - -opus_int silk_Get_Encoder_Size( /* O Returns error code */ - opus_int *encSizeBytes /* O Number of bytes in SILK encoder state */ -) -{ - opus_int ret = SILK_NO_ERROR; - - *encSizeBytes = sizeof( silk_encoder ); - - return ret; -} - -/*************************/ -/* Init or Reset encoder */ -/*************************/ -opus_int silk_InitEncoder( /* O Returns error code */ - void *encState, /* I/O State */ - silk_EncControlStruct *encStatus /* O Encoder Status */ -) -{ - silk_encoder *psEnc; - opus_int n, ret = SILK_NO_ERROR; - - psEnc = (silk_encoder *)encState; - - /* Reset encoder */ - silk_memset( psEnc, 0, sizeof( silk_encoder ) ); - for( n = 0; n < ENCODER_NUM_CHANNELS; n++ ) { - if( ret += silk_init_encoder( &psEnc->state_Fxx[ n ] ) ) { - silk_assert( 0 ); - } - } - - psEnc->nChannelsAPI = 1; - psEnc->nChannelsInternal = 1; - - /* Read control structure */ - if( ret += silk_QueryEncoder( encState, encStatus ) ) { - silk_assert( 0 ); - } - - return ret; -} - -/***************************************/ -/* Read control structure from encoder */ -/***************************************/ -static opus_int silk_QueryEncoder( /* O Returns error code */ - const void *encState, /* I State */ - silk_EncControlStruct *encStatus /* O Encoder Status */ -) -{ - opus_int ret = SILK_NO_ERROR; - silk_encoder_state_Fxx *state_Fxx; - silk_encoder *psEnc = (silk_encoder *)encState; - - state_Fxx = psEnc->state_Fxx; - - encStatus->nChannelsAPI = psEnc->nChannelsAPI; - encStatus->nChannelsInternal = psEnc->nChannelsInternal; - encStatus->API_sampleRate = state_Fxx[ 0 ].sCmn.API_fs_Hz; - encStatus->maxInternalSampleRate = state_Fxx[ 0 ].sCmn.maxInternal_fs_Hz; - encStatus->minInternalSampleRate = state_Fxx[ 0 ].sCmn.minInternal_fs_Hz; - encStatus->desiredInternalSampleRate = state_Fxx[ 0 ].sCmn.desiredInternal_fs_Hz; - encStatus->payloadSize_ms = state_Fxx[ 0 ].sCmn.PacketSize_ms; - encStatus->bitRate = state_Fxx[ 0 ].sCmn.TargetRate_bps; - encStatus->packetLossPercentage = state_Fxx[ 0 ].sCmn.PacketLoss_perc; - encStatus->complexity = state_Fxx[ 0 ].sCmn.Complexity; - encStatus->useInBandFEC = state_Fxx[ 0 ].sCmn.useInBandFEC; - encStatus->useDTX = state_Fxx[ 0 ].sCmn.useDTX; - encStatus->useCBR = state_Fxx[ 0 ].sCmn.useCBR; - encStatus->internalSampleRate = silk_SMULBB( state_Fxx[ 0 ].sCmn.fs_kHz, 1000 ); - encStatus->allowBandwidthSwitch = state_Fxx[ 0 ].sCmn.allow_bandwidth_switch; - encStatus->inWBmodeWithoutVariableLP = state_Fxx[ 0 ].sCmn.fs_kHz == 16 && state_Fxx[ 0 ].sCmn.sLP.mode == 0; - - return ret; -} - - -/**************************/ -/* Encode frame with Silk */ -/**************************/ -/* Note: if prefillFlag is set, the input must contain 10 ms of audio, irrespective of what */ -/* encControl->payloadSize_ms is set to */ -opus_int silk_Encode( /* O Returns error code */ - void *encState, /* I/O State */ - silk_EncControlStruct *encControl, /* I Control status */ - const opus_int16 *samplesIn, /* I Speech sample input vector */ - opus_int nSamplesIn, /* I Number of samples in input vector */ - ec_enc *psRangeEnc, /* I/O Compressor data structure */ - opus_int32 *nBytesOut, /* I/O Number of bytes in payload (input: Max bytes) */ - const opus_int prefillFlag /* I Flag to indicate prefilling buffers no coding */ -) -{ - opus_int n, i, nBits, flags, tmp_payloadSize_ms = 0, tmp_complexity = 0, ret = 0; - opus_int nSamplesToBuffer, nBlocksOf10ms, nSamplesFromInput = 0; - opus_int speech_act_thr_for_switch_Q8; - opus_int32 TargetRate_bps, MStargetRates_bps[ 2 ], channelRate_bps, LBRR_symbol, sum; - silk_encoder *psEnc = ( silk_encoder * )encState; - opus_int16 buf[ MAX_FRAME_LENGTH_MS * MAX_API_FS_KHZ ]; - opus_int transition, curr_block, tot_blocks; - - psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded = psEnc->state_Fxx[ 1 ].sCmn.nFramesEncoded = 0; - - /* Check values in encoder control structure */ - if( ( ret = check_control_input( encControl ) != 0 ) ) { - silk_assert( 0 ); - return ret; - } - - encControl->switchReady = 0; - - if( encControl->nChannelsInternal > psEnc->nChannelsInternal ) { - /* Mono -> Stereo transition: init state of second channel and stereo state */ - ret += silk_init_encoder( &psEnc->state_Fxx[ 1 ] ); - silk_memset( psEnc->sStereo.pred_prev_Q13, 0, sizeof( psEnc->sStereo.pred_prev_Q13 ) ); - silk_memset( psEnc->sStereo.sSide, 0, sizeof( psEnc->sStereo.sSide ) ); - psEnc->sStereo.mid_side_amp_Q0[ 0 ] = 0; - psEnc->sStereo.mid_side_amp_Q0[ 1 ] = 1; - psEnc->sStereo.mid_side_amp_Q0[ 2 ] = 0; - psEnc->sStereo.mid_side_amp_Q0[ 3 ] = 1; - psEnc->sStereo.width_prev_Q14 = 0; - psEnc->sStereo.smth_width_Q14 = SILK_FIX_CONST( 1, 14 ); - if( psEnc->nChannelsAPI == 2 ) { - silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state, &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, sizeof( silk_resampler_state_struct ) ); - silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.In_HP_State, &psEnc->state_Fxx[ 0 ].sCmn.In_HP_State, sizeof( psEnc->state_Fxx[ 1 ].sCmn.In_HP_State ) ); - } - } - - transition = (encControl->payloadSize_ms != psEnc->state_Fxx[ 0 ].sCmn.PacketSize_ms) || (psEnc->nChannelsInternal != encControl->nChannelsInternal); - - psEnc->nChannelsAPI = encControl->nChannelsAPI; - psEnc->nChannelsInternal = encControl->nChannelsInternal; - - nBlocksOf10ms = silk_DIV32( 100 * nSamplesIn, encControl->API_sampleRate ); - tot_blocks = ( nBlocksOf10ms > 1 ) ? nBlocksOf10ms >> 1 : 1; - curr_block = 0; - if( prefillFlag ) { - /* Only accept input length of 10 ms */ - if( nBlocksOf10ms != 1 ) { - ret = SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES; - silk_assert( 0 ); - return ret; - } - /* Reset Encoder */ - for( n = 0; n < encControl->nChannelsInternal; n++ ) { - if( (ret = silk_init_encoder( &psEnc->state_Fxx[ n ] ) ) != 0 ) { - silk_assert( 0 ); - } - } - tmp_payloadSize_ms = encControl->payloadSize_ms; - encControl->payloadSize_ms = 10; - tmp_complexity = encControl->complexity; - encControl->complexity = 0; - for( n = 0; n < encControl->nChannelsInternal; n++ ) { - psEnc->state_Fxx[ n ].sCmn.controlled_since_last_payload = 0; - psEnc->state_Fxx[ n ].sCmn.prefillFlag = 1; - } - } else { - /* Only accept input lengths that are a multiple of 10 ms */ - if( nBlocksOf10ms * encControl->API_sampleRate != 100 * nSamplesIn || nSamplesIn < 0 ) { - ret = SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES; - silk_assert( 0 ); - return ret; - } - /* Make sure no more than one packet can be produced */ - if( 1000 * (opus_int32)nSamplesIn > encControl->payloadSize_ms * encControl->API_sampleRate ) { - ret = SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES; - silk_assert( 0 ); - return ret; - } - } - - TargetRate_bps = silk_RSHIFT32( encControl->bitRate, encControl->nChannelsInternal - 1 ); - for( n = 0; n < encControl->nChannelsInternal; n++ ) { - /* Force the side channel to the same rate as the mid */ - opus_int force_fs_kHz = (n==1) ? psEnc->state_Fxx[0].sCmn.fs_kHz : 0; - if( ( ret = silk_control_encoder( &psEnc->state_Fxx[ n ], encControl, TargetRate_bps, psEnc->allowBandwidthSwitch, n, force_fs_kHz ) ) != 0 ) { - silk_assert( 0 ); - return ret; - } - if( psEnc->state_Fxx[n].sCmn.first_frame_after_reset || transition ) { - for( i = 0; i < psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket; i++ ) { - psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i ] = 0; - } - } - psEnc->state_Fxx[ n ].sCmn.inDTX = psEnc->state_Fxx[ n ].sCmn.useDTX; - } - silk_assert( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 0 ].sCmn.fs_kHz == psEnc->state_Fxx[ 1 ].sCmn.fs_kHz ); - - /* Input buffering/resampling and encoding */ - while( 1 ) { - nSamplesToBuffer = psEnc->state_Fxx[ 0 ].sCmn.frame_length - psEnc->state_Fxx[ 0 ].sCmn.inputBufIx; - nSamplesToBuffer = silk_min( nSamplesToBuffer, 10 * nBlocksOf10ms * psEnc->state_Fxx[ 0 ].sCmn.fs_kHz ); - nSamplesFromInput = silk_DIV32_16( nSamplesToBuffer * psEnc->state_Fxx[ 0 ].sCmn.API_fs_Hz, psEnc->state_Fxx[ 0 ].sCmn.fs_kHz * 1000 ); - /* Resample and write to buffer */ - if( encControl->nChannelsAPI == 2 && encControl->nChannelsInternal == 2 ) { - opus_int id = psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded; - for( n = 0; n < nSamplesFromInput; n++ ) { - buf[ n ] = samplesIn[ 2 * n ]; - } - /* Making sure to start both resamplers from the same state when switching from mono to stereo */ - if( psEnc->nPrevChannelsInternal == 1 && id==0 ) { - silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state, &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, sizeof(psEnc->state_Fxx[ 1 ].sCmn.resampler_state)); - } - - ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, - &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput ); - psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer; - - nSamplesToBuffer = psEnc->state_Fxx[ 1 ].sCmn.frame_length - psEnc->state_Fxx[ 1 ].sCmn.inputBufIx; - nSamplesToBuffer = silk_min( nSamplesToBuffer, 10 * nBlocksOf10ms * psEnc->state_Fxx[ 1 ].sCmn.fs_kHz ); - for( n = 0; n < nSamplesFromInput; n++ ) { - buf[ n ] = samplesIn[ 2 * n + 1 ]; - } - ret += silk_resampler( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state, - &psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput ); - - psEnc->state_Fxx[ 1 ].sCmn.inputBufIx += nSamplesToBuffer; - } else if( encControl->nChannelsAPI == 2 && encControl->nChannelsInternal == 1 ) { - /* Combine left and right channels before resampling */ - for( n = 0; n < nSamplesFromInput; n++ ) { - sum = samplesIn[ 2 * n ] + samplesIn[ 2 * n + 1 ]; - buf[ n ] = (opus_int16)silk_RSHIFT_ROUND( sum, 1 ); - } - ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, - &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput ); - /* On the first mono frame, average the results for the two resampler states */ - if( psEnc->nPrevChannelsInternal == 2 && psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == 0 ) { - ret += silk_resampler( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state, - &psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput ); - for( n = 0; n < psEnc->state_Fxx[ 0 ].sCmn.frame_length; n++ ) { - psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx+n+2 ] = - silk_RSHIFT(psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx+n+2 ] - + psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx+n+2 ], 1); - } - } - psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer; - } else { - silk_assert( encControl->nChannelsAPI == 1 && encControl->nChannelsInternal == 1 ); - silk_memcpy(buf, samplesIn, nSamplesFromInput*sizeof(opus_int16)); - ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, - &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput ); - psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer; - } - - samplesIn += nSamplesFromInput * encControl->nChannelsAPI; - nSamplesIn -= nSamplesFromInput; - - /* Default */ - psEnc->allowBandwidthSwitch = 0; - - /* Silk encoder */ - if( psEnc->state_Fxx[ 0 ].sCmn.inputBufIx >= psEnc->state_Fxx[ 0 ].sCmn.frame_length ) { - /* Enough data in input buffer, so encode */ - silk_assert( psEnc->state_Fxx[ 0 ].sCmn.inputBufIx == psEnc->state_Fxx[ 0 ].sCmn.frame_length ); - silk_assert( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 1 ].sCmn.inputBufIx == psEnc->state_Fxx[ 1 ].sCmn.frame_length ); - - /* Deal with LBRR data */ - if( psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == 0 && !prefillFlag ) { - /* Create space at start of payload for VAD and FEC flags */ - opus_uint8 iCDF[ 2 ] = { 0, 0 }; - iCDF[ 0 ] = 256 - silk_RSHIFT( 256, ( psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket + 1 ) * encControl->nChannelsInternal ); - ec_enc_icdf( psRangeEnc, 0, iCDF, 8 ); - - /* Encode any LBRR data from previous packet */ - /* Encode LBRR flags */ - for( n = 0; n < encControl->nChannelsInternal; n++ ) { - LBRR_symbol = 0; - for( i = 0; i < psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket; i++ ) { - LBRR_symbol |= silk_LSHIFT( psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i ], i ); - } - psEnc->state_Fxx[ n ].sCmn.LBRR_flag = LBRR_symbol > 0 ? 1 : 0; - if( LBRR_symbol && psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket > 1 ) { - ec_enc_icdf( psRangeEnc, LBRR_symbol - 1, silk_LBRR_flags_iCDF_ptr[ psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket - 2 ], 8 ); - } - } - - /* Code LBRR indices and excitation signals */ - for( i = 0; i < psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket; i++ ) { - for( n = 0; n < encControl->nChannelsInternal; n++ ) { - if( psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i ] ) { - opus_int condCoding; - - if( encControl->nChannelsInternal == 2 && n == 0 ) { - silk_stereo_encode_pred( psRangeEnc, psEnc->sStereo.predIx[ i ] ); - /* For LBRR data there's no need to code the mid-only flag if the side-channel LBRR flag is set */ - if( psEnc->state_Fxx[ 1 ].sCmn.LBRR_flags[ i ] == 0 ) { - silk_stereo_encode_mid_only( psRangeEnc, psEnc->sStereo.mid_only_flags[ i ] ); - } - } - /* Use conditional coding if previous frame available */ - if( i > 0 && psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i - 1 ] ) { - condCoding = CODE_CONDITIONALLY; - } else { - condCoding = CODE_INDEPENDENTLY; - } - silk_encode_indices( &psEnc->state_Fxx[ n ].sCmn, psRangeEnc, i, 1, condCoding ); - silk_encode_pulses( psRangeEnc, psEnc->state_Fxx[ n ].sCmn.indices_LBRR[i].signalType, psEnc->state_Fxx[ n ].sCmn.indices_LBRR[i].quantOffsetType, - psEnc->state_Fxx[ n ].sCmn.pulses_LBRR[ i ], psEnc->state_Fxx[ n ].sCmn.frame_length ); - } - } - } - - /* Reset LBRR flags */ - for( n = 0; n < encControl->nChannelsInternal; n++ ) { - silk_memset( psEnc->state_Fxx[ n ].sCmn.LBRR_flags, 0, sizeof( psEnc->state_Fxx[ n ].sCmn.LBRR_flags ) ); - } - } - - silk_HP_variable_cutoff( psEnc->state_Fxx ); - - /* Total target bits for packet */ - nBits = silk_DIV32_16( silk_MUL( encControl->bitRate, encControl->payloadSize_ms ), 1000 ); - /* Subtract half of the bits already used */ - if( !prefillFlag ) { - nBits -= ec_tell( psRangeEnc ) >> 1; - } - /* Divide by number of uncoded frames left in packet */ - nBits = silk_DIV32_16( nBits, psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket - psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ); - /* Convert to bits/second */ - if( encControl->payloadSize_ms == 10 ) { - TargetRate_bps = silk_SMULBB( nBits, 100 ); - } else { - TargetRate_bps = silk_SMULBB( nBits, 50 ); - } - /* Subtract fraction of bits in excess of target in previous packets */ - TargetRate_bps -= silk_DIV32_16( silk_MUL( psEnc->nBitsExceeded, 1000 ), BITRESERVOIR_DECAY_TIME_MS ); - /* Never exceed input bitrate */ - TargetRate_bps = silk_LIMIT( TargetRate_bps, encControl->bitRate, 5000 ); - - /* Convert Left/Right to Mid/Side */ - if( encControl->nChannelsInternal == 2 ) { - silk_stereo_LR_to_MS( &psEnc->sStereo, &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ 2 ], &psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ 2 ], - psEnc->sStereo.predIx[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ], &psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ], - MStargetRates_bps, TargetRate_bps, psEnc->state_Fxx[ 0 ].sCmn.speech_activity_Q8, encControl->toMono, - psEnc->state_Fxx[ 0 ].sCmn.fs_kHz, psEnc->state_Fxx[ 0 ].sCmn.frame_length ); - if( psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] == 0 ) { - /* Reset side channel encoder memory for first frame with side coding */ - if( psEnc->prev_decode_only_middle == 1 ) { - silk_memset( &psEnc->state_Fxx[ 1 ].sShape, 0, sizeof( psEnc->state_Fxx[ 1 ].sShape ) ); - silk_memset( &psEnc->state_Fxx[ 1 ].sPrefilt, 0, sizeof( psEnc->state_Fxx[ 1 ].sPrefilt ) ); - silk_memset( &psEnc->state_Fxx[ 1 ].sCmn.sNSQ, 0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.sNSQ ) ); - silk_memset( psEnc->state_Fxx[ 1 ].sCmn.prev_NLSFq_Q15, 0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.prev_NLSFq_Q15 ) ); - silk_memset( &psEnc->state_Fxx[ 1 ].sCmn.sLP.In_LP_State, 0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.sLP.In_LP_State ) ); - psEnc->state_Fxx[ 1 ].sCmn.prevLag = 100; - psEnc->state_Fxx[ 1 ].sCmn.sNSQ.lagPrev = 100; - psEnc->state_Fxx[ 1 ].sShape.LastGainIndex = 10; - psEnc->state_Fxx[ 1 ].sCmn.prevSignalType = TYPE_NO_VOICE_ACTIVITY; - psEnc->state_Fxx[ 1 ].sCmn.sNSQ.prev_gain_Q16 = 65536; - psEnc->state_Fxx[ 1 ].sCmn.first_frame_after_reset = 1; - } - silk_encode_do_VAD_Fxx( &psEnc->state_Fxx[ 1 ] ); - } else { - psEnc->state_Fxx[ 1 ].sCmn.VAD_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] = 0; - } - if( !prefillFlag ) { - silk_stereo_encode_pred( psRangeEnc, psEnc->sStereo.predIx[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] ); - if( psEnc->state_Fxx[ 1 ].sCmn.VAD_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] == 0 ) { - silk_stereo_encode_mid_only( psRangeEnc, psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] ); - } - } - } else { - /* Buffering */ - silk_memcpy( psEnc->state_Fxx[ 0 ].sCmn.inputBuf, psEnc->sStereo.sMid, 2 * sizeof( opus_int16 ) ); - silk_memcpy( psEnc->sStereo.sMid, &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.frame_length ], 2 * sizeof( opus_int16 ) ); - } - silk_encode_do_VAD_Fxx( &psEnc->state_Fxx[ 0 ] ); - - /* Encode */ - for( n = 0; n < encControl->nChannelsInternal; n++ ) { - opus_int maxBits, useCBR; - - /* Handling rate constraints */ - maxBits = encControl->maxBits; - if( tot_blocks == 2 && curr_block == 0 ) { - maxBits = maxBits * 3 / 5; - } else if( tot_blocks == 3 ) { - if( curr_block == 0 ) { - maxBits = maxBits * 2 / 5; - } else if( curr_block == 1 ) { - maxBits = maxBits * 3 / 4; - } - } - useCBR = encControl->useCBR && curr_block == tot_blocks - 1; - - if( encControl->nChannelsInternal == 1 ) { - channelRate_bps = TargetRate_bps; - } else { - channelRate_bps = MStargetRates_bps[ n ]; - if( n == 0 && MStargetRates_bps[ 1 ] > 0 ) { - useCBR = 0; - /* Give mid up to 1/2 of the max bits for that frame */ - maxBits -= encControl->maxBits / ( tot_blocks * 2 ); - } - } - - if( channelRate_bps > 0 ) { - opus_int condCoding; - - silk_control_SNR( &psEnc->state_Fxx[ n ].sCmn, channelRate_bps ); - - /* Use independent coding if no previous frame available */ - if( psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded - n <= 0 ) { - condCoding = CODE_INDEPENDENTLY; - } else if( n > 0 && psEnc->prev_decode_only_middle ) { - /* If we skipped a side frame in this packet, we don't - need LTP scaling; the LTP state is well-defined. */ - condCoding = CODE_INDEPENDENTLY_NO_LTP_SCALING; - } else { - condCoding = CODE_CONDITIONALLY; - } - if( ( ret = silk_encode_frame_Fxx( &psEnc->state_Fxx[ n ], nBytesOut, psRangeEnc, condCoding, maxBits, useCBR ) ) != 0 ) { - silk_assert( 0 ); - } - } - psEnc->state_Fxx[ n ].sCmn.controlled_since_last_payload = 0; - psEnc->state_Fxx[ n ].sCmn.inputBufIx = 0; - psEnc->state_Fxx[ n ].sCmn.nFramesEncoded++; - } - psEnc->prev_decode_only_middle = psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded - 1 ]; - - /* Insert VAD and FEC flags at beginning of bitstream */ - if( *nBytesOut > 0 && psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket) { - flags = 0; - for( n = 0; n < encControl->nChannelsInternal; n++ ) { - for( i = 0; i < psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket; i++ ) { - flags = silk_LSHIFT( flags, 1 ); - flags |= psEnc->state_Fxx[ n ].sCmn.VAD_flags[ i ]; - } - flags = silk_LSHIFT( flags, 1 ); - flags |= psEnc->state_Fxx[ n ].sCmn.LBRR_flag; - } - if( !prefillFlag ) { - ec_enc_patch_initial_bits( psRangeEnc, flags, ( psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket + 1 ) * encControl->nChannelsInternal ); - } - - /* Return zero bytes if all channels DTXed */ - if( psEnc->state_Fxx[ 0 ].sCmn.inDTX && ( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 1 ].sCmn.inDTX ) ) { - *nBytesOut = 0; - } - - psEnc->nBitsExceeded += *nBytesOut * 8; - psEnc->nBitsExceeded -= silk_DIV32_16( silk_MUL( encControl->bitRate, encControl->payloadSize_ms ), 1000 ); - psEnc->nBitsExceeded = silk_LIMIT( psEnc->nBitsExceeded, 0, 10000 ); - - /* Update flag indicating if bandwidth switching is allowed */ - speech_act_thr_for_switch_Q8 = silk_SMLAWB( SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ), - SILK_FIX_CONST( ( 1 - SPEECH_ACTIVITY_DTX_THRES ) / MAX_BANDWIDTH_SWITCH_DELAY_MS, 16 + 8 ), psEnc->timeSinceSwitchAllowed_ms ); - if( psEnc->state_Fxx[ 0 ].sCmn.speech_activity_Q8 < speech_act_thr_for_switch_Q8 ) { - psEnc->allowBandwidthSwitch = 1; - psEnc->timeSinceSwitchAllowed_ms = 0; - } else { - psEnc->allowBandwidthSwitch = 0; - psEnc->timeSinceSwitchAllowed_ms += encControl->payloadSize_ms; - } - } - - if( nSamplesIn == 0 ) { - break; - } - } else { - break; - } - curr_block++; - } - - psEnc->nPrevChannelsInternal = encControl->nChannelsInternal; - - encControl->allowBandwidthSwitch = psEnc->allowBandwidthSwitch; - encControl->inWBmodeWithoutVariableLP = psEnc->state_Fxx[ 0 ].sCmn.fs_kHz == 16 && psEnc->state_Fxx[ 0 ].sCmn.sLP.mode == 0; - encControl->internalSampleRate = silk_SMULBB( psEnc->state_Fxx[ 0 ].sCmn.fs_kHz, 1000 ); - encControl->stereoWidth_Q14 = encControl->toMono ? 0 : psEnc->sStereo.smth_width_Q14; - if( prefillFlag ) { - encControl->payloadSize_ms = tmp_payloadSize_ms; - encControl->complexity = tmp_complexity; - for( n = 0; n < encControl->nChannelsInternal; n++ ) { - psEnc->state_Fxx[ n ].sCmn.controlled_since_last_payload = 0; - psEnc->state_Fxx[ n ].sCmn.prefillFlag = 0; - } - } - - return ret; -} - diff --git a/src/opus-1.0.2/silk/encode_indices.c b/src/opus-1.0.2/silk/encode_indices.c deleted file mode 100644 index 91e28aa9..00000000 --- a/src/opus-1.0.2/silk/encode_indices.c +++ /dev/null @@ -1,181 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main.h" - -/* Encode side-information parameters to payload */ -void silk_encode_indices( - silk_encoder_state *psEncC, /* I/O Encoder state */ - ec_enc *psRangeEnc, /* I/O Compressor data structure */ - opus_int FrameIndex, /* I Frame number */ - opus_int encode_LBRR, /* I Flag indicating LBRR data is being encoded */ - opus_int condCoding /* I The type of conditional coding to use */ -) -{ - opus_int i, k, typeOffset; - opus_int encode_absolute_lagIndex, delta_lagIndex; - opus_int16 ec_ix[ MAX_LPC_ORDER ]; - opus_uint8 pred_Q8[ MAX_LPC_ORDER ]; - const SideInfoIndices *psIndices; - - if( encode_LBRR ) { - psIndices = &psEncC->indices_LBRR[ FrameIndex ]; - } else { - psIndices = &psEncC->indices; - } - - /*******************************************/ - /* Encode signal type and quantizer offset */ - /*******************************************/ - typeOffset = 2 * psIndices->signalType + psIndices->quantOffsetType; - silk_assert( typeOffset >= 0 && typeOffset < 6 ); - silk_assert( encode_LBRR == 0 || typeOffset >= 2 ); - if( encode_LBRR || typeOffset >= 2 ) { - ec_enc_icdf( psRangeEnc, typeOffset - 2, silk_type_offset_VAD_iCDF, 8 ); - } else { - ec_enc_icdf( psRangeEnc, typeOffset, silk_type_offset_no_VAD_iCDF, 8 ); - } - - /****************/ - /* Encode gains */ - /****************/ - /* first subframe */ - if( condCoding == CODE_CONDITIONALLY ) { - /* conditional coding */ - silk_assert( psIndices->GainsIndices[ 0 ] >= 0 && psIndices->GainsIndices[ 0 ] < MAX_DELTA_GAIN_QUANT - MIN_DELTA_GAIN_QUANT + 1 ); - ec_enc_icdf( psRangeEnc, psIndices->GainsIndices[ 0 ], silk_delta_gain_iCDF, 8 ); - } else { - /* independent coding, in two stages: MSB bits followed by 3 LSBs */ - silk_assert( psIndices->GainsIndices[ 0 ] >= 0 && psIndices->GainsIndices[ 0 ] < N_LEVELS_QGAIN ); - ec_enc_icdf( psRangeEnc, silk_RSHIFT( psIndices->GainsIndices[ 0 ], 3 ), silk_gain_iCDF[ psIndices->signalType ], 8 ); - ec_enc_icdf( psRangeEnc, psIndices->GainsIndices[ 0 ] & 7, silk_uniform8_iCDF, 8 ); - } - - /* remaining subframes */ - for( i = 1; i < psEncC->nb_subfr; i++ ) { - silk_assert( psIndices->GainsIndices[ i ] >= 0 && psIndices->GainsIndices[ i ] < MAX_DELTA_GAIN_QUANT - MIN_DELTA_GAIN_QUANT + 1 ); - ec_enc_icdf( psRangeEnc, psIndices->GainsIndices[ i ], silk_delta_gain_iCDF, 8 ); - } - - /****************/ - /* Encode NLSFs */ - /****************/ - ec_enc_icdf( psRangeEnc, psIndices->NLSFIndices[ 0 ], &psEncC->psNLSF_CB->CB1_iCDF[ ( psIndices->signalType >> 1 ) * psEncC->psNLSF_CB->nVectors ], 8 ); - silk_NLSF_unpack( ec_ix, pred_Q8, psEncC->psNLSF_CB, psIndices->NLSFIndices[ 0 ] ); - silk_assert( psEncC->psNLSF_CB->order == psEncC->predictLPCOrder ); - for( i = 0; i < psEncC->psNLSF_CB->order; i++ ) { - if( psIndices->NLSFIndices[ i+1 ] >= NLSF_QUANT_MAX_AMPLITUDE ) { - ec_enc_icdf( psRangeEnc, 2 * NLSF_QUANT_MAX_AMPLITUDE, &psEncC->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 ); - ec_enc_icdf( psRangeEnc, psIndices->NLSFIndices[ i+1 ] - NLSF_QUANT_MAX_AMPLITUDE, silk_NLSF_EXT_iCDF, 8 ); - } else if( psIndices->NLSFIndices[ i+1 ] <= -NLSF_QUANT_MAX_AMPLITUDE ) { - ec_enc_icdf( psRangeEnc, 0, &psEncC->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 ); - ec_enc_icdf( psRangeEnc, -psIndices->NLSFIndices[ i+1 ] - NLSF_QUANT_MAX_AMPLITUDE, silk_NLSF_EXT_iCDF, 8 ); - } else { - ec_enc_icdf( psRangeEnc, psIndices->NLSFIndices[ i+1 ] + NLSF_QUANT_MAX_AMPLITUDE, &psEncC->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 ); - } - } - - /* Encode NLSF interpolation factor */ - if( psEncC->nb_subfr == MAX_NB_SUBFR ) { - silk_assert( psIndices->NLSFInterpCoef_Q2 >= 0 && psIndices->NLSFInterpCoef_Q2 < 5 ); - ec_enc_icdf( psRangeEnc, psIndices->NLSFInterpCoef_Q2, silk_NLSF_interpolation_factor_iCDF, 8 ); - } - - if( psIndices->signalType == TYPE_VOICED ) - { - /*********************/ - /* Encode pitch lags */ - /*********************/ - /* lag index */ - encode_absolute_lagIndex = 1; - if( condCoding == CODE_CONDITIONALLY && psEncC->ec_prevSignalType == TYPE_VOICED ) { - /* Delta Encoding */ - delta_lagIndex = psIndices->lagIndex - psEncC->ec_prevLagIndex; - if( delta_lagIndex < -8 || delta_lagIndex > 11 ) { - delta_lagIndex = 0; - } else { - delta_lagIndex = delta_lagIndex + 9; - encode_absolute_lagIndex = 0; /* Only use delta */ - } - silk_assert( delta_lagIndex >= 0 && delta_lagIndex < 21 ); - ec_enc_icdf( psRangeEnc, delta_lagIndex, silk_pitch_delta_iCDF, 8 ); - } - if( encode_absolute_lagIndex ) { - /* Absolute encoding */ - opus_int32 pitch_high_bits, pitch_low_bits; - pitch_high_bits = silk_DIV32_16( psIndices->lagIndex, silk_RSHIFT( psEncC->fs_kHz, 1 ) ); - pitch_low_bits = psIndices->lagIndex - silk_SMULBB( pitch_high_bits, silk_RSHIFT( psEncC->fs_kHz, 1 ) ); - silk_assert( pitch_low_bits < psEncC->fs_kHz / 2 ); - silk_assert( pitch_high_bits < 32 ); - ec_enc_icdf( psRangeEnc, pitch_high_bits, silk_pitch_lag_iCDF, 8 ); - ec_enc_icdf( psRangeEnc, pitch_low_bits, psEncC->pitch_lag_low_bits_iCDF, 8 ); - } - psEncC->ec_prevLagIndex = psIndices->lagIndex; - - /* Countour index */ - silk_assert( psIndices->contourIndex >= 0 ); - silk_assert( ( psIndices->contourIndex < 34 && psEncC->fs_kHz > 8 && psEncC->nb_subfr == 4 ) || - ( psIndices->contourIndex < 11 && psEncC->fs_kHz == 8 && psEncC->nb_subfr == 4 ) || - ( psIndices->contourIndex < 12 && psEncC->fs_kHz > 8 && psEncC->nb_subfr == 2 ) || - ( psIndices->contourIndex < 3 && psEncC->fs_kHz == 8 && psEncC->nb_subfr == 2 ) ); - ec_enc_icdf( psRangeEnc, psIndices->contourIndex, psEncC->pitch_contour_iCDF, 8 ); - - /********************/ - /* Encode LTP gains */ - /********************/ - /* PERIndex value */ - silk_assert( psIndices->PERIndex >= 0 && psIndices->PERIndex < 3 ); - ec_enc_icdf( psRangeEnc, psIndices->PERIndex, silk_LTP_per_index_iCDF, 8 ); - - /* Codebook Indices */ - for( k = 0; k < psEncC->nb_subfr; k++ ) { - silk_assert( psIndices->LTPIndex[ k ] >= 0 && psIndices->LTPIndex[ k ] < ( 8 << psIndices->PERIndex ) ); - ec_enc_icdf( psRangeEnc, psIndices->LTPIndex[ k ], silk_LTP_gain_iCDF_ptrs[ psIndices->PERIndex ], 8 ); - } - - /**********************/ - /* Encode LTP scaling */ - /**********************/ - if( condCoding == CODE_INDEPENDENTLY ) { - silk_assert( psIndices->LTP_scaleIndex >= 0 && psIndices->LTP_scaleIndex < 3 ); - ec_enc_icdf( psRangeEnc, psIndices->LTP_scaleIndex, silk_LTPscale_iCDF, 8 ); - } - silk_assert( !condCoding || psIndices->LTP_scaleIndex == 0 ); - } - - psEncC->ec_prevSignalType = psIndices->signalType; - - /***************/ - /* Encode seed */ - /***************/ - silk_assert( psIndices->Seed >= 0 && psIndices->Seed < 4 ); - ec_enc_icdf( psRangeEnc, psIndices->Seed, silk_uniform4_iCDF, 8 ); -} diff --git a/src/opus-1.0.2/silk/encode_pulses.c b/src/opus-1.0.2/silk/encode_pulses.c deleted file mode 100644 index b01b5853..00000000 --- a/src/opus-1.0.2/silk/encode_pulses.c +++ /dev/null @@ -1,199 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main.h" - -/*********************************************/ -/* Encode quantization indices of excitation */ -/*********************************************/ - -static inline opus_int combine_and_check( /* return ok */ - opus_int *pulses_comb, /* O */ - const opus_int *pulses_in, /* I */ - opus_int max_pulses, /* I max value for sum of pulses */ - opus_int len /* I number of output values */ -) -{ - opus_int k, sum; - - for( k = 0; k < len; k++ ) { - sum = pulses_in[ 2 * k ] + pulses_in[ 2 * k + 1 ]; - if( sum > max_pulses ) { - return 1; - } - pulses_comb[ k ] = sum; - } - - return 0; -} - -/* Encode quantization indices of excitation */ -void silk_encode_pulses( - ec_enc *psRangeEnc, /* I/O compressor data structure */ - const opus_int signalType, /* I Signal type */ - const opus_int quantOffsetType, /* I quantOffsetType */ - opus_int8 pulses[], /* I quantization indices */ - const opus_int frame_length /* I Frame length */ -) -{ - opus_int i, k, j, iter, bit, nLS, scale_down, RateLevelIndex = 0; - opus_int32 abs_q, minSumBits_Q5, sumBits_Q5; - opus_int abs_pulses[ MAX_FRAME_LENGTH ]; - opus_int sum_pulses[ MAX_NB_SHELL_BLOCKS ]; - opus_int nRshifts[ MAX_NB_SHELL_BLOCKS ]; - opus_int pulses_comb[ 8 ]; - opus_int *abs_pulses_ptr; - const opus_int8 *pulses_ptr; - const opus_uint8 *cdf_ptr; - const opus_uint8 *nBits_ptr; - - silk_memset( pulses_comb, 0, 8 * sizeof( opus_int ) ); /* Fixing Valgrind reported problem*/ - - /****************************/ - /* Prepare for shell coding */ - /****************************/ - /* Calculate number of shell blocks */ - silk_assert( 1 << LOG2_SHELL_CODEC_FRAME_LENGTH == SHELL_CODEC_FRAME_LENGTH ); - iter = silk_RSHIFT( frame_length, LOG2_SHELL_CODEC_FRAME_LENGTH ); - if( iter * SHELL_CODEC_FRAME_LENGTH < frame_length ) { - silk_assert( frame_length == 12 * 10 ); /* Make sure only happens for 10 ms @ 12 kHz */ - iter++; - silk_memset( &pulses[ frame_length ], 0, SHELL_CODEC_FRAME_LENGTH * sizeof(opus_int8)); - } - - /* Take the absolute value of the pulses */ - for( i = 0; i < iter * SHELL_CODEC_FRAME_LENGTH; i+=4 ) { - abs_pulses[i+0] = ( opus_int )silk_abs( pulses[ i + 0 ] ); - abs_pulses[i+1] = ( opus_int )silk_abs( pulses[ i + 1 ] ); - abs_pulses[i+2] = ( opus_int )silk_abs( pulses[ i + 2 ] ); - abs_pulses[i+3] = ( opus_int )silk_abs( pulses[ i + 3 ] ); - } - - /* Calc sum pulses per shell code frame */ - abs_pulses_ptr = abs_pulses; - for( i = 0; i < iter; i++ ) { - nRshifts[ i ] = 0; - - while( 1 ) { - /* 1+1 -> 2 */ - scale_down = combine_and_check( pulses_comb, abs_pulses_ptr, silk_max_pulses_table[ 0 ], 8 ); - /* 2+2 -> 4 */ - scale_down += combine_and_check( pulses_comb, pulses_comb, silk_max_pulses_table[ 1 ], 4 ); - /* 4+4 -> 8 */ - scale_down += combine_and_check( pulses_comb, pulses_comb, silk_max_pulses_table[ 2 ], 2 ); - /* 8+8 -> 16 */ - scale_down += combine_and_check( &sum_pulses[ i ], pulses_comb, silk_max_pulses_table[ 3 ], 1 ); - - if( scale_down ) { - /* We need to downscale the quantization signal */ - nRshifts[ i ]++; - for( k = 0; k < SHELL_CODEC_FRAME_LENGTH; k++ ) { - abs_pulses_ptr[ k ] = silk_RSHIFT( abs_pulses_ptr[ k ], 1 ); - } - } else { - /* Jump out of while(1) loop and go to next shell coding frame */ - break; - } - } - abs_pulses_ptr += SHELL_CODEC_FRAME_LENGTH; - } - - /**************/ - /* Rate level */ - /**************/ - /* find rate level that leads to fewest bits for coding of pulses per block info */ - minSumBits_Q5 = silk_int32_MAX; - for( k = 0; k < N_RATE_LEVELS - 1; k++ ) { - nBits_ptr = silk_pulses_per_block_BITS_Q5[ k ]; - sumBits_Q5 = silk_rate_levels_BITS_Q5[ signalType >> 1 ][ k ]; - for( i = 0; i < iter; i++ ) { - if( nRshifts[ i ] > 0 ) { - sumBits_Q5 += nBits_ptr[ MAX_PULSES + 1 ]; - } else { - sumBits_Q5 += nBits_ptr[ sum_pulses[ i ] ]; - } - } - if( sumBits_Q5 < minSumBits_Q5 ) { - minSumBits_Q5 = sumBits_Q5; - RateLevelIndex = k; - } - } - ec_enc_icdf( psRangeEnc, RateLevelIndex, silk_rate_levels_iCDF[ signalType >> 1 ], 8 ); - - /***************************************************/ - /* Sum-Weighted-Pulses Encoding */ - /***************************************************/ - cdf_ptr = silk_pulses_per_block_iCDF[ RateLevelIndex ]; - for( i = 0; i < iter; i++ ) { - if( nRshifts[ i ] == 0 ) { - ec_enc_icdf( psRangeEnc, sum_pulses[ i ], cdf_ptr, 8 ); - } else { - ec_enc_icdf( psRangeEnc, MAX_PULSES + 1, cdf_ptr, 8 ); - for( k = 0; k < nRshifts[ i ] - 1; k++ ) { - ec_enc_icdf( psRangeEnc, MAX_PULSES + 1, silk_pulses_per_block_iCDF[ N_RATE_LEVELS - 1 ], 8 ); - } - ec_enc_icdf( psRangeEnc, sum_pulses[ i ], silk_pulses_per_block_iCDF[ N_RATE_LEVELS - 1 ], 8 ); - } - } - - /******************/ - /* Shell Encoding */ - /******************/ - for( i = 0; i < iter; i++ ) { - if( sum_pulses[ i ] > 0 ) { - silk_shell_encoder( psRangeEnc, &abs_pulses[ i * SHELL_CODEC_FRAME_LENGTH ] ); - } - } - - /****************/ - /* LSB Encoding */ - /****************/ - for( i = 0; i < iter; i++ ) { - if( nRshifts[ i ] > 0 ) { - pulses_ptr = &pulses[ i * SHELL_CODEC_FRAME_LENGTH ]; - nLS = nRshifts[ i ] - 1; - for( k = 0; k < SHELL_CODEC_FRAME_LENGTH; k++ ) { - abs_q = (opus_int8)silk_abs( pulses_ptr[ k ] ); - for( j = nLS; j > 0; j-- ) { - bit = silk_RSHIFT( abs_q, j ) & 1; - ec_enc_icdf( psRangeEnc, bit, silk_lsb_iCDF, 8 ); - } - bit = abs_q & 1; - ec_enc_icdf( psRangeEnc, bit, silk_lsb_iCDF, 8 ); - } - } - } - - /****************/ - /* Encode signs */ - /****************/ - silk_encode_signs( psRangeEnc, pulses, frame_length, signalType, quantOffsetType, sum_pulses ); -} diff --git a/src/opus-1.0.2/silk/errors.h b/src/opus-1.0.2/silk/errors.h deleted file mode 100644 index 0591e009..00000000 --- a/src/opus-1.0.2/silk/errors.h +++ /dev/null @@ -1,98 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifndef SILK_ERRORS_H -#define SILK_ERRORS_H - -#ifdef __cplusplus -extern "C" -{ -#endif - -/******************/ -/* Error messages */ -/******************/ -#define SILK_NO_ERROR 0 - -/**************************/ -/* Encoder error messages */ -/**************************/ - -/* Input length is not a multiple of 10 ms, or length is longer than the packet length */ -#define SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES -101 - -/* Sampling frequency not 8000, 12000 or 16000 Hertz */ -#define SILK_ENC_FS_NOT_SUPPORTED -102 - -/* Packet size not 10, 20, 40, or 60 ms */ -#define SILK_ENC_PACKET_SIZE_NOT_SUPPORTED -103 - -/* Allocated payload buffer too short */ -#define SILK_ENC_PAYLOAD_BUF_TOO_SHORT -104 - -/* Loss rate not between 0 and 100 percent */ -#define SILK_ENC_INVALID_LOSS_RATE -105 - -/* Complexity setting not valid, use 0...10 */ -#define SILK_ENC_INVALID_COMPLEXITY_SETTING -106 - -/* Inband FEC setting not valid, use 0 or 1 */ -#define SILK_ENC_INVALID_INBAND_FEC_SETTING -107 - -/* DTX setting not valid, use 0 or 1 */ -#define SILK_ENC_INVALID_DTX_SETTING -108 - -/* CBR setting not valid, use 0 or 1 */ -#define SILK_ENC_INVALID_CBR_SETTING -109 - -/* Internal encoder error */ -#define SILK_ENC_INTERNAL_ERROR -110 - -/* Internal encoder error */ -#define SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR -111 - -/**************************/ -/* Decoder error messages */ -/**************************/ - -/* Output sampling frequency lower than internal decoded sampling frequency */ -#define SILK_DEC_INVALID_SAMPLING_FREQUENCY -200 - -/* Payload size exceeded the maximum allowed 1024 bytes */ -#define SILK_DEC_PAYLOAD_TOO_LARGE -201 - -/* Payload has bit errors */ -#define SILK_DEC_PAYLOAD_ERROR -202 - -/* Payload has bit errors */ -#define SILK_DEC_INVALID_FRAME_SIZE -203 - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/opus-1.0.2/silk/fixed/LTP_analysis_filter_FIX.c b/src/opus-1.0.2/silk/fixed/LTP_analysis_filter_FIX.c deleted file mode 100644 index a8fee555..00000000 --- a/src/opus-1.0.2/silk/fixed/LTP_analysis_filter_FIX.c +++ /dev/null @@ -1,85 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main_FIX.h" - -void silk_LTP_analysis_filter_FIX( - opus_int16 *LTP_res, /* O LTP residual signal of length MAX_NB_SUBFR * ( pre_length + subfr_length ) */ - const opus_int16 *x, /* I Pointer to input signal with at least max( pitchL ) preceding samples */ - const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],/* I LTP_ORDER LTP coefficients for each MAX_NB_SUBFR subframe */ - const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag, one for each subframe */ - const opus_int32 invGains_Q16[ MAX_NB_SUBFR ], /* I Inverse quantization gains, one for each subframe */ - const opus_int subfr_length, /* I Length of each subframe */ - const opus_int nb_subfr, /* I Number of subframes */ - const opus_int pre_length /* I Length of the preceding samples starting at &x[0] for each subframe */ -) -{ - const opus_int16 *x_ptr, *x_lag_ptr; - opus_int16 Btmp_Q14[ LTP_ORDER ]; - opus_int16 *LTP_res_ptr; - opus_int k, i, j; - opus_int32 LTP_est; - - x_ptr = x; - LTP_res_ptr = LTP_res; - for( k = 0; k < nb_subfr; k++ ) { - - x_lag_ptr = x_ptr - pitchL[ k ]; - for( i = 0; i < LTP_ORDER; i++ ) { - Btmp_Q14[ i ] = LTPCoef_Q14[ k * LTP_ORDER + i ]; - } - - /* LTP analysis FIR filter */ - for( i = 0; i < subfr_length + pre_length; i++ ) { - LTP_res_ptr[ i ] = x_ptr[ i ]; - - /* Long-term prediction */ - LTP_est = silk_SMULBB( x_lag_ptr[ LTP_ORDER / 2 ], Btmp_Q14[ 0 ] ); - for( j = 1; j < LTP_ORDER; j++ ) { - LTP_est = silk_SMLABB_ovflw( LTP_est, x_lag_ptr[ LTP_ORDER / 2 - j ], Btmp_Q14[ j ] ); - } - LTP_est = silk_RSHIFT_ROUND( LTP_est, 14 ); /* round and -> Q0*/ - - /* Subtract long-term prediction */ - LTP_res_ptr[ i ] = (opus_int16)silk_SAT16( (opus_int32)x_ptr[ i ] - LTP_est ); - - /* Scale residual */ - LTP_res_ptr[ i ] = silk_SMULWB( invGains_Q16[ k ], LTP_res_ptr[ i ] ); - - x_lag_ptr++; - } - - /* Update pointers */ - LTP_res_ptr += subfr_length + pre_length; - x_ptr += subfr_length; - } -} - diff --git a/src/opus-1.0.2/silk/fixed/LTP_scale_ctrl_FIX.c b/src/opus-1.0.2/silk/fixed/LTP_scale_ctrl_FIX.c deleted file mode 100644 index ac2fba17..00000000 --- a/src/opus-1.0.2/silk/fixed/LTP_scale_ctrl_FIX.c +++ /dev/null @@ -1,53 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main_FIX.h" - -/* Calculation of LTP state scaling */ -void silk_LTP_scale_ctrl_FIX( - silk_encoder_state_FIX *psEnc, /* I/O encoder state */ - silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */ - opus_int condCoding /* I The type of conditional coding to use */ -) -{ - opus_int round_loss; - - if( condCoding == CODE_INDEPENDENTLY ) { - /* Only scale if first frame in packet */ - round_loss = psEnc->sCmn.PacketLoss_perc + psEnc->sCmn.nFramesPerPacket; - psEnc->sCmn.indices.LTP_scaleIndex = (opus_int8)silk_LIMIT( - silk_SMULWB( silk_SMULBB( round_loss, psEncCtrl->LTPredCodGain_Q7 ), SILK_FIX_CONST( 0.1, 9 ) ), 0, 2 ); - } else { - /* Default is minimum scaling */ - psEnc->sCmn.indices.LTP_scaleIndex = 0; - } - psEncCtrl->LTP_scale_Q14 = silk_LTPScales_table_Q14[ psEnc->sCmn.indices.LTP_scaleIndex ]; -} diff --git a/src/opus-1.0.2/silk/fixed/apply_sine_window_FIX.c b/src/opus-1.0.2/silk/fixed/apply_sine_window_FIX.c deleted file mode 100644 index 897fdc30..00000000 --- a/src/opus-1.0.2/silk/fixed/apply_sine_window_FIX.c +++ /dev/null @@ -1,101 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "SigProc_FIX.h" - -/* Apply sine window to signal vector. */ -/* Window types: */ -/* 1 -> sine window from 0 to pi/2 */ -/* 2 -> sine window from pi/2 to pi */ -/* Every other sample is linearly interpolated, for speed. */ -/* Window length must be between 16 and 120 (incl) and a multiple of 4. */ - -/* Matlab code for table: - for k=16:9*4:16+2*9*4, fprintf(' %7.d,', -round(65536*pi ./ (k:4:k+8*4))); fprintf('\n'); end -*/ -static const opus_int16 freq_table_Q16[ 27 ] = { - 12111, 9804, 8235, 7100, 6239, 5565, 5022, 4575, 4202, - 3885, 3612, 3375, 3167, 2984, 2820, 2674, 2542, 2422, - 2313, 2214, 2123, 2038, 1961, 1889, 1822, 1760, 1702, -}; - -void silk_apply_sine_window( - opus_int16 px_win[], /* O Pointer to windowed signal */ - const opus_int16 px[], /* I Pointer to input signal */ - const opus_int win_type, /* I Selects a window type */ - const opus_int length /* I Window length, multiple of 4 */ -) -{ - opus_int k, f_Q16, c_Q16; - opus_int32 S0_Q16, S1_Q16; - - silk_assert( win_type == 1 || win_type == 2 ); - - /* Length must be in a range from 16 to 120 and a multiple of 4 */ - silk_assert( length >= 16 && length <= 120 ); - silk_assert( ( length & 3 ) == 0 ); - - /* Frequency */ - k = ( length >> 2 ) - 4; - silk_assert( k >= 0 && k <= 26 ); - f_Q16 = (opus_int)freq_table_Q16[ k ]; - - /* Factor used for cosine approximation */ - c_Q16 = silk_SMULWB( (opus_int32)f_Q16, -f_Q16 ); - silk_assert( c_Q16 >= -32768 ); - - /* initialize state */ - if( win_type == 1 ) { - /* start from 0 */ - S0_Q16 = 0; - /* approximation of sin(f) */ - S1_Q16 = f_Q16 + silk_RSHIFT( length, 3 ); - } else { - /* start from 1 */ - S0_Q16 = ( (opus_int32)1 << 16 ); - /* approximation of cos(f) */ - S1_Q16 = ( (opus_int32)1 << 16 ) + silk_RSHIFT( c_Q16, 1 ) + silk_RSHIFT( length, 4 ); - } - - /* Uses the recursive equation: sin(n*f) = 2 * cos(f) * sin((n-1)*f) - sin((n-2)*f) */ - /* 4 samples at a time */ - for( k = 0; k < length; k += 4 ) { - px_win[ k ] = (opus_int16)silk_SMULWB( silk_RSHIFT( S0_Q16 + S1_Q16, 1 ), px[ k ] ); - px_win[ k + 1 ] = (opus_int16)silk_SMULWB( S1_Q16, px[ k + 1] ); - S0_Q16 = silk_SMULWB( S1_Q16, c_Q16 ) + silk_LSHIFT( S1_Q16, 1 ) - S0_Q16 + 1; - S0_Q16 = silk_min( S0_Q16, ( (opus_int32)1 << 16 ) ); - - px_win[ k + 2 ] = (opus_int16)silk_SMULWB( silk_RSHIFT( S0_Q16 + S1_Q16, 1 ), px[ k + 2] ); - px_win[ k + 3 ] = (opus_int16)silk_SMULWB( S0_Q16, px[ k + 3 ] ); - S1_Q16 = silk_SMULWB( S0_Q16, c_Q16 ) + silk_LSHIFT( S0_Q16, 1 ) - S1_Q16; - S1_Q16 = silk_min( S1_Q16, ( (opus_int32)1 << 16 ) ); - } -} diff --git a/src/opus-1.0.2/silk/fixed/autocorr_FIX.c b/src/opus-1.0.2/silk/fixed/autocorr_FIX.c deleted file mode 100644 index c2ebb6a9..00000000 --- a/src/opus-1.0.2/silk/fixed/autocorr_FIX.c +++ /dev/null @@ -1,76 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "SigProc_FIX.h" - -/* Compute autocorrelation */ -void silk_autocorr( - opus_int32 *results, /* O Result (length correlationCount) */ - opus_int *scale, /* O Scaling of the correlation vector */ - const opus_int16 *inputData, /* I Input data to correlate */ - const opus_int inputDataSize, /* I Length of input */ - const opus_int correlationCount /* I Number of correlation taps to compute */ -) -{ - opus_int i, lz, nRightShifts, corrCount; - opus_int64 corr64; - - corrCount = silk_min_int( inputDataSize, correlationCount ); - - /* compute energy (zero-lag correlation) */ - corr64 = silk_inner_prod16_aligned_64( inputData, inputData, inputDataSize ); - - /* deal with all-zero input data */ - corr64 += 1; - - /* number of leading zeros */ - lz = silk_CLZ64( corr64 ); - - /* scaling: number of right shifts applied to correlations */ - nRightShifts = 35 - lz; - *scale = nRightShifts; - - if( nRightShifts <= 0 ) { - results[ 0 ] = silk_LSHIFT( (opus_int32)silk_CHECK_FIT32( corr64 ), -nRightShifts ); - - /* compute remaining correlations based on int32 inner product */ - for( i = 1; i < corrCount; i++ ) { - results[ i ] = silk_LSHIFT( silk_inner_prod_aligned( inputData, inputData + i, inputDataSize - i ), -nRightShifts ); - } - } else { - results[ 0 ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( corr64, nRightShifts ) ); - - /* compute remaining correlations based on int64 inner product */ - for( i = 1; i < corrCount; i++ ) { - results[ i ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( silk_inner_prod16_aligned_64( inputData, inputData + i, inputDataSize - i ), nRightShifts ) ); - } - } -} diff --git a/src/opus-1.0.2/silk/fixed/burg_modified_FIX.c b/src/opus-1.0.2/silk/fixed/burg_modified_FIX.c deleted file mode 100644 index 26a66b1c..00000000 --- a/src/opus-1.0.2/silk/fixed/burg_modified_FIX.c +++ /dev/null @@ -1,269 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "SigProc_FIX.h" -#include "define.h" -#include "tuning_parameters.h" - -#define MAX_FRAME_SIZE 384 /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384 */ - -#define QA 25 -#define N_BITS_HEAD_ROOM 2 -#define MIN_RSHIFTS -16 -#define MAX_RSHIFTS (32 - QA) - -/* Compute reflection coefficients from input signal */ -void silk_burg_modified( - opus_int32 *res_nrg, /* O Residual energy */ - opus_int *res_nrg_Q, /* O Residual energy Q value */ - opus_int32 A_Q16[], /* O Prediction coefficients (length order) */ - const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */ - const opus_int32 minInvGain_Q30, /* I Inverse of max prediction gain */ - const opus_int subfr_length, /* I Input signal subframe length (incl. D preceding samples) */ - const opus_int nb_subfr, /* I Number of subframes stacked in x */ - const opus_int D /* I Order */ -) -{ - opus_int k, n, s, lz, rshifts, rshifts_extra, reached_max_gain; - opus_int32 C0, num, nrg, rc_Q31, invGain_Q30, Atmp_QA, Atmp1, tmp1, tmp2, x1, x2; - const opus_int16 *x_ptr; - opus_int32 C_first_row[ SILK_MAX_ORDER_LPC ]; - opus_int32 C_last_row[ SILK_MAX_ORDER_LPC ]; - opus_int32 Af_QA[ SILK_MAX_ORDER_LPC ]; - opus_int32 CAf[ SILK_MAX_ORDER_LPC + 1 ]; - opus_int32 CAb[ SILK_MAX_ORDER_LPC + 1 ]; - - silk_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE ); - - /* Compute autocorrelations, added over subframes */ - silk_sum_sqr_shift( &C0, &rshifts, x, nb_subfr * subfr_length ); - if( rshifts > MAX_RSHIFTS ) { - C0 = silk_LSHIFT32( C0, rshifts - MAX_RSHIFTS ); - silk_assert( C0 > 0 ); - rshifts = MAX_RSHIFTS; - } else { - lz = silk_CLZ32( C0 ) - 1; - rshifts_extra = N_BITS_HEAD_ROOM - lz; - if( rshifts_extra > 0 ) { - rshifts_extra = silk_min( rshifts_extra, MAX_RSHIFTS - rshifts ); - C0 = silk_RSHIFT32( C0, rshifts_extra ); - } else { - rshifts_extra = silk_max( rshifts_extra, MIN_RSHIFTS - rshifts ); - C0 = silk_LSHIFT32( C0, -rshifts_extra ); - } - rshifts += rshifts_extra; - } - CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1; /* Q(-rshifts) */ - silk_memset( C_first_row, 0, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) ); - if( rshifts > 0 ) { - for( s = 0; s < nb_subfr; s++ ) { - x_ptr = x + s * subfr_length; - for( n = 1; n < D + 1; n++ ) { - C_first_row[ n - 1 ] += (opus_int32)silk_RSHIFT64( - silk_inner_prod16_aligned_64( x_ptr, x_ptr + n, subfr_length - n ), rshifts ); - } - } - } else { - for( s = 0; s < nb_subfr; s++ ) { - x_ptr = x + s * subfr_length; - for( n = 1; n < D + 1; n++ ) { - C_first_row[ n - 1 ] += silk_LSHIFT32( - silk_inner_prod_aligned( x_ptr, x_ptr + n, subfr_length - n ), -rshifts ); - } - } - } - silk_memcpy( C_last_row, C_first_row, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) ); - - /* Initialize */ - CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1; /* Q(-rshifts) */ - - invGain_Q30 = (opus_int32)1 << 30; - reached_max_gain = 0; - for( n = 0; n < D; n++ ) { - /* Update first row of correlation matrix (without first element) */ - /* Update last row of correlation matrix (without last element, stored in reversed order) */ - /* Update C * Af */ - /* Update C * flipud(Af) (stored in reversed order) */ - if( rshifts > -2 ) { - for( s = 0; s < nb_subfr; s++ ) { - x_ptr = x + s * subfr_length; - x1 = -silk_LSHIFT32( (opus_int32)x_ptr[ n ], 16 - rshifts ); /* Q(16-rshifts) */ - x2 = -silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], 16 - rshifts ); /* Q(16-rshifts) */ - tmp1 = silk_LSHIFT32( (opus_int32)x_ptr[ n ], QA - 16 ); /* Q(QA-16) */ - tmp2 = silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], QA - 16 ); /* Q(QA-16) */ - for( k = 0; k < n; k++ ) { - C_first_row[ k ] = silk_SMLAWB( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts ) */ - C_last_row[ k ] = silk_SMLAWB( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts ) */ - Atmp_QA = Af_QA[ k ]; - tmp1 = silk_SMLAWB( tmp1, Atmp_QA, x_ptr[ n - k - 1 ] ); /* Q(QA-16) */ - tmp2 = silk_SMLAWB( tmp2, Atmp_QA, x_ptr[ subfr_length - n + k ] ); /* Q(QA-16) */ - } - tmp1 = silk_LSHIFT32( -tmp1, 32 - QA - rshifts ); /* Q(16-rshifts) */ - tmp2 = silk_LSHIFT32( -tmp2, 32 - QA - rshifts ); /* Q(16-rshifts) */ - for( k = 0; k <= n; k++ ) { - CAf[ k ] = silk_SMLAWB( CAf[ k ], tmp1, x_ptr[ n - k ] ); /* Q( -rshift ) */ - CAb[ k ] = silk_SMLAWB( CAb[ k ], tmp2, x_ptr[ subfr_length - n + k - 1 ] ); /* Q( -rshift ) */ - } - } - } else { - for( s = 0; s < nb_subfr; s++ ) { - x_ptr = x + s * subfr_length; - x1 = -silk_LSHIFT32( (opus_int32)x_ptr[ n ], -rshifts ); /* Q( -rshifts ) */ - x2 = -silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], -rshifts ); /* Q( -rshifts ) */ - tmp1 = silk_LSHIFT32( (opus_int32)x_ptr[ n ], 17 ); /* Q17 */ - tmp2 = silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], 17 ); /* Q17 */ - for( k = 0; k < n; k++ ) { - C_first_row[ k ] = silk_MLA( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts ) */ - C_last_row[ k ] = silk_MLA( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts ) */ - Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 17 ); /* Q17 */ - tmp1 = silk_MLA( tmp1, x_ptr[ n - k - 1 ], Atmp1 ); /* Q17 */ - tmp2 = silk_MLA( tmp2, x_ptr[ subfr_length - n + k ], Atmp1 ); /* Q17 */ - } - tmp1 = -tmp1; /* Q17 */ - tmp2 = -tmp2; /* Q17 */ - for( k = 0; k <= n; k++ ) { - CAf[ k ] = silk_SMLAWW( CAf[ k ], tmp1, - silk_LSHIFT32( (opus_int32)x_ptr[ n - k ], -rshifts - 1 ) ); /* Q( -rshift ) */ - CAb[ k ] = silk_SMLAWW( CAb[ k ], tmp2, - silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n + k - 1 ], -rshifts - 1 ) ); /* Q( -rshift ) */ - } - } - } - - /* Calculate nominator and denominator for the next order reflection (parcor) coefficient */ - tmp1 = C_first_row[ n ]; /* Q( -rshifts ) */ - tmp2 = C_last_row[ n ]; /* Q( -rshifts ) */ - num = 0; /* Q( -rshifts ) */ - nrg = silk_ADD32( CAb[ 0 ], CAf[ 0 ] ); /* Q( 1-rshifts ) */ - for( k = 0; k < n; k++ ) { - Atmp_QA = Af_QA[ k ]; - lz = silk_CLZ32( silk_abs( Atmp_QA ) ) - 1; - lz = silk_min( 32 - QA, lz ); - Atmp1 = silk_LSHIFT32( Atmp_QA, lz ); /* Q( QA + lz ) */ - - tmp1 = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( C_last_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */ - tmp2 = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( C_first_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */ - num = silk_ADD_LSHIFT32( num, silk_SMMUL( CAb[ n - k ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */ - nrg = silk_ADD_LSHIFT32( nrg, silk_SMMUL( silk_ADD32( CAb[ k + 1 ], CAf[ k + 1 ] ), - Atmp1 ), 32 - QA - lz ); /* Q( 1-rshifts ) */ - } - CAf[ n + 1 ] = tmp1; /* Q( -rshifts ) */ - CAb[ n + 1 ] = tmp2; /* Q( -rshifts ) */ - num = silk_ADD32( num, tmp2 ); /* Q( -rshifts ) */ - num = silk_LSHIFT32( -num, 1 ); /* Q( 1-rshifts ) */ - - /* Calculate the next order reflection (parcor) coefficient */ - if( silk_abs( num ) < nrg ) { - rc_Q31 = silk_DIV32_varQ( num, nrg, 31 ); - } else { - rc_Q31 = ( num > 0 ) ? silk_int32_MAX : silk_int32_MIN; - } - - /* Update inverse prediction gain */ - tmp1 = ( (opus_int32)1 << 30 ) - silk_SMMUL( rc_Q31, rc_Q31 ); - tmp1 = silk_LSHIFT( silk_SMMUL( invGain_Q30, tmp1 ), 2 ); - if( tmp1 <= minInvGain_Q30 ) { - /* Max prediction gain exceeded; set reflection coefficient such that max prediction gain is exactly hit */ - tmp2 = ( (opus_int32)1 << 30 ) - silk_DIV32_varQ( minInvGain_Q30, invGain_Q30, 30 ); /* Q30 */ - rc_Q31 = silk_SQRT_APPROX( tmp2 ); /* Q15 */ - /* Newton-Raphson iteration */ - rc_Q31 = silk_RSHIFT32( rc_Q31 + silk_DIV32( tmp2, rc_Q31 ), 1 ); /* Q15 */ - rc_Q31 = silk_LSHIFT32( rc_Q31, 16 ); /* Q31 */ - if( num < 0 ) { - /* Ensure adjusted reflection coefficients has the original sign */ - rc_Q31 = -rc_Q31; - } - invGain_Q30 = minInvGain_Q30; - reached_max_gain = 1; - } else { - invGain_Q30 = tmp1; - } - - /* Update the AR coefficients */ - for( k = 0; k < (n + 1) >> 1; k++ ) { - tmp1 = Af_QA[ k ]; /* QA */ - tmp2 = Af_QA[ n - k - 1 ]; /* QA */ - Af_QA[ k ] = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( tmp2, rc_Q31 ), 1 ); /* QA */ - Af_QA[ n - k - 1 ] = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( tmp1, rc_Q31 ), 1 ); /* QA */ - } - Af_QA[ n ] = silk_RSHIFT32( rc_Q31, 31 - QA ); /* QA */ - - if( reached_max_gain ) { - /* Reached max prediction gain; set remaining coefficients to zero and exit loop */ - for( k = n + 1; k < D; k++ ) { - Af_QA[ k ] = 0; - } - break; - } - - /* Update C * Af and C * Ab */ - for( k = 0; k <= n + 1; k++ ) { - tmp1 = CAf[ k ]; /* Q( -rshifts ) */ - tmp2 = CAb[ n - k + 1 ]; /* Q( -rshifts ) */ - CAf[ k ] = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( tmp2, rc_Q31 ), 1 ); /* Q( -rshifts ) */ - CAb[ n - k + 1 ] = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( tmp1, rc_Q31 ), 1 ); /* Q( -rshifts ) */ - } - } - - if( reached_max_gain ) { - for( k = 0; k < D; k++ ) { - /* Scale coefficients */ - A_Q16[ k ] = -silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 ); - } - /* Subtract energy of preceding samples from C0 */ - if( rshifts > 0 ) { - for( s = 0; s < nb_subfr; s++ ) { - x_ptr = x + s * subfr_length; - C0 -= (opus_int32)silk_RSHIFT64( silk_inner_prod16_aligned_64( x_ptr, x_ptr, D ), rshifts ); - } - } else { - for( s = 0; s < nb_subfr; s++ ) { - x_ptr = x + s * subfr_length; - C0 -= silk_LSHIFT32( silk_inner_prod_aligned( x_ptr, x_ptr, D ), -rshifts ); - } - } - /* Approximate residual energy */ - *res_nrg = silk_LSHIFT( silk_SMMUL( invGain_Q30, C0 ), 2 ); - *res_nrg_Q = -rshifts; - } else { - /* Return residual energy */ - nrg = CAf[ 0 ]; /* Q( -rshifts ) */ - tmp1 = (opus_int32)1 << 16; /* Q16 */ - for( k = 0; k < D; k++ ) { - Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 ); /* Q16 */ - nrg = silk_SMLAWW( nrg, CAf[ k + 1 ], Atmp1 ); /* Q( -rshifts ) */ - tmp1 = silk_SMLAWW( tmp1, Atmp1, Atmp1 ); /* Q16 */ - A_Q16[ k ] = -Atmp1; - } - *res_nrg = silk_SMLAWW( nrg, silk_SMMUL( FIND_LPC_COND_FAC, C0 ), -tmp1 ); /* Q( -rshifts ) */ - *res_nrg_Q = -rshifts; - } -} diff --git a/src/opus-1.0.2/silk/fixed/corrMatrix_FIX.c b/src/opus-1.0.2/silk/fixed/corrMatrix_FIX.c deleted file mode 100644 index 21502499..00000000 --- a/src/opus-1.0.2/silk/fixed/corrMatrix_FIX.c +++ /dev/null @@ -1,156 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/********************************************************************** - * Correlation Matrix Computations for LS estimate. - **********************************************************************/ - -#include "main_FIX.h" - -/* Calculates correlation vector X'*t */ -void silk_corrVector_FIX( - const opus_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */ - const opus_int16 *t, /* I Target vector [L] */ - const opus_int L, /* I Length of vectors */ - const opus_int order, /* I Max lag for correlation */ - opus_int32 *Xt, /* O Pointer to X'*t correlation vector [order] */ - const opus_int rshifts /* I Right shifts of correlations */ -) -{ - opus_int lag, i; - const opus_int16 *ptr1, *ptr2; - opus_int32 inner_prod; - - ptr1 = &x[ order - 1 ]; /* Points to first sample of column 0 of X: X[:,0] */ - ptr2 = t; - /* Calculate X'*t */ - if( rshifts > 0 ) { - /* Right shifting used */ - for( lag = 0; lag < order; lag++ ) { - inner_prod = 0; - for( i = 0; i < L; i++ ) { - inner_prod += silk_RSHIFT32( silk_SMULBB( ptr1[ i ], ptr2[i] ), rshifts ); - } - Xt[ lag ] = inner_prod; /* X[:,lag]'*t */ - ptr1--; /* Go to next column of X */ - } - } else { - silk_assert( rshifts == 0 ); - for( lag = 0; lag < order; lag++ ) { - Xt[ lag ] = silk_inner_prod_aligned( ptr1, ptr2, L ); /* X[:,lag]'*t */ - ptr1--; /* Go to next column of X */ - } - } -} - -/* Calculates correlation matrix X'*X */ -void silk_corrMatrix_FIX( - const opus_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */ - const opus_int L, /* I Length of vectors */ - const opus_int order, /* I Max lag for correlation */ - const opus_int head_room, /* I Desired headroom */ - opus_int32 *XX, /* O Pointer to X'*X correlation matrix [ order x order ] */ - opus_int *rshifts /* I/O Right shifts of correlations */ -) -{ - opus_int i, j, lag, rshifts_local, head_room_rshifts; - opus_int32 energy; - const opus_int16 *ptr1, *ptr2; - - /* Calculate energy to find shift used to fit in 32 bits */ - silk_sum_sqr_shift( &energy, &rshifts_local, x, L + order - 1 ); - /* Add shifts to get the desired head room */ - head_room_rshifts = silk_max( head_room - silk_CLZ32( energy ), 0 ); - - energy = silk_RSHIFT32( energy, head_room_rshifts ); - rshifts_local += head_room_rshifts; - - /* Calculate energy of first column (0) of X: X[:,0]'*X[:,0] */ - /* Remove contribution of first order - 1 samples */ - for( i = 0; i < order - 1; i++ ) { - energy -= silk_RSHIFT32( silk_SMULBB( x[ i ], x[ i ] ), rshifts_local ); - } - if( rshifts_local < *rshifts ) { - /* Adjust energy */ - energy = silk_RSHIFT32( energy, *rshifts - rshifts_local ); - rshifts_local = *rshifts; - } - - /* Calculate energy of remaining columns of X: X[:,j]'*X[:,j] */ - /* Fill out the diagonal of the correlation matrix */ - matrix_ptr( XX, 0, 0, order ) = energy; - ptr1 = &x[ order - 1 ]; /* First sample of column 0 of X */ - for( j = 1; j < order; j++ ) { - energy = silk_SUB32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ L - j ], ptr1[ L - j ] ), rshifts_local ) ); - energy = silk_ADD32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ -j ], ptr1[ -j ] ), rshifts_local ) ); - matrix_ptr( XX, j, j, order ) = energy; - } - - ptr2 = &x[ order - 2 ]; /* First sample of column 1 of X */ - /* Calculate the remaining elements of the correlation matrix */ - if( rshifts_local > 0 ) { - /* Right shifting used */ - for( lag = 1; lag < order; lag++ ) { - /* Inner product of column 0 and column lag: X[:,0]'*X[:,lag] */ - energy = 0; - for( i = 0; i < L; i++ ) { - energy += silk_RSHIFT32( silk_SMULBB( ptr1[ i ], ptr2[i] ), rshifts_local ); - } - /* Calculate remaining off diagonal: X[:,j]'*X[:,j + lag] */ - matrix_ptr( XX, lag, 0, order ) = energy; - matrix_ptr( XX, 0, lag, order ) = energy; - for( j = 1; j < ( order - lag ); j++ ) { - energy = silk_SUB32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ), rshifts_local ) ); - energy = silk_ADD32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ -j ], ptr2[ -j ] ), rshifts_local ) ); - matrix_ptr( XX, lag + j, j, order ) = energy; - matrix_ptr( XX, j, lag + j, order ) = energy; - } - ptr2--; /* Update pointer to first sample of next column (lag) in X */ - } - } else { - for( lag = 1; lag < order; lag++ ) { - /* Inner product of column 0 and column lag: X[:,0]'*X[:,lag] */ - energy = silk_inner_prod_aligned( ptr1, ptr2, L ); - matrix_ptr( XX, lag, 0, order ) = energy; - matrix_ptr( XX, 0, lag, order ) = energy; - /* Calculate remaining off diagonal: X[:,j]'*X[:,j + lag] */ - for( j = 1; j < ( order - lag ); j++ ) { - energy = silk_SUB32( energy, silk_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ) ); - energy = silk_SMLABB( energy, ptr1[ -j ], ptr2[ -j ] ); - matrix_ptr( XX, lag + j, j, order ) = energy; - matrix_ptr( XX, j, lag + j, order ) = energy; - } - ptr2--;/* Update pointer to first sample of next column (lag) in X */ - } - } - *rshifts = rshifts_local; -} - diff --git a/src/opus-1.0.2/silk/fixed/encode_frame_FIX.c b/src/opus-1.0.2/silk/fixed/encode_frame_FIX.c deleted file mode 100644 index a37a9f21..00000000 --- a/src/opus-1.0.2/silk/fixed/encode_frame_FIX.c +++ /dev/null @@ -1,372 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main_FIX.h" -#include "tuning_parameters.h" - -/* Low Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode with lower bitrate */ -static inline void silk_LBRR_encode_FIX( - silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ - silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk FIX encoder control struct */ - const opus_int32 xfw_Q3[], /* I Input signal */ - opus_int condCoding /* I The type of conditional coding used so far for this frame */ -); - -void silk_encode_do_VAD_FIX( - silk_encoder_state_FIX *psEnc /* I/O Pointer to Silk FIX encoder state */ -) -{ - /****************************/ - /* Voice Activity Detection */ - /****************************/ - silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf + 1 ); - - /**************************************************/ - /* Convert speech activity into VAD and DTX flags */ - /**************************************************/ - if( psEnc->sCmn.speech_activity_Q8 < SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ) ) { - psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY; - psEnc->sCmn.noSpeechCounter++; - if( psEnc->sCmn.noSpeechCounter < NB_SPEECH_FRAMES_BEFORE_DTX ) { - psEnc->sCmn.inDTX = 0; - } else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) { - psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX; - psEnc->sCmn.inDTX = 0; - } - psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 0; - } else { - psEnc->sCmn.noSpeechCounter = 0; - psEnc->sCmn.inDTX = 0; - psEnc->sCmn.indices.signalType = TYPE_UNVOICED; - psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 1; - } -} - -/****************/ -/* Encode frame */ -/****************/ -opus_int silk_encode_frame_FIX( - silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ - opus_int32 *pnBytesOut, /* O Pointer to number of payload bytes; */ - ec_enc *psRangeEnc, /* I/O compressor data structure */ - opus_int condCoding, /* I The type of conditional coding to use */ - opus_int maxBits, /* I If > 0: maximum number of output bits */ - opus_int useCBR /* I Flag to force constant-bitrate operation */ -) -{ - silk_encoder_control_FIX sEncCtrl; - opus_int i, iter, maxIter, found_upper, found_lower, ret = 0; - opus_int16 *x_frame, *res_pitch_frame; - opus_int32 xfw_Q3[ MAX_FRAME_LENGTH ]; - opus_int16 res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ]; - ec_enc sRangeEnc_copy, sRangeEnc_copy2; - silk_nsq_state sNSQ_copy, sNSQ_copy2; - opus_int32 seed_copy, nBits, nBits_lower, nBits_upper, gainMult_lower, gainMult_upper; - opus_int32 gainsID, gainsID_lower, gainsID_upper; - opus_int16 gainMult_Q8; - opus_int16 ec_prevLagIndex_copy; - opus_int ec_prevSignalType_copy; - opus_int8 LastGainIndex_copy2; - opus_uint8 ec_buf_copy[ 1275 ]; - - /* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */ - LastGainIndex_copy2 = nBits_lower = nBits_upper = gainMult_lower = gainMult_upper = 0; - - psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3; - - /**************************************************************/ - /* Set up Input Pointers, and insert frame in input buffer */ - /*************************************************************/ - /* pointers aligned with start of frame to encode */ - x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length; /* start of frame to encode */ - res_pitch_frame = res_pitch + psEnc->sCmn.ltp_mem_length; /* start of pitch LPC residual frame */ - - /***************************************/ - /* Ensure smooth bandwidth transitions */ - /***************************************/ - silk_LP_variable_cutoff( &psEnc->sCmn.sLP, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length ); - - /*******************************************/ - /* Copy new frame to front of input buffer */ - /*******************************************/ - silk_memcpy( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length * sizeof( opus_int16 ) ); - - if( !psEnc->sCmn.prefillFlag ) { - /*****************************************/ - /* Find pitch lags, initial LPC analysis */ - /*****************************************/ - silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame ); - - /************************/ - /* Noise shape analysis */ - /************************/ - silk_noise_shape_analysis_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame ); - - /***************************************************/ - /* Find linear prediction coefficients (LPC + LTP) */ - /***************************************************/ - silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch, x_frame, condCoding ); - - /****************************************/ - /* Process gains */ - /****************************************/ - silk_process_gains_FIX( psEnc, &sEncCtrl, condCoding ); - - /*****************************************/ - /* Prefiltering for noise shaper */ - /*****************************************/ - silk_prefilter_FIX( psEnc, &sEncCtrl, xfw_Q3, x_frame ); - - /****************************************/ - /* Low Bitrate Redundant Encoding */ - /****************************************/ - silk_LBRR_encode_FIX( psEnc, &sEncCtrl, xfw_Q3, condCoding ); - - /* Loop over quantizer and entropy coding to control bitrate */ - maxIter = 6; - gainMult_Q8 = SILK_FIX_CONST( 1, 8 ); - found_lower = 0; - found_upper = 0; - gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr ); - gainsID_lower = -1; - gainsID_upper = -1; - /* Copy part of the input state */ - silk_memcpy( &sRangeEnc_copy, psRangeEnc, sizeof( ec_enc ) ); - silk_memcpy( &sNSQ_copy, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); - seed_copy = psEnc->sCmn.indices.Seed; - ec_prevLagIndex_copy = psEnc->sCmn.ec_prevLagIndex; - ec_prevSignalType_copy = psEnc->sCmn.ec_prevSignalType; - for( iter = 0; ; iter++ ) { - if( gainsID == gainsID_lower ) { - nBits = nBits_lower; - } else if( gainsID == gainsID_upper ) { - nBits = nBits_upper; - } else { - /* Restore part of the input state */ - if( iter > 0 ) { - silk_memcpy( psRangeEnc, &sRangeEnc_copy, sizeof( ec_enc ) ); - silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy, sizeof( silk_nsq_state ) ); - psEnc->sCmn.indices.Seed = seed_copy; - psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy; - psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy; - } - - /*****************************************/ - /* Noise shaping quantization */ - /*****************************************/ - if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) { - silk_NSQ_del_dec( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw_Q3, psEnc->sCmn.pulses, - sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14, - sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14 ); - } else { - silk_NSQ( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw_Q3, psEnc->sCmn.pulses, - sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14, - sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14 ); - } - - /****************************************/ - /* Encode Parameters */ - /****************************************/ - silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding ); - - /****************************************/ - /* Encode Excitation Signal */ - /****************************************/ - silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType, - psEnc->sCmn.pulses, psEnc->sCmn.frame_length ); - - nBits = ec_tell( psRangeEnc ); - - if( useCBR == 0 && iter == 0 && nBits <= maxBits ) { - break; - } - } - - if( iter == maxIter ) { - if( found_lower && ( gainsID == gainsID_lower || nBits > maxBits ) ) { - /* Restore output state from earlier iteration that did meet the bitrate budget */ - silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) ); - silk_assert( sRangeEnc_copy2.offs <= 1275 ); - silk_memcpy( psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs ); - silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy2, sizeof( silk_nsq_state ) ); - psEnc->sShape.LastGainIndex = LastGainIndex_copy2; - } - break; - } - - if( nBits > maxBits ) { - if( found_lower == 0 && iter >= 2 ) { - /* Adjust the quantizer's rate/distortion tradeoff and discard previous "upper" results */ - sEncCtrl.Lambda_Q10 = silk_ADD_RSHIFT32( sEncCtrl.Lambda_Q10, sEncCtrl.Lambda_Q10, 1 ); - found_upper = 0; - gainsID_upper = -1; - } else { - found_upper = 1; - nBits_upper = nBits; - gainMult_upper = gainMult_Q8; - gainsID_upper = gainsID; - } - } else if( nBits < maxBits - 5 ) { - found_lower = 1; - nBits_lower = nBits; - gainMult_lower = gainMult_Q8; - if( gainsID != gainsID_lower ) { - gainsID_lower = gainsID; - /* Copy part of the output state */ - silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) ); - silk_assert( psRangeEnc->offs <= 1275 ); - silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs ); - silk_memcpy( &sNSQ_copy2, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); - LastGainIndex_copy2 = psEnc->sShape.LastGainIndex; - } - } else { - /* Within 5 bits of budget: close enough */ - break; - } - - if( ( found_lower & found_upper ) == 0 ) { - /* Adjust gain according to high-rate rate/distortion curve */ - opus_int32 gain_factor_Q16; - gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) ); - gain_factor_Q16 = silk_min_32( gain_factor_Q16, SILK_FIX_CONST( 2, 16 ) ); - if( nBits > maxBits ) { - gain_factor_Q16 = silk_max_32( gain_factor_Q16, SILK_FIX_CONST( 1.3, 16 ) ); - } - gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 ); - } else { - /* Adjust gain by interpolating */ - gainMult_Q8 = gainMult_lower + silk_DIV32_16( silk_MUL( gainMult_upper - gainMult_lower, maxBits - nBits_lower ), nBits_upper - nBits_lower ); - /* New gain multplier must be between 25% and 75% of old range (note that gainMult_upper < gainMult_lower) */ - if( gainMult_Q8 > silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ) ) { - gainMult_Q8 = silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ); - } else - if( gainMult_Q8 < silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ) ) { - gainMult_Q8 = silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ); - } - } - - for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { - sEncCtrl.Gains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], gainMult_Q8 ), 8 ); - } - - /* Quantize gains */ - psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev; - silk_gains_quant( psEnc->sCmn.indices.GainsIndices, sEncCtrl.Gains_Q16, - &psEnc->sShape.LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); - - /* Unique identifier of gains vector */ - gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr ); - } - } - - /* Update input buffer */ - silk_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ], - ( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( opus_int16 ) ); - - /* Parameters needed for next frame */ - psEnc->sCmn.prevLag = sEncCtrl.pitchL[ psEnc->sCmn.nb_subfr - 1 ]; - psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType; - - /* Exit without entropy coding */ - if( psEnc->sCmn.prefillFlag ) { - /* No payload */ - *pnBytesOut = 0; - return ret; - } - - /****************************************/ - /* Finalize payload */ - /****************************************/ - psEnc->sCmn.first_frame_after_reset = 0; - /* Payload size */ - *pnBytesOut = silk_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 ); - - return ret; -} - -/* Low-Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode excitation at lower bitrate */ -static inline void silk_LBRR_encode_FIX( - silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ - silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk FIX encoder control struct */ - const opus_int32 xfw_Q3[], /* I Input signal */ - opus_int condCoding /* I The type of conditional coding used so far for this frame */ -) -{ - opus_int32 TempGains_Q16[ MAX_NB_SUBFR ]; - SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesEncoded ]; - silk_nsq_state sNSQ_LBRR; - - /*******************************************/ - /* Control use of inband LBRR */ - /*******************************************/ - if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SILK_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) { - psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded ] = 1; - - /* Copy noise shaping quantizer state and quantization indices from regular encoding */ - silk_memcpy( &sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); - silk_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) ); - - /* Save original gains */ - silk_memcpy( TempGains_Q16, psEncCtrl->Gains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) ); - - if( psEnc->sCmn.nFramesEncoded == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded - 1 ] == 0 ) { - /* First frame in packet or previous frame not LBRR coded */ - psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex; - - /* Increase Gains to get target LBRR rate */ - psIndices_LBRR->GainsIndices[ 0 ] = psIndices_LBRR->GainsIndices[ 0 ] + psEnc->sCmn.LBRR_GainIncreases; - psIndices_LBRR->GainsIndices[ 0 ] = silk_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 ); - } - - /* Decode to get gains in sync with decoder */ - /* Overwrite unquantized gains with quantized gains */ - silk_gains_dequant( psEncCtrl->Gains_Q16, psIndices_LBRR->GainsIndices, - &psEnc->sCmn.LBRRprevLastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); - - /*****************************************/ - /* Noise shaping quantization */ - /*****************************************/ - if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) { - silk_NSQ_del_dec( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, xfw_Q3, - psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14, - psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14, - psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 ); - } else { - silk_NSQ( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, xfw_Q3, - psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14, - psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14, - psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 ); - } - - /* Restore original gains */ - silk_memcpy( psEncCtrl->Gains_Q16, TempGains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) ); - } -} diff --git a/src/opus-1.0.2/silk/fixed/find_LPC_FIX.c b/src/opus-1.0.2/silk/fixed/find_LPC_FIX.c deleted file mode 100644 index 0ed7e846..00000000 --- a/src/opus-1.0.2/silk/fixed/find_LPC_FIX.c +++ /dev/null @@ -1,145 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main_FIX.h" -#include "tuning_parameters.h" - -/* Finds LPC vector from correlations, and converts to NLSF */ -void silk_find_LPC_FIX( - silk_encoder_state *psEncC, /* I/O Encoder state */ - opus_int16 NLSF_Q15[], /* O NLSFs */ - const opus_int16 x[], /* I Input signal */ - const opus_int32 minInvGain_Q30 /* I Inverse of max prediction gain */ -) -{ - opus_int k, subfr_length; - opus_int32 a_Q16[ MAX_LPC_ORDER ]; - opus_int isInterpLower, shift; - opus_int32 res_nrg0, res_nrg1; - opus_int rshift0, rshift1; - - /* Used only for LSF interpolation */ - opus_int32 a_tmp_Q16[ MAX_LPC_ORDER ], res_nrg_interp, res_nrg, res_tmp_nrg; - opus_int res_nrg_interp_Q, res_nrg_Q, res_tmp_nrg_Q; - opus_int16 a_tmp_Q12[ MAX_LPC_ORDER ]; - opus_int16 NLSF0_Q15[ MAX_LPC_ORDER ]; - opus_int16 LPC_res[ MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ]; - - subfr_length = psEncC->subfr_length + psEncC->predictLPCOrder; - - /* Default: no interpolation */ - psEncC->indices.NLSFInterpCoef_Q2 = 4; - - /* Burg AR analysis for the full frame */ - silk_burg_modified( &res_nrg, &res_nrg_Q, a_Q16, x, minInvGain_Q30, subfr_length, psEncC->nb_subfr, psEncC->predictLPCOrder ); - - if( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) { - /* Optimal solution for last 10 ms */ - silk_burg_modified( &res_tmp_nrg, &res_tmp_nrg_Q, a_tmp_Q16, x + 2 * subfr_length, minInvGain_Q30, subfr_length, 2, psEncC->predictLPCOrder ); - - /* subtract residual energy here, as that's easier than adding it to the */ - /* residual energy of the first 10 ms in each iteration of the search below */ - shift = res_tmp_nrg_Q - res_nrg_Q; - if( shift >= 0 ) { - if( shift < 32 ) { - res_nrg = res_nrg - silk_RSHIFT( res_tmp_nrg, shift ); - } - } else { - silk_assert( shift > -32 ); - res_nrg = silk_RSHIFT( res_nrg, -shift ) - res_tmp_nrg; - res_nrg_Q = res_tmp_nrg_Q; - } - - /* Convert to NLSFs */ - silk_A2NLSF( NLSF_Q15, a_tmp_Q16, psEncC->predictLPCOrder ); - - /* Search over interpolation indices to find the one with lowest residual energy */ - for( k = 3; k >= 0; k-- ) { - /* Interpolate NLSFs for first half */ - silk_interpolate( NLSF0_Q15, psEncC->prev_NLSFq_Q15, NLSF_Q15, k, psEncC->predictLPCOrder ); - - /* Convert to LPC for residual energy evaluation */ - silk_NLSF2A( a_tmp_Q12, NLSF0_Q15, psEncC->predictLPCOrder ); - - /* Calculate residual energy with NLSF interpolation */ - silk_LPC_analysis_filter( LPC_res, x, a_tmp_Q12, 2 * subfr_length, psEncC->predictLPCOrder ); - - silk_sum_sqr_shift( &res_nrg0, &rshift0, LPC_res + psEncC->predictLPCOrder, subfr_length - psEncC->predictLPCOrder ); - silk_sum_sqr_shift( &res_nrg1, &rshift1, LPC_res + psEncC->predictLPCOrder + subfr_length, subfr_length - psEncC->predictLPCOrder ); - - /* Add subframe energies from first half frame */ - shift = rshift0 - rshift1; - if( shift >= 0 ) { - res_nrg1 = silk_RSHIFT( res_nrg1, shift ); - res_nrg_interp_Q = -rshift0; - } else { - res_nrg0 = silk_RSHIFT( res_nrg0, -shift ); - res_nrg_interp_Q = -rshift1; - } - res_nrg_interp = silk_ADD32( res_nrg0, res_nrg1 ); - - /* Compare with first half energy without NLSF interpolation, or best interpolated value so far */ - shift = res_nrg_interp_Q - res_nrg_Q; - if( shift >= 0 ) { - if( silk_RSHIFT( res_nrg_interp, shift ) < res_nrg ) { - isInterpLower = silk_TRUE; - } else { - isInterpLower = silk_FALSE; - } - } else { - if( -shift < 32 ) { - if( res_nrg_interp < silk_RSHIFT( res_nrg, -shift ) ) { - isInterpLower = silk_TRUE; - } else { - isInterpLower = silk_FALSE; - } - } else { - isInterpLower = silk_FALSE; - } - } - - /* Determine whether current interpolated NLSFs are best so far */ - if( isInterpLower == silk_TRUE ) { - /* Interpolation has lower residual energy */ - res_nrg = res_nrg_interp; - res_nrg_Q = res_nrg_interp_Q; - psEncC->indices.NLSFInterpCoef_Q2 = (opus_int8)k; - } - } - } - - if( psEncC->indices.NLSFInterpCoef_Q2 == 4 ) { - /* NLSF interpolation is currently inactive, calculate NLSFs from full frame AR coefficients */ - silk_A2NLSF( NLSF_Q15, a_Q16, psEncC->predictLPCOrder ); - } - - silk_assert( psEncC->indices.NLSFInterpCoef_Q2 == 4 || ( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) ); -} diff --git a/src/opus-1.0.2/silk/fixed/find_LTP_FIX.c b/src/opus-1.0.2/silk/fixed/find_LTP_FIX.c deleted file mode 100644 index bd210874..00000000 --- a/src/opus-1.0.2/silk/fixed/find_LTP_FIX.c +++ /dev/null @@ -1,244 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main_FIX.h" -#include "tuning_parameters.h" - -/* Head room for correlations */ -#define LTP_CORRS_HEAD_ROOM 2 - -void silk_fit_LTP( - opus_int32 LTP_coefs_Q16[ LTP_ORDER ], - opus_int16 LTP_coefs_Q14[ LTP_ORDER ] -); - -void silk_find_LTP_FIX( - opus_int16 b_Q14[ MAX_NB_SUBFR * LTP_ORDER ], /* O LTP coefs */ - opus_int32 WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */ - opus_int *LTPredCodGain_Q7, /* O LTP coding gain */ - const opus_int16 r_lpc[], /* I residual signal after LPC signal + state for first 10 ms */ - const opus_int lag[ MAX_NB_SUBFR ], /* I LTP lags */ - const opus_int32 Wght_Q15[ MAX_NB_SUBFR ], /* I weights */ - const opus_int subfr_length, /* I subframe length */ - const opus_int nb_subfr, /* I number of subframes */ - const opus_int mem_offset, /* I number of samples in LTP memory */ - opus_int corr_rshifts[ MAX_NB_SUBFR ] /* O right shifts applied to correlations */ -) -{ - opus_int i, k, lshift; - const opus_int16 *r_ptr, *lag_ptr; - opus_int16 *b_Q14_ptr; - - opus_int32 regu; - opus_int32 *WLTP_ptr; - opus_int32 b_Q16[ LTP_ORDER ], delta_b_Q14[ LTP_ORDER ], d_Q14[ MAX_NB_SUBFR ], nrg[ MAX_NB_SUBFR ], g_Q26; - opus_int32 w[ MAX_NB_SUBFR ], WLTP_max, max_abs_d_Q14, max_w_bits; - - opus_int32 temp32, denom32; - opus_int extra_shifts; - opus_int rr_shifts, maxRshifts, maxRshifts_wxtra, LZs; - opus_int32 LPC_res_nrg, LPC_LTP_res_nrg, div_Q16; - opus_int32 Rr[ LTP_ORDER ], rr[ MAX_NB_SUBFR ]; - opus_int32 wd, m_Q12; - - b_Q14_ptr = b_Q14; - WLTP_ptr = WLTP; - r_ptr = &r_lpc[ mem_offset ]; - for( k = 0; k < nb_subfr; k++ ) { - lag_ptr = r_ptr - ( lag[ k ] + LTP_ORDER / 2 ); - - silk_sum_sqr_shift( &rr[ k ], &rr_shifts, r_ptr, subfr_length ); /* rr[ k ] in Q( -rr_shifts ) */ - - /* Assure headroom */ - LZs = silk_CLZ32( rr[k] ); - if( LZs < LTP_CORRS_HEAD_ROOM ) { - rr[ k ] = silk_RSHIFT_ROUND( rr[ k ], LTP_CORRS_HEAD_ROOM - LZs ); - rr_shifts += ( LTP_CORRS_HEAD_ROOM - LZs ); - } - corr_rshifts[ k ] = rr_shifts; - silk_corrMatrix_FIX( lag_ptr, subfr_length, LTP_ORDER, LTP_CORRS_HEAD_ROOM, WLTP_ptr, &corr_rshifts[ k ] ); /* WLTP_fix_ptr in Q( -corr_rshifts[ k ] ) */ - - /* The correlation vector always has lower max abs value than rr and/or RR so head room is assured */ - silk_corrVector_FIX( lag_ptr, r_ptr, subfr_length, LTP_ORDER, Rr, corr_rshifts[ k ] ); /* Rr_fix_ptr in Q( -corr_rshifts[ k ] ) */ - if( corr_rshifts[ k ] > rr_shifts ) { - rr[ k ] = silk_RSHIFT( rr[ k ], corr_rshifts[ k ] - rr_shifts ); /* rr[ k ] in Q( -corr_rshifts[ k ] ) */ - } - silk_assert( rr[ k ] >= 0 ); - - regu = 1; - regu = silk_SMLAWB( regu, rr[ k ], SILK_FIX_CONST( LTP_DAMPING/3, 16 ) ); - regu = silk_SMLAWB( regu, matrix_ptr( WLTP_ptr, 0, 0, LTP_ORDER ), SILK_FIX_CONST( LTP_DAMPING/3, 16 ) ); - regu = silk_SMLAWB( regu, matrix_ptr( WLTP_ptr, LTP_ORDER-1, LTP_ORDER-1, LTP_ORDER ), SILK_FIX_CONST( LTP_DAMPING/3, 16 ) ); - silk_regularize_correlations_FIX( WLTP_ptr, &rr[k], regu, LTP_ORDER ); - - silk_solve_LDL_FIX( WLTP_ptr, LTP_ORDER, Rr, b_Q16 ); /* WLTP_fix_ptr and Rr_fix_ptr both in Q(-corr_rshifts[k]) */ - - /* Limit and store in Q14 */ - silk_fit_LTP( b_Q16, b_Q14_ptr ); - - /* Calculate residual energy */ - nrg[ k ] = silk_residual_energy16_covar_FIX( b_Q14_ptr, WLTP_ptr, Rr, rr[ k ], LTP_ORDER, 14 ); /* nrg_fix in Q( -corr_rshifts[ k ] ) */ - - /* temp = Wght[ k ] / ( nrg[ k ] * Wght[ k ] + 0.01f * subfr_length ); */ - extra_shifts = silk_min_int( corr_rshifts[ k ], LTP_CORRS_HEAD_ROOM ); - denom32 = silk_LSHIFT_SAT32( silk_SMULWB( nrg[ k ], Wght_Q15[ k ] ), 1 + extra_shifts ) + /* Q( -corr_rshifts[ k ] + extra_shifts ) */ - silk_RSHIFT( silk_SMULWB( (opus_int32)subfr_length, 655 ), corr_rshifts[ k ] - extra_shifts ); /* Q( -corr_rshifts[ k ] + extra_shifts ) */ - denom32 = silk_max( denom32, 1 ); - silk_assert( ((opus_int64)Wght_Q15[ k ] << 16 ) < silk_int32_MAX ); /* Wght always < 0.5 in Q0 */ - temp32 = silk_DIV32( silk_LSHIFT( (opus_int32)Wght_Q15[ k ], 16 ), denom32 ); /* Q( 15 + 16 + corr_rshifts[k] - extra_shifts ) */ - temp32 = silk_RSHIFT( temp32, 31 + corr_rshifts[ k ] - extra_shifts - 26 ); /* Q26 */ - - /* Limit temp such that the below scaling never wraps around */ - WLTP_max = 0; - for( i = 0; i < LTP_ORDER * LTP_ORDER; i++ ) { - WLTP_max = silk_max( WLTP_ptr[ i ], WLTP_max ); - } - lshift = silk_CLZ32( WLTP_max ) - 1 - 3; /* keep 3 bits free for vq_nearest_neighbor_fix */ - silk_assert( 26 - 18 + lshift >= 0 ); - if( 26 - 18 + lshift < 31 ) { - temp32 = silk_min_32( temp32, silk_LSHIFT( (opus_int32)1, 26 - 18 + lshift ) ); - } - - silk_scale_vector32_Q26_lshift_18( WLTP_ptr, temp32, LTP_ORDER * LTP_ORDER ); /* WLTP_ptr in Q( 18 - corr_rshifts[ k ] ) */ - - w[ k ] = matrix_ptr( WLTP_ptr, LTP_ORDER/2, LTP_ORDER/2, LTP_ORDER ); /* w in Q( 18 - corr_rshifts[ k ] ) */ - silk_assert( w[k] >= 0 ); - - r_ptr += subfr_length; - b_Q14_ptr += LTP_ORDER; - WLTP_ptr += LTP_ORDER * LTP_ORDER; - } - - maxRshifts = 0; - for( k = 0; k < nb_subfr; k++ ) { - maxRshifts = silk_max_int( corr_rshifts[ k ], maxRshifts ); - } - - /* Compute LTP coding gain */ - if( LTPredCodGain_Q7 != NULL ) { - LPC_LTP_res_nrg = 0; - LPC_res_nrg = 0; - silk_assert( LTP_CORRS_HEAD_ROOM >= 2 ); /* Check that no overflow will happen when adding */ - for( k = 0; k < nb_subfr; k++ ) { - LPC_res_nrg = silk_ADD32( LPC_res_nrg, silk_RSHIFT( silk_ADD32( silk_SMULWB( rr[ k ], Wght_Q15[ k ] ), 1 ), 1 + ( maxRshifts - corr_rshifts[ k ] ) ) ); /* Q( -maxRshifts ) */ - LPC_LTP_res_nrg = silk_ADD32( LPC_LTP_res_nrg, silk_RSHIFT( silk_ADD32( silk_SMULWB( nrg[ k ], Wght_Q15[ k ] ), 1 ), 1 + ( maxRshifts - corr_rshifts[ k ] ) ) ); /* Q( -maxRshifts ) */ - } - LPC_LTP_res_nrg = silk_max( LPC_LTP_res_nrg, 1 ); /* avoid division by zero */ - - div_Q16 = silk_DIV32_varQ( LPC_res_nrg, LPC_LTP_res_nrg, 16 ); - *LTPredCodGain_Q7 = ( opus_int )silk_SMULBB( 3, silk_lin2log( div_Q16 ) - ( 16 << 7 ) ); - - silk_assert( *LTPredCodGain_Q7 == ( opus_int )silk_SAT16( silk_MUL( 3, silk_lin2log( div_Q16 ) - ( 16 << 7 ) ) ) ); - } - - /* smoothing */ - /* d = sum( B, 1 ); */ - b_Q14_ptr = b_Q14; - for( k = 0; k < nb_subfr; k++ ) { - d_Q14[ k ] = 0; - for( i = 0; i < LTP_ORDER; i++ ) { - d_Q14[ k ] += b_Q14_ptr[ i ]; - } - b_Q14_ptr += LTP_ORDER; - } - - /* m = ( w * d' ) / ( sum( w ) + 1e-3 ); */ - - /* Find maximum absolute value of d_Q14 and the bits used by w in Q0 */ - max_abs_d_Q14 = 0; - max_w_bits = 0; - for( k = 0; k < nb_subfr; k++ ) { - max_abs_d_Q14 = silk_max_32( max_abs_d_Q14, silk_abs( d_Q14[ k ] ) ); - /* w[ k ] is in Q( 18 - corr_rshifts[ k ] ) */ - /* Find bits needed in Q( 18 - maxRshifts ) */ - max_w_bits = silk_max_32( max_w_bits, 32 - silk_CLZ32( w[ k ] ) + corr_rshifts[ k ] - maxRshifts ); - } - - /* max_abs_d_Q14 = (5 << 15); worst case, i.e. LTP_ORDER * -silk_int16_MIN */ - silk_assert( max_abs_d_Q14 <= ( 5 << 15 ) ); - - /* How many bits is needed for w*d' in Q( 18 - maxRshifts ) in the worst case, of all d_Q14's being equal to max_abs_d_Q14 */ - extra_shifts = max_w_bits + 32 - silk_CLZ32( max_abs_d_Q14 ) - 14; - - /* Subtract what we got available; bits in output var plus maxRshifts */ - extra_shifts -= ( 32 - 1 - 2 + maxRshifts ); /* Keep sign bit free as well as 2 bits for accumulation */ - extra_shifts = silk_max_int( extra_shifts, 0 ); - - maxRshifts_wxtra = maxRshifts + extra_shifts; - - temp32 = silk_RSHIFT( 262, maxRshifts + extra_shifts ) + 1; /* 1e-3f in Q( 18 - (maxRshifts + extra_shifts) ) */ - wd = 0; - for( k = 0; k < nb_subfr; k++ ) { - /* w has at least 2 bits of headroom so no overflow should happen */ - temp32 = silk_ADD32( temp32, silk_RSHIFT( w[ k ], maxRshifts_wxtra - corr_rshifts[ k ] ) ); /* Q( 18 - maxRshifts_wxtra ) */ - wd = silk_ADD32( wd, silk_LSHIFT( silk_SMULWW( silk_RSHIFT( w[ k ], maxRshifts_wxtra - corr_rshifts[ k ] ), d_Q14[ k ] ), 2 ) ); /* Q( 18 - maxRshifts_wxtra ) */ - } - m_Q12 = silk_DIV32_varQ( wd, temp32, 12 ); - - b_Q14_ptr = b_Q14; - for( k = 0; k < nb_subfr; k++ ) { - /* w_fix[ k ] from Q( 18 - corr_rshifts[ k ] ) to Q( 16 ) */ - if( 2 - corr_rshifts[k] > 0 ) { - temp32 = silk_RSHIFT( w[ k ], 2 - corr_rshifts[ k ] ); - } else { - temp32 = silk_LSHIFT_SAT32( w[ k ], corr_rshifts[ k ] - 2 ); - } - - g_Q26 = silk_MUL( - silk_DIV32( - SILK_FIX_CONST( LTP_SMOOTHING, 26 ), - silk_RSHIFT( SILK_FIX_CONST( LTP_SMOOTHING, 26 ), 10 ) + temp32 ), /* Q10 */ - silk_LSHIFT_SAT32( silk_SUB_SAT32( (opus_int32)m_Q12, silk_RSHIFT( d_Q14[ k ], 2 ) ), 4 ) ); /* Q16 */ - - temp32 = 0; - for( i = 0; i < LTP_ORDER; i++ ) { - delta_b_Q14[ i ] = silk_max_16( b_Q14_ptr[ i ], 1638 ); /* 1638_Q14 = 0.1_Q0 */ - temp32 += delta_b_Q14[ i ]; /* Q14 */ - } - temp32 = silk_DIV32( g_Q26, temp32 ); /* Q14 -> Q12 */ - for( i = 0; i < LTP_ORDER; i++ ) { - b_Q14_ptr[ i ] = silk_LIMIT_32( (opus_int32)b_Q14_ptr[ i ] + silk_SMULWB( silk_LSHIFT_SAT32( temp32, 4 ), delta_b_Q14[ i ] ), -16000, 28000 ); - } - b_Q14_ptr += LTP_ORDER; - } -} - -void silk_fit_LTP( - opus_int32 LTP_coefs_Q16[ LTP_ORDER ], - opus_int16 LTP_coefs_Q14[ LTP_ORDER ] -) -{ - opus_int i; - - for( i = 0; i < LTP_ORDER; i++ ) { - LTP_coefs_Q14[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( LTP_coefs_Q16[ i ], 2 ) ); - } -} diff --git a/src/opus-1.0.2/silk/fixed/find_pitch_lags_FIX.c b/src/opus-1.0.2/silk/fixed/find_pitch_lags_FIX.c deleted file mode 100644 index 39c30487..00000000 --- a/src/opus-1.0.2/silk/fixed/find_pitch_lags_FIX.c +++ /dev/null @@ -1,137 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main_FIX.h" -#include "tuning_parameters.h" - -/* Find pitch lags */ -void silk_find_pitch_lags_FIX( - silk_encoder_state_FIX *psEnc, /* I/O encoder state */ - silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */ - opus_int16 res[], /* O residual */ - const opus_int16 x[] /* I Speech signal */ -) -{ - opus_int buf_len, i, scale; - opus_int32 thrhld_Q15, res_nrg; - const opus_int16 *x_buf, *x_buf_ptr; - opus_int16 Wsig[ FIND_PITCH_LPC_WIN_MAX ], *Wsig_ptr; - opus_int32 auto_corr[ MAX_FIND_PITCH_LPC_ORDER + 1 ]; - opus_int16 rc_Q15[ MAX_FIND_PITCH_LPC_ORDER ]; - opus_int32 A_Q24[ MAX_FIND_PITCH_LPC_ORDER ]; - opus_int16 A_Q12[ MAX_FIND_PITCH_LPC_ORDER ]; - - /******************************************/ - /* Set up buffer lengths etc based on Fs */ - /******************************************/ - buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length; - - /* Safety check */ - silk_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length ); - - x_buf = x - psEnc->sCmn.ltp_mem_length; - - /*************************************/ - /* Estimate LPC AR coefficients */ - /*************************************/ - - /* Calculate windowed signal */ - - /* First LA_LTP samples */ - x_buf_ptr = x_buf + buf_len - psEnc->sCmn.pitch_LPC_win_length; - Wsig_ptr = Wsig; - silk_apply_sine_window( Wsig_ptr, x_buf_ptr, 1, psEnc->sCmn.la_pitch ); - - /* Middle un - windowed samples */ - Wsig_ptr += psEnc->sCmn.la_pitch; - x_buf_ptr += psEnc->sCmn.la_pitch; - silk_memcpy( Wsig_ptr, x_buf_ptr, ( psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 ) ) * sizeof( opus_int16 ) ); - - /* Last LA_LTP samples */ - Wsig_ptr += psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 ); - x_buf_ptr += psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 ); - silk_apply_sine_window( Wsig_ptr, x_buf_ptr, 2, psEnc->sCmn.la_pitch ); - - /* Calculate autocorrelation sequence */ - silk_autocorr( auto_corr, &scale, Wsig, psEnc->sCmn.pitch_LPC_win_length, psEnc->sCmn.pitchEstimationLPCOrder + 1 ); - - /* Add white noise, as fraction of energy */ - auto_corr[ 0 ] = silk_SMLAWB( auto_corr[ 0 ], auto_corr[ 0 ], SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) ) + 1; - - /* Calculate the reflection coefficients using schur */ - res_nrg = silk_schur( rc_Q15, auto_corr, psEnc->sCmn.pitchEstimationLPCOrder ); - - /* Prediction gain */ - psEncCtrl->predGain_Q16 = silk_DIV32_varQ( auto_corr[ 0 ], silk_max_int( res_nrg, 1 ), 16 ); - - /* Convert reflection coefficients to prediction coefficients */ - silk_k2a( A_Q24, rc_Q15, psEnc->sCmn.pitchEstimationLPCOrder ); - - /* Convert From 32 bit Q24 to 16 bit Q12 coefs */ - for( i = 0; i < psEnc->sCmn.pitchEstimationLPCOrder; i++ ) { - A_Q12[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT( A_Q24[ i ], 12 ) ); - } - - /* Do BWE */ - silk_bwexpander( A_Q12, psEnc->sCmn.pitchEstimationLPCOrder, SILK_FIX_CONST( FIND_PITCH_BANDWIDTH_EXPANSION, 16 ) ); - - /*****************************************/ - /* LPC analysis filtering */ - /*****************************************/ - silk_LPC_analysis_filter( res, x_buf, A_Q12, buf_len, psEnc->sCmn.pitchEstimationLPCOrder ); - - if( psEnc->sCmn.indices.signalType != TYPE_NO_VOICE_ACTIVITY && psEnc->sCmn.first_frame_after_reset == 0 ) { - /* Threshold for pitch estimator */ - thrhld_Q15 = SILK_FIX_CONST( 0.6, 15 ); - thrhld_Q15 = silk_SMLABB( thrhld_Q15, SILK_FIX_CONST( -0.004, 15 ), psEnc->sCmn.pitchEstimationLPCOrder ); - thrhld_Q15 = silk_SMLABB( thrhld_Q15, SILK_FIX_CONST( -0.1, 7 ), psEnc->sCmn.speech_activity_Q8 ); - thrhld_Q15 = silk_SMLABB( thrhld_Q15, SILK_FIX_CONST( -0.15, 15 ), silk_RSHIFT( psEnc->sCmn.prevSignalType, 1 ) ); - thrhld_Q15 = silk_SMLAWB( thrhld_Q15, SILK_FIX_CONST( -0.1, 16 ), psEnc->sCmn.input_tilt_Q15 ); - thrhld_Q15 = silk_SAT16( thrhld_Q15 ); - - /*****************************************/ - /* Call pitch estimator */ - /*****************************************/ - if( silk_pitch_analysis_core( res, psEncCtrl->pitchL, &psEnc->sCmn.indices.lagIndex, &psEnc->sCmn.indices.contourIndex, - &psEnc->LTPCorr_Q15, psEnc->sCmn.prevLag, psEnc->sCmn.pitchEstimationThreshold_Q16, - (opus_int16)thrhld_Q15, psEnc->sCmn.fs_kHz, psEnc->sCmn.pitchEstimationComplexity, psEnc->sCmn.nb_subfr ) == 0 ) - { - psEnc->sCmn.indices.signalType = TYPE_VOICED; - } else { - psEnc->sCmn.indices.signalType = TYPE_UNVOICED; - } - } else { - silk_memset( psEncCtrl->pitchL, 0, sizeof( psEncCtrl->pitchL ) ); - psEnc->sCmn.indices.lagIndex = 0; - psEnc->sCmn.indices.contourIndex = 0; - psEnc->LTPCorr_Q15 = 0; - } -} diff --git a/src/opus-1.0.2/silk/fixed/find_pred_coefs_FIX.c b/src/opus-1.0.2/silk/fixed/find_pred_coefs_FIX.c deleted file mode 100644 index 997989b5..00000000 --- a/src/opus-1.0.2/silk/fixed/find_pred_coefs_FIX.c +++ /dev/null @@ -1,136 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main_FIX.h" - -void silk_find_pred_coefs_FIX( - silk_encoder_state_FIX *psEnc, /* I/O encoder state */ - silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */ - const opus_int16 res_pitch[], /* I Residual from pitch analysis */ - const opus_int16 x[], /* I Speech signal */ - opus_int condCoding /* I The type of conditional coding to use */ -) -{ - opus_int i; - opus_int32 WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ]; - opus_int32 invGains_Q16[ MAX_NB_SUBFR ], local_gains[ MAX_NB_SUBFR ], Wght_Q15[ MAX_NB_SUBFR ]; - opus_int16 NLSF_Q15[ MAX_LPC_ORDER ]; - const opus_int16 *x_ptr; - opus_int16 *x_pre_ptr, LPC_in_pre[ MAX_NB_SUBFR * MAX_LPC_ORDER + MAX_FRAME_LENGTH ]; - opus_int32 tmp, min_gain_Q16, minInvGain_Q30; - opus_int LTP_corrs_rshift[ MAX_NB_SUBFR ]; - - /* weighting for weighted least squares */ - min_gain_Q16 = silk_int32_MAX >> 6; - for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { - min_gain_Q16 = silk_min( min_gain_Q16, psEncCtrl->Gains_Q16[ i ] ); - } - for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { - /* Divide to Q16 */ - silk_assert( psEncCtrl->Gains_Q16[ i ] > 0 ); - /* Invert and normalize gains, and ensure that maximum invGains_Q16 is within range of a 16 bit int */ - invGains_Q16[ i ] = silk_DIV32_varQ( min_gain_Q16, psEncCtrl->Gains_Q16[ i ], 16 - 2 ); - - /* Ensure Wght_Q15 a minimum value 1 */ - invGains_Q16[ i ] = silk_max( invGains_Q16[ i ], 363 ); - - /* Square the inverted gains */ - silk_assert( invGains_Q16[ i ] == silk_SAT16( invGains_Q16[ i ] ) ); - tmp = silk_SMULWB( invGains_Q16[ i ], invGains_Q16[ i ] ); - Wght_Q15[ i ] = silk_RSHIFT( tmp, 1 ); - - /* Invert the inverted and normalized gains */ - local_gains[ i ] = silk_DIV32( ( (opus_int32)1 << 16 ), invGains_Q16[ i ] ); - } - - if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - /**********/ - /* VOICED */ - /**********/ - silk_assert( psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->pitchL[ 0 ] + LTP_ORDER / 2 ); - - /* LTP analysis */ - silk_find_LTP_FIX( psEncCtrl->LTPCoef_Q14, WLTP, &psEncCtrl->LTPredCodGain_Q7, - res_pitch, psEncCtrl->pitchL, Wght_Q15, psEnc->sCmn.subfr_length, - psEnc->sCmn.nb_subfr, psEnc->sCmn.ltp_mem_length, LTP_corrs_rshift ); - - /* Quantize LTP gain parameters */ - silk_quant_LTP_gains( psEncCtrl->LTPCoef_Q14, psEnc->sCmn.indices.LTPIndex, &psEnc->sCmn.indices.PERIndex, - WLTP, psEnc->sCmn.mu_LTP_Q9, psEnc->sCmn.LTPQuantLowComplexity, psEnc->sCmn.nb_subfr); - - /* Control LTP scaling */ - silk_LTP_scale_ctrl_FIX( psEnc, psEncCtrl, condCoding ); - - /* Create LTP residual */ - silk_LTP_analysis_filter_FIX( LPC_in_pre, x - psEnc->sCmn.predictLPCOrder, psEncCtrl->LTPCoef_Q14, - psEncCtrl->pitchL, invGains_Q16, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder ); - - } else { - /************/ - /* UNVOICED */ - /************/ - /* Create signal with prepended subframes, scaled by inverse gains */ - x_ptr = x - psEnc->sCmn.predictLPCOrder; - x_pre_ptr = LPC_in_pre; - for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { - silk_scale_copy_vector16( x_pre_ptr, x_ptr, invGains_Q16[ i ], - psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder ); - x_pre_ptr += psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder; - x_ptr += psEnc->sCmn.subfr_length; - } - - silk_memset( psEncCtrl->LTPCoef_Q14, 0, psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( opus_int16 ) ); - psEncCtrl->LTPredCodGain_Q7 = 0; - } - - /* Limit on total predictive coding gain */ - if( psEnc->sCmn.first_frame_after_reset ) { - minInvGain_Q30 = SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN_AFTER_RESET, 30 ); - } else { - minInvGain_Q30 = silk_log2lin( silk_SMLAWB( 16 << 7, (opus_int32)psEncCtrl->LTPredCodGain_Q7, SILK_FIX_CONST( 1.0 / 3, 16 ) ) ); /* Q16 */ - minInvGain_Q30 = silk_DIV32_varQ( minInvGain_Q30, - silk_SMULWW( SILK_FIX_CONST( MAX_PREDICTION_POWER_GAIN, 0 ), - silk_SMLAWB( SILK_FIX_CONST( 0.25, 18 ), SILK_FIX_CONST( 0.75, 18 ), psEncCtrl->coding_quality_Q14 ) ), 14 ); - } - - /* LPC_in_pre contains the LTP-filtered input for voiced, and the unfiltered input for unvoiced */ - silk_find_LPC_FIX( &psEnc->sCmn, NLSF_Q15, LPC_in_pre, minInvGain_Q30 ); - - /* Quantize LSFs */ - silk_process_NLSFs( &psEnc->sCmn, psEncCtrl->PredCoef_Q12, NLSF_Q15, psEnc->sCmn.prev_NLSFq_Q15 ); - - /* Calculate residual energy using quantized LPC coefficients */ - silk_residual_energy_FIX( psEncCtrl->ResNrg, psEncCtrl->ResNrgQ, LPC_in_pre, psEncCtrl->PredCoef_Q12, local_gains, - psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder ); - - /* Copy to prediction struct for use in next frame for interpolation */ - silk_memcpy( psEnc->sCmn.prev_NLSFq_Q15, NLSF_Q15, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) ); -} diff --git a/src/opus-1.0.2/silk/fixed/k2a_FIX.c b/src/opus-1.0.2/silk/fixed/k2a_FIX.c deleted file mode 100644 index cadc9274..00000000 --- a/src/opus-1.0.2/silk/fixed/k2a_FIX.c +++ /dev/null @@ -1,53 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "SigProc_FIX.h" - -/* Step up function, converts reflection coefficients to prediction coefficients */ -void silk_k2a( - opus_int32 *A_Q24, /* O Prediction coefficients [order] Q24 */ - const opus_int16 *rc_Q15, /* I Reflection coefficients [order] Q15 */ - const opus_int32 order /* I Prediction order */ -) -{ - opus_int k, n; - opus_int32 Atmp[ SILK_MAX_ORDER_LPC ]; - - for( k = 0; k < order; k++ ) { - for( n = 0; n < k; n++ ) { - Atmp[ n ] = A_Q24[ n ]; - } - for( n = 0; n < k; n++ ) { - A_Q24[ n ] = silk_SMLAWB( A_Q24[ n ], silk_LSHIFT( Atmp[ k - n - 1 ], 1 ), rc_Q15[ k ] ); - } - A_Q24[ k ] = -silk_LSHIFT( (opus_int32)rc_Q15[ k ], 9 ); - } -} diff --git a/src/opus-1.0.2/silk/fixed/k2a_Q16_FIX.c b/src/opus-1.0.2/silk/fixed/k2a_Q16_FIX.c deleted file mode 100644 index f96f3064..00000000 --- a/src/opus-1.0.2/silk/fixed/k2a_Q16_FIX.c +++ /dev/null @@ -1,53 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "SigProc_FIX.h" - -/* Step up function, converts reflection coefficients to prediction coefficients */ -void silk_k2a_Q16( - opus_int32 *A_Q24, /* O Prediction coefficients [order] Q24 */ - const opus_int32 *rc_Q16, /* I Reflection coefficients [order] Q16 */ - const opus_int32 order /* I Prediction order */ -) -{ - opus_int k, n; - opus_int32 Atmp[ SILK_MAX_ORDER_LPC ]; - - for( k = 0; k < order; k++ ) { - for( n = 0; n < k; n++ ) { - Atmp[ n ] = A_Q24[ n ]; - } - for( n = 0; n < k; n++ ) { - A_Q24[ n ] = silk_SMLAWW( A_Q24[ n ], Atmp[ k - n - 1 ], rc_Q16[ k ] ); - } - A_Q24[ k ] = -silk_LSHIFT( rc_Q16[ k ], 8 ); - } -} diff --git a/src/opus-1.0.2/silk/fixed/main_FIX.h b/src/opus-1.0.2/silk/fixed/main_FIX.h deleted file mode 100644 index 369b31ee..00000000 --- a/src/opus-1.0.2/silk/fixed/main_FIX.h +++ /dev/null @@ -1,254 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifndef SILK_MAIN_FIX_H -#define SILK_MAIN_FIX_H - -#include "SigProc_FIX.h" -#include "structs_FIX.h" -#include "control.h" -#include "main.h" -#include "PLC.h" -#include "debug.h" -#include "entenc.h" - -#ifndef FORCE_CPP_BUILD -#ifdef __cplusplus -extern "C" -{ -#endif -#endif - -#define silk_encoder_state_Fxx silk_encoder_state_FIX -#define silk_encode_do_VAD_Fxx silk_encode_do_VAD_FIX -#define silk_encode_frame_Fxx silk_encode_frame_FIX - -/*********************/ -/* Encoder Functions */ -/*********************/ - -/* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */ -void silk_HP_variable_cutoff( - silk_encoder_state_Fxx state_Fxx[] /* I/O Encoder states */ -); - -/* Encoder main function */ -void silk_encode_do_VAD_FIX( - silk_encoder_state_FIX *psEnc /* I/O Pointer to Silk FIX encoder state */ -); - -/* Encoder main function */ -opus_int silk_encode_frame_FIX( - silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ - opus_int32 *pnBytesOut, /* O Pointer to number of payload bytes; */ - ec_enc *psRangeEnc, /* I/O compressor data structure */ - opus_int condCoding, /* I The type of conditional coding to use */ - opus_int maxBits, /* I If > 0: maximum number of output bits */ - opus_int useCBR /* I Flag to force constant-bitrate operation */ -); - -/* Initializes the Silk encoder state */ -opus_int silk_init_encoder( - silk_encoder_state_Fxx *psEnc /* I/O Pointer to Silk FIX encoder state */ -); - -/* Control the Silk encoder */ -opus_int silk_control_encoder( - silk_encoder_state_Fxx *psEnc, /* I/O Pointer to Silk encoder state */ - silk_EncControlStruct *encControl, /* I Control structure */ - const opus_int32 TargetRate_bps, /* I Target max bitrate (bps) */ - const opus_int allow_bw_switch, /* I Flag to allow switching audio bandwidth */ - const opus_int channelNb, /* I Channel number */ - const opus_int force_fs_kHz -); - -/****************/ -/* Prefiltering */ -/****************/ -void silk_prefilter_FIX( - silk_encoder_state_FIX *psEnc, /* I/O Encoder state */ - const silk_encoder_control_FIX *psEncCtrl, /* I Encoder control */ - opus_int32 xw_Q10[], /* O Weighted signal */ - const opus_int16 x[] /* I Speech signal */ -); - -/**************************/ -/* Noise shaping analysis */ -/**************************/ -/* Compute noise shaping coefficients and initial gain values */ -void silk_noise_shape_analysis_FIX( - silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */ - silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control FIX */ - const opus_int16 *pitch_res, /* I LPC residual from pitch analysis */ - const opus_int16 *x /* I Input signal [ frame_length + la_shape ] */ -); - -/* Autocorrelations for a warped frequency axis */ -void silk_warped_autocorrelation_FIX( - opus_int32 *corr, /* O Result [order + 1] */ - opus_int *scale, /* O Scaling of the correlation vector */ - const opus_int16 *input, /* I Input data to correlate */ - const opus_int warping_Q16, /* I Warping coefficient */ - const opus_int length, /* I Length of input */ - const opus_int order /* I Correlation order (even) */ -); - -/* Calculation of LTP state scaling */ -void silk_LTP_scale_ctrl_FIX( - silk_encoder_state_FIX *psEnc, /* I/O encoder state */ - silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */ - opus_int condCoding /* I The type of conditional coding to use */ -); - -/**********************************************/ -/* Prediction Analysis */ -/**********************************************/ -/* Find pitch lags */ -void silk_find_pitch_lags_FIX( - silk_encoder_state_FIX *psEnc, /* I/O encoder state */ - silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */ - opus_int16 res[], /* O residual */ - const opus_int16 x[] /* I Speech signal */ -); - -/* Find LPC and LTP coefficients */ -void silk_find_pred_coefs_FIX( - silk_encoder_state_FIX *psEnc, /* I/O encoder state */ - silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */ - const opus_int16 res_pitch[], /* I Residual from pitch analysis */ - const opus_int16 x[], /* I Speech signal */ - opus_int condCoding /* I The type of conditional coding to use */ -); - -/* LPC analysis */ -void silk_find_LPC_FIX( - silk_encoder_state *psEncC, /* I/O Encoder state */ - opus_int16 NLSF_Q15[], /* O NLSFs */ - const opus_int16 x[], /* I Input signal */ - const opus_int32 minInvGain_Q30 /* I Inverse of max prediction gain */ -); - -/* LTP analysis */ -void silk_find_LTP_FIX( - opus_int16 b_Q14[ MAX_NB_SUBFR * LTP_ORDER ], /* O LTP coefs */ - opus_int32 WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */ - opus_int *LTPredCodGain_Q7, /* O LTP coding gain */ - const opus_int16 r_lpc[], /* I residual signal after LPC signal + state for first 10 ms */ - const opus_int lag[ MAX_NB_SUBFR ], /* I LTP lags */ - const opus_int32 Wght_Q15[ MAX_NB_SUBFR ], /* I weights */ - const opus_int subfr_length, /* I subframe length */ - const opus_int nb_subfr, /* I number of subframes */ - const opus_int mem_offset, /* I number of samples in LTP memory */ - opus_int corr_rshifts[ MAX_NB_SUBFR ] /* O right shifts applied to correlations */ -); - -void silk_LTP_analysis_filter_FIX( - opus_int16 *LTP_res, /* O LTP residual signal of length MAX_NB_SUBFR * ( pre_length + subfr_length ) */ - const opus_int16 *x, /* I Pointer to input signal with at least max( pitchL ) preceding samples */ - const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],/* I LTP_ORDER LTP coefficients for each MAX_NB_SUBFR subframe */ - const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag, one for each subframe */ - const opus_int32 invGains_Q16[ MAX_NB_SUBFR ], /* I Inverse quantization gains, one for each subframe */ - const opus_int subfr_length, /* I Length of each subframe */ - const opus_int nb_subfr, /* I Number of subframes */ - const opus_int pre_length /* I Length of the preceding samples starting at &x[0] for each subframe */ -); - -/* Calculates residual energies of input subframes where all subframes have LPC_order */ -/* of preceding samples */ -void silk_residual_energy_FIX( - opus_int32 nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */ - opus_int nrgsQ[ MAX_NB_SUBFR ], /* O Q value per subframe */ - const opus_int16 x[], /* I Input signal */ - opus_int16 a_Q12[ 2 ][ MAX_LPC_ORDER ], /* I AR coefs for each frame half */ - const opus_int32 gains[ MAX_NB_SUBFR ], /* I Quantization gains */ - const opus_int subfr_length, /* I Subframe length */ - const opus_int nb_subfr, /* I Number of subframes */ - const opus_int LPC_order /* I LPC order */ -); - -/* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */ -opus_int32 silk_residual_energy16_covar_FIX( - const opus_int16 *c, /* I Prediction vector */ - const opus_int32 *wXX, /* I Correlation matrix */ - const opus_int32 *wXx, /* I Correlation vector */ - opus_int32 wxx, /* I Signal energy */ - opus_int D, /* I Dimension */ - opus_int cQ /* I Q value for c vector 0 - 15 */ -); - -/* Processing of gains */ -void silk_process_gains_FIX( - silk_encoder_state_FIX *psEnc, /* I/O Encoder state */ - silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control */ - opus_int condCoding /* I The type of conditional coding to use */ -); - -/******************/ -/* Linear Algebra */ -/******************/ -/* Calculates correlation matrix X'*X */ -void silk_corrMatrix_FIX( - const opus_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */ - const opus_int L, /* I Length of vectors */ - const opus_int order, /* I Max lag for correlation */ - const opus_int head_room, /* I Desired headroom */ - opus_int32 *XX, /* O Pointer to X'*X correlation matrix [ order x order ] */ - opus_int *rshifts /* I/O Right shifts of correlations */ -); - -/* Calculates correlation vector X'*t */ -void silk_corrVector_FIX( - const opus_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */ - const opus_int16 *t, /* I Target vector [L] */ - const opus_int L, /* I Length of vectors */ - const opus_int order, /* I Max lag for correlation */ - opus_int32 *Xt, /* O Pointer to X'*t correlation vector [order] */ - const opus_int rshifts /* I Right shifts of correlations */ -); - -/* Add noise to matrix diagonal */ -void silk_regularize_correlations_FIX( - opus_int32 *XX, /* I/O Correlation matrices */ - opus_int32 *xx, /* I/O Correlation values */ - opus_int32 noise, /* I Noise to add */ - opus_int D /* I Dimension of XX */ -); - -/* Solves Ax = b, assuming A is symmetric */ -void silk_solve_LDL_FIX( - opus_int32 *A, /* I Pointer to symetric square matrix A */ - opus_int M, /* I Size of matrix */ - const opus_int32 *b, /* I Pointer to b vector */ - opus_int32 *x_Q16 /* O Pointer to x solution vector */ -); - -#ifndef FORCE_CPP_BUILD -#ifdef __cplusplus -} -#endif /* __cplusplus */ -#endif /* FORCE_CPP_BUILD */ -#endif /* SILK_MAIN_FIX_H */ diff --git a/src/opus-1.0.2/silk/fixed/noise_shape_analysis_FIX.c b/src/opus-1.0.2/silk/fixed/noise_shape_analysis_FIX.c deleted file mode 100644 index d230e48d..00000000 --- a/src/opus-1.0.2/silk/fixed/noise_shape_analysis_FIX.c +++ /dev/null @@ -1,440 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main_FIX.h" -#include "tuning_parameters.h" - -/* Compute gain to make warped filter coefficients have a zero mean log frequency response on a */ -/* non-warped frequency scale. (So that it can be implemented with a minimum-phase monic filter.) */ -/* Note: A monic filter is one with the first coefficient equal to 1.0. In Silk we omit the first */ -/* coefficient in an array of coefficients, for monic filters. */ -static inline opus_int32 warped_gain( /* gain in Q16*/ - const opus_int32 *coefs_Q24, - opus_int lambda_Q16, - opus_int order -) { - opus_int i; - opus_int32 gain_Q24; - - lambda_Q16 = -lambda_Q16; - gain_Q24 = coefs_Q24[ order - 1 ]; - for( i = order - 2; i >= 0; i-- ) { - gain_Q24 = silk_SMLAWB( coefs_Q24[ i ], gain_Q24, lambda_Q16 ); - } - gain_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), gain_Q24, -lambda_Q16 ); - return silk_INVERSE32_varQ( gain_Q24, 40 ); -} - -/* Convert warped filter coefficients to monic pseudo-warped coefficients and limit maximum */ -/* amplitude of monic warped coefficients by using bandwidth expansion on the true coefficients */ -static inline void limit_warped_coefs( - opus_int32 *coefs_syn_Q24, - opus_int32 *coefs_ana_Q24, - opus_int lambda_Q16, - opus_int32 limit_Q24, - opus_int order -) { - opus_int i, iter, ind = 0; - opus_int32 tmp, maxabs_Q24, chirp_Q16, gain_syn_Q16, gain_ana_Q16; - opus_int32 nom_Q16, den_Q24; - - /* Convert to monic coefficients */ - lambda_Q16 = -lambda_Q16; - for( i = order - 1; i > 0; i-- ) { - coefs_syn_Q24[ i - 1 ] = silk_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 ); - coefs_ana_Q24[ i - 1 ] = silk_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 ); - } - lambda_Q16 = -lambda_Q16; - nom_Q16 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -(opus_int32)lambda_Q16, lambda_Q16 ); - den_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_syn_Q24[ 0 ], lambda_Q16 ); - gain_syn_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 ); - den_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_ana_Q24[ 0 ], lambda_Q16 ); - gain_ana_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 ); - for( i = 0; i < order; i++ ) { - coefs_syn_Q24[ i ] = silk_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] ); - coefs_ana_Q24[ i ] = silk_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] ); - } - - for( iter = 0; iter < 10; iter++ ) { - /* Find maximum absolute value */ - maxabs_Q24 = -1; - for( i = 0; i < order; i++ ) { - tmp = silk_max( silk_abs_int32( coefs_syn_Q24[ i ] ), silk_abs_int32( coefs_ana_Q24[ i ] ) ); - if( tmp > maxabs_Q24 ) { - maxabs_Q24 = tmp; - ind = i; - } - } - if( maxabs_Q24 <= limit_Q24 ) { - /* Coefficients are within range - done */ - return; - } - - /* Convert back to true warped coefficients */ - for( i = 1; i < order; i++ ) { - coefs_syn_Q24[ i - 1 ] = silk_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 ); - coefs_ana_Q24[ i - 1 ] = silk_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 ); - } - gain_syn_Q16 = silk_INVERSE32_varQ( gain_syn_Q16, 32 ); - gain_ana_Q16 = silk_INVERSE32_varQ( gain_ana_Q16, 32 ); - for( i = 0; i < order; i++ ) { - coefs_syn_Q24[ i ] = silk_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] ); - coefs_ana_Q24[ i ] = silk_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] ); - } - - /* Apply bandwidth expansion */ - chirp_Q16 = SILK_FIX_CONST( 0.99, 16 ) - silk_DIV32_varQ( - silk_SMULWB( maxabs_Q24 - limit_Q24, silk_SMLABB( SILK_FIX_CONST( 0.8, 10 ), SILK_FIX_CONST( 0.1, 10 ), iter ) ), - silk_MUL( maxabs_Q24, ind + 1 ), 22 ); - silk_bwexpander_32( coefs_syn_Q24, order, chirp_Q16 ); - silk_bwexpander_32( coefs_ana_Q24, order, chirp_Q16 ); - - /* Convert to monic warped coefficients */ - lambda_Q16 = -lambda_Q16; - for( i = order - 1; i > 0; i-- ) { - coefs_syn_Q24[ i - 1 ] = silk_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 ); - coefs_ana_Q24[ i - 1 ] = silk_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 ); - } - lambda_Q16 = -lambda_Q16; - nom_Q16 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -(opus_int32)lambda_Q16, lambda_Q16 ); - den_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_syn_Q24[ 0 ], lambda_Q16 ); - gain_syn_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 ); - den_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_ana_Q24[ 0 ], lambda_Q16 ); - gain_ana_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 ); - for( i = 0; i < order; i++ ) { - coefs_syn_Q24[ i ] = silk_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] ); - coefs_ana_Q24[ i ] = silk_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] ); - } - } - silk_assert( 0 ); -} - -/**************************************************************/ -/* Compute noise shaping coefficients and initial gain values */ -/**************************************************************/ -void silk_noise_shape_analysis_FIX( - silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */ - silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control FIX */ - const opus_int16 *pitch_res, /* I LPC residual from pitch analysis */ - const opus_int16 *x /* I Input signal [ frame_length + la_shape ] */ -) -{ - silk_shape_state_FIX *psShapeSt = &psEnc->sShape; - opus_int k, i, nSamples, Qnrg, b_Q14, warping_Q16, scale = 0; - opus_int32 SNR_adj_dB_Q7, HarmBoost_Q16, HarmShapeGain_Q16, Tilt_Q16, tmp32; - opus_int32 nrg, pre_nrg_Q30, log_energy_Q7, log_energy_prev_Q7, energy_variation_Q7; - opus_int32 delta_Q16, BWExp1_Q16, BWExp2_Q16, gain_mult_Q16, gain_add_Q16, strength_Q16, b_Q8; - opus_int32 auto_corr[ MAX_SHAPE_LPC_ORDER + 1 ]; - opus_int32 refl_coef_Q16[ MAX_SHAPE_LPC_ORDER ]; - opus_int32 AR1_Q24[ MAX_SHAPE_LPC_ORDER ]; - opus_int32 AR2_Q24[ MAX_SHAPE_LPC_ORDER ]; - opus_int16 x_windowed[ SHAPE_LPC_WIN_MAX ]; - const opus_int16 *x_ptr, *pitch_res_ptr; - - /* Point to start of first LPC analysis block */ - x_ptr = x - psEnc->sCmn.la_shape; - - /****************/ - /* GAIN CONTROL */ - /****************/ - SNR_adj_dB_Q7 = psEnc->sCmn.SNR_dB_Q7; - - /* Input quality is the average of the quality in the lowest two VAD bands */ - psEncCtrl->input_quality_Q14 = ( opus_int )silk_RSHIFT( (opus_int32)psEnc->sCmn.input_quality_bands_Q15[ 0 ] - + psEnc->sCmn.input_quality_bands_Q15[ 1 ], 2 ); - - /* Coding quality level, between 0.0_Q0 and 1.0_Q0, but in Q14 */ - psEncCtrl->coding_quality_Q14 = silk_RSHIFT( silk_sigm_Q15( silk_RSHIFT_ROUND( SNR_adj_dB_Q7 - - SILK_FIX_CONST( 20.0, 7 ), 4 ) ), 1 ); - - /* Reduce coding SNR during low speech activity */ - if( psEnc->sCmn.useCBR == 0 ) { - b_Q8 = SILK_FIX_CONST( 1.0, 8 ) - psEnc->sCmn.speech_activity_Q8; - b_Q8 = silk_SMULWB( silk_LSHIFT( b_Q8, 8 ), b_Q8 ); - SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, - silk_SMULBB( SILK_FIX_CONST( -BG_SNR_DECR_dB, 7 ) >> ( 4 + 1 ), b_Q8 ), /* Q11*/ - silk_SMULWB( SILK_FIX_CONST( 1.0, 14 ) + psEncCtrl->input_quality_Q14, psEncCtrl->coding_quality_Q14 ) ); /* Q12*/ - } - - if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - /* Reduce gains for periodic signals */ - SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, SILK_FIX_CONST( HARM_SNR_INCR_dB, 8 ), psEnc->LTPCorr_Q15 ); - } else { - /* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */ - SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, - silk_SMLAWB( SILK_FIX_CONST( 6.0, 9 ), -SILK_FIX_CONST( 0.4, 18 ), psEnc->sCmn.SNR_dB_Q7 ), - SILK_FIX_CONST( 1.0, 14 ) - psEncCtrl->input_quality_Q14 ); - } - - /*************************/ - /* SPARSENESS PROCESSING */ - /*************************/ - /* Set quantizer offset */ - if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - /* Initially set to 0; may be overruled in process_gains(..) */ - psEnc->sCmn.indices.quantOffsetType = 0; - psEncCtrl->sparseness_Q8 = 0; - } else { - /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */ - nSamples = silk_LSHIFT( psEnc->sCmn.fs_kHz, 1 ); - energy_variation_Q7 = 0; - log_energy_prev_Q7 = 0; - pitch_res_ptr = pitch_res; - for( k = 0; k < silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2; k++ ) { - silk_sum_sqr_shift( &nrg, &scale, pitch_res_ptr, nSamples ); - nrg += silk_RSHIFT( nSamples, scale ); /* Q(-scale)*/ - - log_energy_Q7 = silk_lin2log( nrg ); - if( k > 0 ) { - energy_variation_Q7 += silk_abs( log_energy_Q7 - log_energy_prev_Q7 ); - } - log_energy_prev_Q7 = log_energy_Q7; - pitch_res_ptr += nSamples; - } - - psEncCtrl->sparseness_Q8 = silk_RSHIFT( silk_sigm_Q15( silk_SMULWB( energy_variation_Q7 - - SILK_FIX_CONST( 5.0, 7 ), SILK_FIX_CONST( 0.1, 16 ) ) ), 7 ); - - /* Set quantization offset depending on sparseness measure */ - if( psEncCtrl->sparseness_Q8 > SILK_FIX_CONST( SPARSENESS_THRESHOLD_QNT_OFFSET, 8 ) ) { - psEnc->sCmn.indices.quantOffsetType = 0; - } else { - psEnc->sCmn.indices.quantOffsetType = 1; - } - - /* Increase coding SNR for sparse signals */ - SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, SILK_FIX_CONST( SPARSE_SNR_INCR_dB, 15 ), psEncCtrl->sparseness_Q8 - SILK_FIX_CONST( 0.5, 8 ) ); - } - - /*******************************/ - /* Control bandwidth expansion */ - /*******************************/ - /* More BWE for signals with high prediction gain */ - strength_Q16 = silk_SMULWB( psEncCtrl->predGain_Q16, SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) ); - BWExp1_Q16 = BWExp2_Q16 = silk_DIV32_varQ( SILK_FIX_CONST( BANDWIDTH_EXPANSION, 16 ), - silk_SMLAWW( SILK_FIX_CONST( 1.0, 16 ), strength_Q16, strength_Q16 ), 16 ); - delta_Q16 = silk_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - silk_SMULBB( 3, psEncCtrl->coding_quality_Q14 ), - SILK_FIX_CONST( LOW_RATE_BANDWIDTH_EXPANSION_DELTA, 16 ) ); - BWExp1_Q16 = silk_SUB32( BWExp1_Q16, delta_Q16 ); - BWExp2_Q16 = silk_ADD32( BWExp2_Q16, delta_Q16 ); - /* BWExp1 will be applied after BWExp2, so make it relative */ - BWExp1_Q16 = silk_DIV32_16( silk_LSHIFT( BWExp1_Q16, 14 ), silk_RSHIFT( BWExp2_Q16, 2 ) ); - - if( psEnc->sCmn.warping_Q16 > 0 ) { - /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */ - warping_Q16 = silk_SMLAWB( psEnc->sCmn.warping_Q16, (opus_int32)psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( 0.01, 18 ) ); - } else { - warping_Q16 = 0; - } - - /********************************************/ - /* Compute noise shaping AR coefs and gains */ - /********************************************/ - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - /* Apply window: sine slope followed by flat part followed by cosine slope */ - opus_int shift, slope_part, flat_part; - flat_part = psEnc->sCmn.fs_kHz * 3; - slope_part = silk_RSHIFT( psEnc->sCmn.shapeWinLength - flat_part, 1 ); - - silk_apply_sine_window( x_windowed, x_ptr, 1, slope_part ); - shift = slope_part; - silk_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(opus_int16) ); - shift += flat_part; - silk_apply_sine_window( x_windowed + shift, x_ptr + shift, 2, slope_part ); - - /* Update pointer: next LPC analysis block */ - x_ptr += psEnc->sCmn.subfr_length; - - if( psEnc->sCmn.warping_Q16 > 0 ) { - /* Calculate warped auto correlation */ - silk_warped_autocorrelation_FIX( auto_corr, &scale, x_windowed, warping_Q16, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder ); - } else { - /* Calculate regular auto correlation */ - silk_autocorr( auto_corr, &scale, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1 ); - } - - /* Add white noise, as a fraction of energy */ - auto_corr[0] = silk_ADD32( auto_corr[0], silk_max_32( silk_SMULWB( silk_RSHIFT( auto_corr[ 0 ], 4 ), - SILK_FIX_CONST( SHAPE_WHITE_NOISE_FRACTION, 20 ) ), 1 ) ); - - /* Calculate the reflection coefficients using schur */ - nrg = silk_schur64( refl_coef_Q16, auto_corr, psEnc->sCmn.shapingLPCOrder ); - silk_assert( nrg >= 0 ); - - /* Convert reflection coefficients to prediction coefficients */ - silk_k2a_Q16( AR2_Q24, refl_coef_Q16, psEnc->sCmn.shapingLPCOrder ); - - Qnrg = -scale; /* range: -12...30*/ - silk_assert( Qnrg >= -12 ); - silk_assert( Qnrg <= 30 ); - - /* Make sure that Qnrg is an even number */ - if( Qnrg & 1 ) { - Qnrg -= 1; - nrg >>= 1; - } - - tmp32 = silk_SQRT_APPROX( nrg ); - Qnrg >>= 1; /* range: -6...15*/ - - psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT_SAT32( tmp32, 16 - Qnrg ); - - if( psEnc->sCmn.warping_Q16 > 0 ) { - /* Adjust gain for warping */ - gain_mult_Q16 = warped_gain( AR2_Q24, warping_Q16, psEnc->sCmn.shapingLPCOrder ); - silk_assert( psEncCtrl->Gains_Q16[ k ] >= 0 ); - if ( silk_SMULWW( silk_RSHIFT_ROUND( psEncCtrl->Gains_Q16[ k ], 1 ), gain_mult_Q16 ) >= ( silk_int32_MAX >> 1 ) ) { - psEncCtrl->Gains_Q16[ k ] = silk_int32_MAX; - } else { - psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 ); - } - } - - /* Bandwidth expansion for synthesis filter shaping */ - silk_bwexpander_32( AR2_Q24, psEnc->sCmn.shapingLPCOrder, BWExp2_Q16 ); - - /* Compute noise shaping filter coefficients */ - silk_memcpy( AR1_Q24, AR2_Q24, psEnc->sCmn.shapingLPCOrder * sizeof( opus_int32 ) ); - - /* Bandwidth expansion for analysis filter shaping */ - silk_assert( BWExp1_Q16 <= SILK_FIX_CONST( 1.0, 16 ) ); - silk_bwexpander_32( AR1_Q24, psEnc->sCmn.shapingLPCOrder, BWExp1_Q16 ); - - /* Ratio of prediction gains, in energy domain */ - pre_nrg_Q30 = silk_LPC_inverse_pred_gain_Q24( AR2_Q24, psEnc->sCmn.shapingLPCOrder ); - nrg = silk_LPC_inverse_pred_gain_Q24( AR1_Q24, psEnc->sCmn.shapingLPCOrder ); - - /*psEncCtrl->GainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg ) = 0.3f + 0.7f * pre_nrg / nrg;*/ - pre_nrg_Q30 = silk_LSHIFT32( silk_SMULWB( pre_nrg_Q30, SILK_FIX_CONST( 0.7, 15 ) ), 1 ); - psEncCtrl->GainsPre_Q14[ k ] = ( opus_int ) SILK_FIX_CONST( 0.3, 14 ) + silk_DIV32_varQ( pre_nrg_Q30, nrg, 14 ); - - /* Convert to monic warped prediction coefficients and limit absolute values */ - limit_warped_coefs( AR2_Q24, AR1_Q24, warping_Q16, SILK_FIX_CONST( 3.999, 24 ), psEnc->sCmn.shapingLPCOrder ); - - /* Convert from Q24 to Q13 and store in int16 */ - for( i = 0; i < psEnc->sCmn.shapingLPCOrder; i++ ) { - psEncCtrl->AR1_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR1_Q24[ i ], 11 ) ); - psEncCtrl->AR2_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR2_Q24[ i ], 11 ) ); - } - } - - /*****************/ - /* Gain tweaking */ - /*****************/ - /* Increase gains during low speech activity and put lower limit on gains */ - gain_mult_Q16 = silk_log2lin( -silk_SMLAWB( -SILK_FIX_CONST( 16.0, 7 ), SNR_adj_dB_Q7, SILK_FIX_CONST( 0.16, 16 ) ) ); - gain_add_Q16 = silk_log2lin( silk_SMLAWB( SILK_FIX_CONST( 16.0, 7 ), SILK_FIX_CONST( MIN_QGAIN_DB, 7 ), SILK_FIX_CONST( 0.16, 16 ) ) ); - silk_assert( gain_mult_Q16 > 0 ); - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 ); - silk_assert( psEncCtrl->Gains_Q16[ k ] >= 0 ); - psEncCtrl->Gains_Q16[ k ] = silk_ADD_POS_SAT32( psEncCtrl->Gains_Q16[ k ], gain_add_Q16 ); - } - - gain_mult_Q16 = SILK_FIX_CONST( 1.0, 16 ) + silk_RSHIFT_ROUND( silk_MLA( SILK_FIX_CONST( INPUT_TILT, 26 ), - psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( HIGH_RATE_INPUT_TILT, 12 ) ), 10 ); - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - psEncCtrl->GainsPre_Q14[ k ] = silk_SMULWB( gain_mult_Q16, psEncCtrl->GainsPre_Q14[ k ] ); - } - - /************************************************/ - /* Control low-frequency shaping and noise tilt */ - /************************************************/ - /* Less low frequency shaping for noisy inputs */ - strength_Q16 = silk_MUL( SILK_FIX_CONST( LOW_FREQ_SHAPING, 4 ), silk_SMLAWB( SILK_FIX_CONST( 1.0, 12 ), - SILK_FIX_CONST( LOW_QUALITY_LOW_FREQ_SHAPING_DECR, 13 ), psEnc->sCmn.input_quality_bands_Q15[ 0 ] - SILK_FIX_CONST( 1.0, 15 ) ) ); - strength_Q16 = silk_RSHIFT( silk_MUL( strength_Q16, psEnc->sCmn.speech_activity_Q8 ), 8 ); - if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - /* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */ - /*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/ - opus_int fs_kHz_inv = silk_DIV32_16( SILK_FIX_CONST( 0.2, 14 ), psEnc->sCmn.fs_kHz ); - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - b_Q14 = fs_kHz_inv + silk_DIV32_16( SILK_FIX_CONST( 3.0, 14 ), psEncCtrl->pitchL[ k ] ); - /* Pack two coefficients in one int32 */ - psEncCtrl->LF_shp_Q14[ k ] = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 - silk_SMULWB( strength_Q16, b_Q14 ), 16 ); - psEncCtrl->LF_shp_Q14[ k ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) ); - } - silk_assert( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ) < SILK_FIX_CONST( 0.5, 24 ) ); /* Guarantees that second argument to SMULWB() is within range of an opus_int16*/ - Tilt_Q16 = - SILK_FIX_CONST( HP_NOISE_COEF, 16 ) - - silk_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - SILK_FIX_CONST( HP_NOISE_COEF, 16 ), - silk_SMULWB( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ), psEnc->sCmn.speech_activity_Q8 ) ); - } else { - b_Q14 = silk_DIV32_16( 21299, psEnc->sCmn.fs_kHz ); /* 1.3_Q0 = 21299_Q14*/ - /* Pack two coefficients in one int32 */ - psEncCtrl->LF_shp_Q14[ 0 ] = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 - - silk_SMULWB( strength_Q16, silk_SMULWB( SILK_FIX_CONST( 0.6, 16 ), b_Q14 ) ), 16 ); - psEncCtrl->LF_shp_Q14[ 0 ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) ); - for( k = 1; k < psEnc->sCmn.nb_subfr; k++ ) { - psEncCtrl->LF_shp_Q14[ k ] = psEncCtrl->LF_shp_Q14[ 0 ]; - } - Tilt_Q16 = -SILK_FIX_CONST( HP_NOISE_COEF, 16 ); - } - - /****************************/ - /* HARMONIC SHAPING CONTROL */ - /****************************/ - /* Control boosting of harmonic frequencies */ - HarmBoost_Q16 = silk_SMULWB( silk_SMULWB( SILK_FIX_CONST( 1.0, 17 ) - silk_LSHIFT( psEncCtrl->coding_quality_Q14, 3 ), - psEnc->LTPCorr_Q15 ), SILK_FIX_CONST( LOW_RATE_HARMONIC_BOOST, 16 ) ); - - /* More harmonic boost for noisy input signals */ - HarmBoost_Q16 = silk_SMLAWB( HarmBoost_Q16, - SILK_FIX_CONST( 1.0, 16 ) - silk_LSHIFT( psEncCtrl->input_quality_Q14, 2 ), SILK_FIX_CONST( LOW_INPUT_QUALITY_HARMONIC_BOOST, 16 ) ); - - if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - /* More harmonic noise shaping for high bitrates or noisy input */ - HarmShapeGain_Q16 = silk_SMLAWB( SILK_FIX_CONST( HARMONIC_SHAPING, 16 ), - SILK_FIX_CONST( 1.0, 16 ) - silk_SMULWB( SILK_FIX_CONST( 1.0, 18 ) - silk_LSHIFT( psEncCtrl->coding_quality_Q14, 4 ), - psEncCtrl->input_quality_Q14 ), SILK_FIX_CONST( HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING, 16 ) ); - - /* Less harmonic noise shaping for less periodic signals */ - HarmShapeGain_Q16 = silk_SMULWB( silk_LSHIFT( HarmShapeGain_Q16, 1 ), - silk_SQRT_APPROX( silk_LSHIFT( psEnc->LTPCorr_Q15, 15 ) ) ); - } else { - HarmShapeGain_Q16 = 0; - } - - /*************************/ - /* Smooth over subframes */ - /*************************/ - for( k = 0; k < MAX_NB_SUBFR; k++ ) { - psShapeSt->HarmBoost_smth_Q16 = - silk_SMLAWB( psShapeSt->HarmBoost_smth_Q16, HarmBoost_Q16 - psShapeSt->HarmBoost_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) ); - psShapeSt->HarmShapeGain_smth_Q16 = - silk_SMLAWB( psShapeSt->HarmShapeGain_smth_Q16, HarmShapeGain_Q16 - psShapeSt->HarmShapeGain_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) ); - psShapeSt->Tilt_smth_Q16 = - silk_SMLAWB( psShapeSt->Tilt_smth_Q16, Tilt_Q16 - psShapeSt->Tilt_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) ); - - psEncCtrl->HarmBoost_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmBoost_smth_Q16, 2 ); - psEncCtrl->HarmShapeGain_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmShapeGain_smth_Q16, 2 ); - psEncCtrl->Tilt_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->Tilt_smth_Q16, 2 ); - } -} diff --git a/src/opus-1.0.2/silk/fixed/pitch_analysis_core_FIX.c b/src/opus-1.0.2/silk/fixed/pitch_analysis_core_FIX.c deleted file mode 100644 index d43f444d..00000000 --- a/src/opus-1.0.2/silk/fixed/pitch_analysis_core_FIX.c +++ /dev/null @@ -1,745 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/*********************************************************** -* Pitch analyser function -********************************************************** */ -#include "SigProc_FIX.h" -#include "pitch_est_defines.h" -#include "debug.h" - -#define SCRATCH_SIZE 22 - -/************************************************************/ -/* Internally used functions */ -/************************************************************/ -void silk_P_Ana_calc_corr_st3( - opus_int32 cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ],/* (O) 3 DIM correlation array */ - const opus_int16 frame[], /* I vector to correlate */ - opus_int start_lag, /* I lag offset to search around */ - opus_int sf_length, /* I length of a 5 ms subframe */ - opus_int nb_subfr, /* I number of subframes */ - opus_int complexity /* I Complexity setting */ -); - -void silk_P_Ana_calc_energy_st3( - opus_int32 energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ],/* (O) 3 DIM energy array */ - const opus_int16 frame[], /* I vector to calc energy in */ - opus_int start_lag, /* I lag offset to search around */ - opus_int sf_length, /* I length of one 5 ms subframe */ - opus_int nb_subfr, /* I number of subframes */ - opus_int complexity /* I Complexity setting */ -); - -opus_int32 silk_P_Ana_find_scaling( - const opus_int16 *frame, - const opus_int frame_length, - const opus_int sum_sqr_len -); - -/*************************************************************/ -/* FIXED POINT CORE PITCH ANALYSIS FUNCTION */ -/*************************************************************/ -opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0 voiced, 1 unvoiced */ - const opus_int16 *frame, /* I Signal of length PE_FRAME_LENGTH_MS*Fs_kHz */ - opus_int *pitch_out, /* O 4 pitch lag values */ - opus_int16 *lagIndex, /* O Lag Index */ - opus_int8 *contourIndex, /* O Pitch contour Index */ - opus_int *LTPCorr_Q15, /* I/O Normalized correlation; input: value from previous frame */ - opus_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */ - const opus_int32 search_thres1_Q16, /* I First stage threshold for lag candidates 0 - 1 */ - const opus_int search_thres2_Q15, /* I Final threshold for lag candidates 0 - 1 */ - const opus_int Fs_kHz, /* I Sample frequency (kHz) */ - const opus_int complexity, /* I Complexity setting, 0-2, where 2 is highest */ - const opus_int nb_subfr /* I number of 5 ms subframes */ -) -{ - opus_int16 frame_8kHz[ PE_MAX_FRAME_LENGTH_ST_2 ]; - opus_int16 frame_4kHz[ PE_MAX_FRAME_LENGTH_ST_1 ]; - opus_int32 filt_state[ 6 ]; - opus_int32 scratch_mem[ 3 * PE_MAX_FRAME_LENGTH ]; - opus_int16 *input_frame_ptr; - opus_int i, k, d, j; - opus_int16 C[ PE_MAX_NB_SUBFR ][ ( PE_MAX_LAG >> 1 ) + 5 ]; - const opus_int16 *target_ptr, *basis_ptr; - opus_int32 cross_corr, normalizer, energy, shift, energy_basis, energy_target; - opus_int d_srch[ PE_D_SRCH_LENGTH ], Cmax, length_d_srch, length_d_comp; - opus_int16 d_comp[ ( PE_MAX_LAG >> 1 ) + 5 ]; - opus_int32 sum, threshold, temp32, lag_counter; - opus_int CBimax, CBimax_new, CBimax_old, lag, start_lag, end_lag, lag_new; - opus_int32 CC[ PE_NB_CBKS_STAGE2_EXT ], CCmax, CCmax_b, CCmax_new_b, CCmax_new; - opus_int32 energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ]; - opus_int32 crosscorr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ]; - opus_int frame_length, frame_length_8kHz, frame_length_4kHz, max_sum_sq_length; - opus_int sf_length, sf_length_8kHz, sf_length_4kHz; - opus_int min_lag, min_lag_8kHz, min_lag_4kHz; - opus_int max_lag, max_lag_8kHz, max_lag_4kHz; - opus_int32 contour_bias_Q20, diff, lz, lshift; - opus_int nb_cbk_search, cbk_size; - opus_int32 delta_lag_log2_sqr_Q7, lag_log2_Q7, prevLag_log2_Q7, prev_lag_bias_Q15, corr_thres_Q15; - const opus_int8 *Lag_CB_ptr; - /* Check for valid sampling frequency */ - silk_assert( Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16 ); - - /* Check for valid complexity setting */ - silk_assert( complexity >= SILK_PE_MIN_COMPLEX ); - silk_assert( complexity <= SILK_PE_MAX_COMPLEX ); - - silk_assert( search_thres1_Q16 >= 0 && search_thres1_Q16 <= (1<<16) ); - silk_assert( search_thres2_Q15 >= 0 && search_thres2_Q15 <= (1<<15) ); - - /* Set up frame lengths max / min lag for the sampling frequency */ - frame_length = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * Fs_kHz; - frame_length_4kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 4; - frame_length_8kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 8; - sf_length = PE_SUBFR_LENGTH_MS * Fs_kHz; - sf_length_4kHz = PE_SUBFR_LENGTH_MS * 4; - sf_length_8kHz = PE_SUBFR_LENGTH_MS * 8; - min_lag = PE_MIN_LAG_MS * Fs_kHz; - min_lag_4kHz = PE_MIN_LAG_MS * 4; - min_lag_8kHz = PE_MIN_LAG_MS * 8; - max_lag = PE_MAX_LAG_MS * Fs_kHz - 1; - max_lag_4kHz = PE_MAX_LAG_MS * 4; - max_lag_8kHz = PE_MAX_LAG_MS * 8 - 1; - - silk_memset( C, 0, sizeof( opus_int16 ) * nb_subfr * ( ( PE_MAX_LAG >> 1 ) + 5) ); - - /* Resample from input sampled at Fs_kHz to 8 kHz */ - if( Fs_kHz == 16 ) { - silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) ); - silk_resampler_down2( filt_state, frame_8kHz, frame, frame_length ); - } else if( Fs_kHz == 12 ) { - silk_memset( filt_state, 0, 6 * sizeof( opus_int32 ) ); - silk_resampler_down2_3( filt_state, frame_8kHz, frame, frame_length ); - } else { - silk_assert( Fs_kHz == 8 ); - silk_memcpy( frame_8kHz, frame, frame_length_8kHz * sizeof(opus_int16) ); - } - - /* Decimate again to 4 kHz */ - silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) );/* Set state to zero */ - silk_resampler_down2( filt_state, frame_4kHz, frame_8kHz, frame_length_8kHz ); - - /* Low-pass filter */ - for( i = frame_length_4kHz - 1; i > 0; i-- ) { - frame_4kHz[ i ] = silk_ADD_SAT16( frame_4kHz[ i ], frame_4kHz[ i - 1 ] ); - } - - /******************************************************************************* - ** Scale 4 kHz signal down to prevent correlations measures from overflowing - ** find scaling as max scaling for each 8kHz(?) subframe - *******************************************************************************/ - - /* Inner product is calculated with different lengths, so scale for the worst case */ - max_sum_sq_length = silk_max_32( sf_length_8kHz, silk_LSHIFT( sf_length_4kHz, 2 ) ); - shift = silk_P_Ana_find_scaling( frame_4kHz, frame_length_4kHz, max_sum_sq_length ); - if( shift > 0 ) { - for( i = 0; i < frame_length_4kHz; i++ ) { - frame_4kHz[ i ] = silk_RSHIFT( frame_4kHz[ i ], shift ); - } - } - - /****************************************************************************** - * FIRST STAGE, operating in 4 khz - ******************************************************************************/ - target_ptr = &frame_4kHz[ silk_LSHIFT( sf_length_4kHz, 2 ) ]; - for( k = 0; k < nb_subfr >> 1; k++ ) { - /* Check that we are within range of the array */ - silk_assert( target_ptr >= frame_4kHz ); - silk_assert( target_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz ); - - basis_ptr = target_ptr - min_lag_4kHz; - - /* Check that we are within range of the array */ - silk_assert( basis_ptr >= frame_4kHz ); - silk_assert( basis_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz ); - - /* Calculate first vector products before loop */ - cross_corr = silk_inner_prod_aligned( target_ptr, basis_ptr, sf_length_8kHz ); - normalizer = silk_inner_prod_aligned( basis_ptr, basis_ptr, sf_length_8kHz ); - normalizer = silk_ADD_SAT32( normalizer, silk_SMULBB( sf_length_8kHz, 4000 ) ); - - temp32 = silk_DIV32( cross_corr, silk_SQRT_APPROX( normalizer ) + 1 ); - C[ k ][ min_lag_4kHz ] = (opus_int16)silk_SAT16( temp32 ); /* Q0 */ - - /* From now on normalizer is computed recursively */ - for( d = min_lag_4kHz + 1; d <= max_lag_4kHz; d++ ) { - basis_ptr--; - - /* Check that we are within range of the array */ - silk_assert( basis_ptr >= frame_4kHz ); - silk_assert( basis_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz ); - - cross_corr = silk_inner_prod_aligned( target_ptr, basis_ptr, sf_length_8kHz ); - - /* Add contribution of new sample and remove contribution from oldest sample */ - normalizer += - silk_SMULBB( basis_ptr[ 0 ], basis_ptr[ 0 ] ) - - silk_SMULBB( basis_ptr[ sf_length_8kHz ], basis_ptr[ sf_length_8kHz ] ); - - temp32 = silk_DIV32( cross_corr, silk_SQRT_APPROX( normalizer ) + 1 ); - C[ k ][ d ] = (opus_int16)silk_SAT16( temp32 ); /* Q0 */ - } - /* Update target pointer */ - target_ptr += sf_length_8kHz; - } - - /* Combine two subframes into single correlation measure and apply short-lag bias */ - if( nb_subfr == PE_MAX_NB_SUBFR ) { - for( i = max_lag_4kHz; i >= min_lag_4kHz; i-- ) { - sum = (opus_int32)C[ 0 ][ i ] + (opus_int32)C[ 1 ][ i ]; /* Q0 */ - silk_assert( silk_RSHIFT( sum, 1 ) == silk_SAT16( silk_RSHIFT( sum, 1 ) ) ); - sum = silk_RSHIFT( sum, 1 ); /* Q-1 */ - silk_assert( silk_LSHIFT( (opus_int32)-i, 4 ) == silk_SAT16( silk_LSHIFT( (opus_int32)-i, 4 ) ) ); - sum = silk_SMLAWB( sum, sum, silk_LSHIFT( -i, 4 ) ); /* Q-1 */ - silk_assert( sum == silk_SAT16( sum ) ); - C[ 0 ][ i ] = (opus_int16)sum; /* Q-1 */ - } - } else { - /* Only short-lag bias */ - for( i = max_lag_4kHz; i >= min_lag_4kHz; i-- ) { - sum = (opus_int32)C[ 0 ][ i ]; - sum = silk_SMLAWB( sum, sum, silk_LSHIFT( -i, 4 ) ); /* Q-1 */ - C[ 0 ][ i ] = (opus_int16)sum; /* Q-1 */ - } - } - - /* Sort */ - length_d_srch = silk_ADD_LSHIFT32( 4, complexity, 1 ); - silk_assert( 3 * length_d_srch <= PE_D_SRCH_LENGTH ); - silk_insertion_sort_decreasing_int16( &C[ 0 ][ min_lag_4kHz ], d_srch, max_lag_4kHz - min_lag_4kHz + 1, length_d_srch ); - - /* Escape if correlation is very low already here */ - target_ptr = &frame_4kHz[ silk_SMULBB( sf_length_4kHz, nb_subfr ) ]; - energy = silk_inner_prod_aligned( target_ptr, target_ptr, silk_LSHIFT( sf_length_4kHz, 2 ) ); - energy = silk_ADD_SAT32( energy, 1000 ); /* Q0 */ - Cmax = (opus_int)C[ 0 ][ min_lag_4kHz ]; /* Q-1 */ - threshold = silk_SMULBB( Cmax, Cmax ); /* Q-2 */ - - /* Compare in Q-2 domain */ - if( silk_RSHIFT( energy, 4 + 2 ) > threshold ) { - silk_memset( pitch_out, 0, nb_subfr * sizeof( opus_int ) ); - *LTPCorr_Q15 = 0; - *lagIndex = 0; - *contourIndex = 0; - return 1; - } - - threshold = silk_SMULWB( search_thres1_Q16, Cmax ); - for( i = 0; i < length_d_srch; i++ ) { - /* Convert to 8 kHz indices for the sorted correlation that exceeds the threshold */ - if( C[ 0 ][ min_lag_4kHz + i ] > threshold ) { - d_srch[ i ] = silk_LSHIFT( d_srch[ i ] + min_lag_4kHz, 1 ); - } else { - length_d_srch = i; - break; - } - } - silk_assert( length_d_srch > 0 ); - - for( i = min_lag_8kHz - 5; i < max_lag_8kHz + 5; i++ ) { - d_comp[ i ] = 0; - } - for( i = 0; i < length_d_srch; i++ ) { - d_comp[ d_srch[ i ] ] = 1; - } - - /* Convolution */ - for( i = max_lag_8kHz + 3; i >= min_lag_8kHz; i-- ) { - d_comp[ i ] += d_comp[ i - 1 ] + d_comp[ i - 2 ]; - } - - length_d_srch = 0; - for( i = min_lag_8kHz; i < max_lag_8kHz + 1; i++ ) { - if( d_comp[ i + 1 ] > 0 ) { - d_srch[ length_d_srch ] = i; - length_d_srch++; - } - } - - /* Convolution */ - for( i = max_lag_8kHz + 3; i >= min_lag_8kHz; i-- ) { - d_comp[ i ] += d_comp[ i - 1 ] + d_comp[ i - 2 ] + d_comp[ i - 3 ]; - } - - length_d_comp = 0; - for( i = min_lag_8kHz; i < max_lag_8kHz + 4; i++ ) { - if( d_comp[ i ] > 0 ) { - d_comp[ length_d_comp ] = i - 2; - length_d_comp++; - } - } - - /********************************************************************************** - ** SECOND STAGE, operating at 8 kHz, on lag sections with high correlation - *************************************************************************************/ - - /****************************************************************************** - ** Scale signal down to avoid correlations measures from overflowing - *******************************************************************************/ - /* find scaling as max scaling for each subframe */ - shift = silk_P_Ana_find_scaling( frame_8kHz, frame_length_8kHz, sf_length_8kHz ); - if( shift > 0 ) { - for( i = 0; i < frame_length_8kHz; i++ ) { - frame_8kHz[ i ] = silk_RSHIFT( frame_8kHz[ i ], shift ); - } - } - - /********************************************************************************* - * Find energy of each subframe projected onto its history, for a range of delays - *********************************************************************************/ - silk_memset( C, 0, PE_MAX_NB_SUBFR * ( ( PE_MAX_LAG >> 1 ) + 5 ) * sizeof( opus_int16 ) ); - - target_ptr = &frame_8kHz[ PE_LTP_MEM_LENGTH_MS * 8 ]; - for( k = 0; k < nb_subfr; k++ ) { - - /* Check that we are within range of the array */ - silk_assert( target_ptr >= frame_8kHz ); - silk_assert( target_ptr + sf_length_8kHz <= frame_8kHz + frame_length_8kHz ); - - energy_target = silk_inner_prod_aligned( target_ptr, target_ptr, sf_length_8kHz ); - for( j = 0; j < length_d_comp; j++ ) { - d = d_comp[ j ]; - basis_ptr = target_ptr - d; - - /* Check that we are within range of the array */ - silk_assert( basis_ptr >= frame_8kHz ); - silk_assert( basis_ptr + sf_length_8kHz <= frame_8kHz + frame_length_8kHz ); - - cross_corr = silk_inner_prod_aligned( target_ptr, basis_ptr, sf_length_8kHz ); - energy_basis = silk_inner_prod_aligned( basis_ptr, basis_ptr, sf_length_8kHz ); - if( cross_corr > 0 ) { - energy = silk_max( energy_target, energy_basis ); /* Find max to make sure first division < 1.0 */ - lz = silk_CLZ32( cross_corr ); - lshift = silk_LIMIT_32( lz - 1, 0, 15 ); - temp32 = silk_DIV32( silk_LSHIFT( cross_corr, lshift ), silk_RSHIFT( energy, 15 - lshift ) + 1 ); /* Q15 */ - silk_assert( temp32 == silk_SAT16( temp32 ) ); - temp32 = silk_SMULWB( cross_corr, temp32 ); /* Q(-1), cc * ( cc / max(b, t) ) */ - temp32 = silk_ADD_SAT32( temp32, temp32 ); /* Q(0) */ - lz = silk_CLZ32( temp32 ); - lshift = silk_LIMIT_32( lz - 1, 0, 15 ); - energy = silk_min( energy_target, energy_basis ); - C[ k ][ d ] = silk_DIV32( silk_LSHIFT( temp32, lshift ), silk_RSHIFT( energy, 15 - lshift ) + 1 ); /* Q15*/ - } else { - C[ k ][ d ] = 0; - } - } - target_ptr += sf_length_8kHz; - } - - /* search over lag range and lags codebook */ - /* scale factor for lag codebook, as a function of center lag */ - - CCmax = silk_int32_MIN; - CCmax_b = silk_int32_MIN; - - CBimax = 0; /* To avoid returning undefined lag values */ - lag = -1; /* To check if lag with strong enough correlation has been found */ - - if( prevLag > 0 ) { - if( Fs_kHz == 12 ) { - prevLag = silk_DIV32_16( silk_LSHIFT( prevLag, 1 ), 3 ); - } else if( Fs_kHz == 16 ) { - prevLag = silk_RSHIFT( prevLag, 1 ); - } - prevLag_log2_Q7 = silk_lin2log( (opus_int32)prevLag ); - } else { - prevLag_log2_Q7 = 0; - } - silk_assert( search_thres2_Q15 == silk_SAT16( search_thres2_Q15 ) ); - /* Set up stage 2 codebook based on number of subframes */ - if( nb_subfr == PE_MAX_NB_SUBFR ) { - cbk_size = PE_NB_CBKS_STAGE2_EXT; - Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ]; - if( Fs_kHz == 8 && complexity > SILK_PE_MIN_COMPLEX ) { - /* If input is 8 khz use a larger codebook here because it is last stage */ - nb_cbk_search = PE_NB_CBKS_STAGE2_EXT; - } else { - nb_cbk_search = PE_NB_CBKS_STAGE2; - } - corr_thres_Q15 = silk_RSHIFT( silk_SMULBB( search_thres2_Q15, search_thres2_Q15 ), 13 ); - } else { - cbk_size = PE_NB_CBKS_STAGE2_10MS; - Lag_CB_ptr = &silk_CB_lags_stage2_10_ms[ 0 ][ 0 ]; - nb_cbk_search = PE_NB_CBKS_STAGE2_10MS; - corr_thres_Q15 = silk_RSHIFT( silk_SMULBB( search_thres2_Q15, search_thres2_Q15 ), 14 ); - } - - for( k = 0; k < length_d_srch; k++ ) { - d = d_srch[ k ]; - for( j = 0; j < nb_cbk_search; j++ ) { - CC[ j ] = 0; - for( i = 0; i < nb_subfr; i++ ) { - /* Try all codebooks */ - CC[ j ] = CC[ j ] + (opus_int32)C[ i ][ d + matrix_ptr( Lag_CB_ptr, i, j, cbk_size )]; - } - } - /* Find best codebook */ - CCmax_new = silk_int32_MIN; - CBimax_new = 0; - for( i = 0; i < nb_cbk_search; i++ ) { - if( CC[ i ] > CCmax_new ) { - CCmax_new = CC[ i ]; - CBimax_new = i; - } - } - - /* Bias towards shorter lags */ - lag_log2_Q7 = silk_lin2log( (opus_int32)d ); /* Q7 */ - silk_assert( lag_log2_Q7 == silk_SAT16( lag_log2_Q7 ) ); - silk_assert( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 15 ) == silk_SAT16( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 15 ) ) ); - CCmax_new_b = CCmax_new - silk_RSHIFT( silk_SMULBB( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 15 ), lag_log2_Q7 ), 7 ); /* Q15 */ - - /* Bias towards previous lag */ - silk_assert( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 15 ) == silk_SAT16( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 15 ) ) ); - if( prevLag > 0 ) { - delta_lag_log2_sqr_Q7 = lag_log2_Q7 - prevLag_log2_Q7; - silk_assert( delta_lag_log2_sqr_Q7 == silk_SAT16( delta_lag_log2_sqr_Q7 ) ); - delta_lag_log2_sqr_Q7 = silk_RSHIFT( silk_SMULBB( delta_lag_log2_sqr_Q7, delta_lag_log2_sqr_Q7 ), 7 ); - prev_lag_bias_Q15 = silk_RSHIFT( silk_SMULBB( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 15 ), *LTPCorr_Q15 ), 15 ); /* Q15 */ - prev_lag_bias_Q15 = silk_DIV32( silk_MUL( prev_lag_bias_Q15, delta_lag_log2_sqr_Q7 ), delta_lag_log2_sqr_Q7 + ( 1 << 6 ) ); - CCmax_new_b -= prev_lag_bias_Q15; /* Q15 */ - } - - if( CCmax_new_b > CCmax_b && /* Find maximum biased correlation */ - CCmax_new > corr_thres_Q15 && /* Correlation needs to be high enough to be voiced */ - silk_CB_lags_stage2[ 0 ][ CBimax_new ] <= min_lag_8kHz /* Lag must be in range */ - ) { - CCmax_b = CCmax_new_b; - CCmax = CCmax_new; - lag = d; - CBimax = CBimax_new; - } - } - - if( lag == -1 ) { - /* No suitable candidate found */ - silk_memset( pitch_out, 0, nb_subfr * sizeof( opus_int ) ); - *LTPCorr_Q15 = 0; - *lagIndex = 0; - *contourIndex = 0; - return 1; - } - - if( Fs_kHz > 8 ) { - /***************************************************************************/ - /* Scale input signal down to avoid correlations measures from overflowing */ - /***************************************************************************/ - /* find scaling as max scaling for each subframe */ - shift = silk_P_Ana_find_scaling( frame, frame_length, sf_length ); - if( shift > 0 ) { - /* Move signal to scratch mem because the input signal should be unchanged */ - /* Reuse the 32 bit scratch mem vector, use a 16 bit pointer from now */ - input_frame_ptr = (opus_int16*)scratch_mem; - for( i = 0; i < frame_length; i++ ) { - input_frame_ptr[ i ] = silk_RSHIFT( frame[ i ], shift ); - } - } else { - input_frame_ptr = (opus_int16*)frame; - } - - /* Search in original signal */ - - CBimax_old = CBimax; - /* Compensate for decimation */ - silk_assert( lag == silk_SAT16( lag ) ); - if( Fs_kHz == 12 ) { - lag = silk_RSHIFT( silk_SMULBB( lag, 3 ), 1 ); - } else if( Fs_kHz == 16 ) { - lag = silk_LSHIFT( lag, 1 ); - } else { - lag = silk_SMULBB( lag, 3 ); - } - - lag = silk_LIMIT_int( lag, min_lag, max_lag ); - start_lag = silk_max_int( lag - 2, min_lag ); - end_lag = silk_min_int( lag + 2, max_lag ); - lag_new = lag; /* to avoid undefined lag */ - CBimax = 0; /* to avoid undefined lag */ - silk_assert( silk_LSHIFT( CCmax, 13 ) >= 0 ); - *LTPCorr_Q15 = (opus_int)silk_SQRT_APPROX( silk_LSHIFT( CCmax, 13 ) ); /* Output normalized correlation */ - - CCmax = silk_int32_MIN; - /* pitch lags according to second stage */ - for( k = 0; k < nb_subfr; k++ ) { - pitch_out[ k ] = lag + 2 * silk_CB_lags_stage2[ k ][ CBimax_old ]; - } - /* Calculate the correlations and energies needed in stage 3 */ - silk_P_Ana_calc_corr_st3( crosscorr_st3, input_frame_ptr, start_lag, sf_length, nb_subfr, complexity ); - silk_P_Ana_calc_energy_st3( energies_st3, input_frame_ptr, start_lag, sf_length, nb_subfr, complexity ); - - lag_counter = 0; - silk_assert( lag == silk_SAT16( lag ) ); - contour_bias_Q20 = silk_DIV32_16( SILK_FIX_CONST( PE_FLATCONTOUR_BIAS, 20 ), lag ); - - /* Set up codebook parameters according to complexity setting and frame length */ - if( nb_subfr == PE_MAX_NB_SUBFR ) { - nb_cbk_search = (opus_int)silk_nb_cbk_searchs_stage3[ complexity ]; - cbk_size = PE_NB_CBKS_STAGE3_MAX; - Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ]; - } else { - nb_cbk_search = PE_NB_CBKS_STAGE3_10MS; - cbk_size = PE_NB_CBKS_STAGE3_10MS; - Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ]; - } - for( d = start_lag; d <= end_lag; d++ ) { - for( j = 0; j < nb_cbk_search; j++ ) { - cross_corr = 0; - energy = 0; - for( k = 0; k < nb_subfr; k++ ) { - silk_assert( PE_MAX_NB_SUBFR == 4 ); - energy += silk_RSHIFT( energies_st3[ k ][ j ][ lag_counter ], 2 ); /* use mean, to avoid overflow */ - silk_assert( energy >= 0 ); - cross_corr += silk_RSHIFT( crosscorr_st3[ k ][ j ][ lag_counter ], 2 ); /* use mean, to avoid overflow */ - } - if( cross_corr > 0 ) { - /* Divide cross_corr / energy and get result in Q15 */ - lz = silk_CLZ32( cross_corr ); - /* Divide with result in Q13, cross_corr could be larger than energy */ - lshift = silk_LIMIT_32( lz - 1, 0, 13 ); - CCmax_new = silk_DIV32( silk_LSHIFT( cross_corr, lshift ), silk_RSHIFT( energy, 13 - lshift ) + 1 ); - CCmax_new = silk_SAT16( CCmax_new ); - CCmax_new = silk_SMULWB( cross_corr, CCmax_new ); - /* Saturate */ - if( CCmax_new > silk_RSHIFT( silk_int32_MAX, 3 ) ) { - CCmax_new = silk_int32_MAX; - } else { - CCmax_new = silk_LSHIFT( CCmax_new, 3 ); - } - /* Reduce depending on flatness of contour */ - diff = silk_int16_MAX - silk_RSHIFT( silk_MUL( contour_bias_Q20, j ), 5 ); /* Q20 -> Q15 */ - silk_assert( diff == silk_SAT16( diff ) ); - CCmax_new = silk_LSHIFT( silk_SMULWB( CCmax_new, diff ), 1 ); - } else { - CCmax_new = 0; - } - - if( CCmax_new > CCmax && - ( d + silk_CB_lags_stage3[ 0 ][ j ] ) <= max_lag - ) { - CCmax = CCmax_new; - lag_new = d; - CBimax = j; - } - } - lag_counter++; - } - - for( k = 0; k < nb_subfr; k++ ) { - pitch_out[ k ] = lag_new + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size ); - pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], min_lag, PE_MAX_LAG_MS * Fs_kHz ); - } - *lagIndex = (opus_int16)( lag_new - min_lag); - *contourIndex = (opus_int8)CBimax; - } else { /* Fs_kHz == 8 */ - /* Save Lags and correlation */ - CCmax = silk_max( CCmax, 0 ); - *LTPCorr_Q15 = (opus_int)silk_SQRT_APPROX( silk_LSHIFT( CCmax, 13 ) ); /* Output normalized correlation */ - for( k = 0; k < nb_subfr; k++ ) { - pitch_out[ k ] = lag + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size ); - pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], min_lag_8kHz, PE_MAX_LAG_MS * Fs_kHz ); - } - *lagIndex = (opus_int16)( lag - min_lag_8kHz ); - *contourIndex = (opus_int8)CBimax; - } - silk_assert( *lagIndex >= 0 ); - /* return as voiced */ - return 0; -} - -/*************************************************************************/ -/* Calculates the correlations used in stage 3 search. In order to cover */ -/* the whole lag codebook for all the searched offset lags (lag +- 2), */ -/*************************************************************************/ -void silk_P_Ana_calc_corr_st3( - opus_int32 cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ],/* (O) 3 DIM correlation array */ - const opus_int16 frame[], /* I vector to correlate */ - opus_int start_lag, /* I lag offset to search around */ - opus_int sf_length, /* I length of a 5 ms subframe */ - opus_int nb_subfr, /* I number of subframes */ - opus_int complexity /* I Complexity setting */ -) -{ - const opus_int16 *target_ptr, *basis_ptr; - opus_int32 cross_corr; - opus_int i, j, k, lag_counter, lag_low, lag_high; - opus_int nb_cbk_search, delta, idx, cbk_size; - opus_int32 scratch_mem[ SCRATCH_SIZE ]; - const opus_int8 *Lag_range_ptr, *Lag_CB_ptr; - - silk_assert( complexity >= SILK_PE_MIN_COMPLEX ); - silk_assert( complexity <= SILK_PE_MAX_COMPLEX ); - - if( nb_subfr == PE_MAX_NB_SUBFR ) { - Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ]; - Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ]; - nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ]; - cbk_size = PE_NB_CBKS_STAGE3_MAX; - } else { - silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1); - Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ]; - Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ]; - nb_cbk_search = PE_NB_CBKS_STAGE3_10MS; - cbk_size = PE_NB_CBKS_STAGE3_10MS; - } - - target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ]; /* Pointer to middle of frame */ - for( k = 0; k < nb_subfr; k++ ) { - lag_counter = 0; - - /* Calculate the correlations for each subframe */ - lag_low = matrix_ptr( Lag_range_ptr, k, 0, 2 ); - lag_high = matrix_ptr( Lag_range_ptr, k, 1, 2 ); - for( j = lag_low; j <= lag_high; j++ ) { - basis_ptr = target_ptr - ( start_lag + j ); - cross_corr = silk_inner_prod_aligned( (opus_int16*)target_ptr, (opus_int16*)basis_ptr, sf_length ); - silk_assert( lag_counter < SCRATCH_SIZE ); - scratch_mem[ lag_counter ] = cross_corr; - lag_counter++; - } - - delta = matrix_ptr( Lag_range_ptr, k, 0, 2 ); - for( i = 0; i < nb_cbk_search; i++ ) { - /* Fill out the 3 dim array that stores the correlations for */ - /* each code_book vector for each start lag */ - idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta; - for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) { - silk_assert( idx + j < SCRATCH_SIZE ); - silk_assert( idx + j < lag_counter ); - cross_corr_st3[ k ][ i ][ j ] = scratch_mem[ idx + j ]; - } - } - target_ptr += sf_length; - } -} - -/********************************************************************/ -/* Calculate the energies for first two subframes. The energies are */ -/* calculated recursively. */ -/********************************************************************/ -void silk_P_Ana_calc_energy_st3( - opus_int32 energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ],/* (O) 3 DIM energy array */ - const opus_int16 frame[], /* I vector to calc energy in */ - opus_int start_lag, /* I lag offset to search around */ - opus_int sf_length, /* I length of one 5 ms subframe */ - opus_int nb_subfr, /* I number of subframes */ - opus_int complexity /* I Complexity setting */ -) -{ - const opus_int16 *target_ptr, *basis_ptr; - opus_int32 energy; - opus_int k, i, j, lag_counter; - opus_int nb_cbk_search, delta, idx, cbk_size, lag_diff; - opus_int32 scratch_mem[ SCRATCH_SIZE ]; - const opus_int8 *Lag_range_ptr, *Lag_CB_ptr; - - silk_assert( complexity >= SILK_PE_MIN_COMPLEX ); - silk_assert( complexity <= SILK_PE_MAX_COMPLEX ); - - if( nb_subfr == PE_MAX_NB_SUBFR ) { - Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ]; - Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ]; - nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ]; - cbk_size = PE_NB_CBKS_STAGE3_MAX; - } else { - silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1); - Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ]; - Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ]; - nb_cbk_search = PE_NB_CBKS_STAGE3_10MS; - cbk_size = PE_NB_CBKS_STAGE3_10MS; - } - target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ]; - for( k = 0; k < nb_subfr; k++ ) { - lag_counter = 0; - - /* Calculate the energy for first lag */ - basis_ptr = target_ptr - ( start_lag + matrix_ptr( Lag_range_ptr, k, 0, 2 ) ); - energy = silk_inner_prod_aligned( basis_ptr, basis_ptr, sf_length ); - silk_assert( energy >= 0 ); - scratch_mem[ lag_counter ] = energy; - lag_counter++; - - lag_diff = ( matrix_ptr( Lag_range_ptr, k, 1, 2 ) - matrix_ptr( Lag_range_ptr, k, 0, 2 ) + 1 ); - for( i = 1; i < lag_diff; i++ ) { - /* remove part outside new window */ - energy -= silk_SMULBB( basis_ptr[ sf_length - i ], basis_ptr[ sf_length - i ] ); - silk_assert( energy >= 0 ); - - /* add part that comes into window */ - energy = silk_ADD_SAT32( energy, silk_SMULBB( basis_ptr[ -i ], basis_ptr[ -i ] ) ); - silk_assert( energy >= 0 ); - silk_assert( lag_counter < SCRATCH_SIZE ); - scratch_mem[ lag_counter ] = energy; - lag_counter++; - } - - delta = matrix_ptr( Lag_range_ptr, k, 0, 2 ); - for( i = 0; i < nb_cbk_search; i++ ) { - /* Fill out the 3 dim array that stores the correlations for */ - /* each code_book vector for each start lag */ - idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta; - for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) { - silk_assert( idx + j < SCRATCH_SIZE ); - silk_assert( idx + j < lag_counter ); - energies_st3[ k ][ i ][ j ] = scratch_mem[ idx + j ]; - silk_assert( energies_st3[ k ][ i ][ j ] >= 0 ); - } - } - target_ptr += sf_length; - } -} - -opus_int32 silk_P_Ana_find_scaling( - const opus_int16 *frame, - const opus_int frame_length, - const opus_int sum_sqr_len -) -{ - opus_int32 nbits, x_max; - - x_max = silk_int16_array_maxabs( frame, frame_length ); - - if( x_max < silk_int16_MAX ) { - /* Number of bits needed for the sum of the squares */ - nbits = 32 - silk_CLZ32( silk_SMULBB( x_max, x_max ) ); - } else { - /* Here we don't know if x_max should have been silk_int16_MAX + 1, so we expect the worst case */ - nbits = 30; - } - nbits += 17 - silk_CLZ16( sum_sqr_len ); - - /* Without a guarantee of saturation, we need to keep the 31st bit free */ - if( nbits < 31 ) { - return 0; - } else { - return( nbits - 30 ); - } -} diff --git a/src/opus-1.0.2/silk/fixed/prefilter_FIX.c b/src/opus-1.0.2/silk/fixed/prefilter_FIX.c deleted file mode 100644 index a96f5118..00000000 --- a/src/opus-1.0.2/silk/fixed/prefilter_FIX.c +++ /dev/null @@ -1,204 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main_FIX.h" -#include "tuning_parameters.h" - -/* Prefilter for finding Quantizer input signal */ -static inline void silk_prefilt_FIX( - silk_prefilter_state_FIX *P, /* I/O state */ - opus_int32 st_res_Q12[], /* I short term residual signal */ - opus_int32 xw_Q3[], /* O prefiltered signal */ - opus_int32 HarmShapeFIRPacked_Q12, /* I Harmonic shaping coeficients */ - opus_int Tilt_Q14, /* I Tilt shaping coeficient */ - opus_int32 LF_shp_Q14, /* I Low-frequancy shaping coeficients */ - opus_int lag, /* I Lag for harmonic shaping */ - opus_int length /* I Length of signals */ -); - -void silk_warped_LPC_analysis_filter_FIX( - opus_int32 state[], /* I/O State [order + 1] */ - opus_int32 res_Q2[], /* O Residual signal [length] */ - const opus_int16 coef_Q13[], /* I Coefficients [order] */ - const opus_int16 input[], /* I Input signal [length] */ - const opus_int16 lambda_Q16, /* I Warping factor */ - const opus_int length, /* I Length of input signal */ - const opus_int order /* I Filter order (even) */ -) -{ - opus_int n, i; - opus_int32 acc_Q11, tmp1, tmp2; - - /* Order must be even */ - silk_assert( ( order & 1 ) == 0 ); - - for( n = 0; n < length; n++ ) { - /* Output of lowpass section */ - tmp2 = silk_SMLAWB( state[ 0 ], state[ 1 ], lambda_Q16 ); - state[ 0 ] = silk_LSHIFT( input[ n ], 14 ); - /* Output of allpass section */ - tmp1 = silk_SMLAWB( state[ 1 ], state[ 2 ] - tmp2, lambda_Q16 ); - state[ 1 ] = tmp2; - acc_Q11 = silk_RSHIFT( order, 1 ); - acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ 0 ] ); - /* Loop over allpass sections */ - for( i = 2; i < order; i += 2 ) { - /* Output of allpass section */ - tmp2 = silk_SMLAWB( state[ i ], state[ i + 1 ] - tmp1, lambda_Q16 ); - state[ i ] = tmp1; - acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ i - 1 ] ); - /* Output of allpass section */ - tmp1 = silk_SMLAWB( state[ i + 1 ], state[ i + 2 ] - tmp2, lambda_Q16 ); - state[ i + 1 ] = tmp2; - acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ i ] ); - } - state[ order ] = tmp1; - acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ order - 1 ] ); - res_Q2[ n ] = silk_LSHIFT( (opus_int32)input[ n ], 2 ) - silk_RSHIFT_ROUND( acc_Q11, 9 ); - } -} - -void silk_prefilter_FIX( - silk_encoder_state_FIX *psEnc, /* I/O Encoder state */ - const silk_encoder_control_FIX *psEncCtrl, /* I Encoder control */ - opus_int32 xw_Q3[], /* O Weighted signal */ - const opus_int16 x[] /* I Speech signal */ -) -{ - silk_prefilter_state_FIX *P = &psEnc->sPrefilt; - opus_int j, k, lag; - opus_int32 tmp_32; - const opus_int16 *AR1_shp_Q13; - const opus_int16 *px; - opus_int32 *pxw_Q3; - opus_int HarmShapeGain_Q12, Tilt_Q14; - opus_int32 HarmShapeFIRPacked_Q12, LF_shp_Q14; - opus_int32 x_filt_Q12[ MAX_SUB_FRAME_LENGTH ]; - opus_int32 st_res_Q2[ MAX_SUB_FRAME_LENGTH + MAX_LPC_ORDER ]; - opus_int16 B_Q10[ 2 ]; - - /* Set up pointers */ - px = x; - pxw_Q3 = xw_Q3; - lag = P->lagPrev; - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - /* Update Variables that change per sub frame */ - if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - lag = psEncCtrl->pitchL[ k ]; - } - - /* Noise shape parameters */ - HarmShapeGain_Q12 = silk_SMULWB( (opus_int32)psEncCtrl->HarmShapeGain_Q14[ k ], 16384 - psEncCtrl->HarmBoost_Q14[ k ] ); - silk_assert( HarmShapeGain_Q12 >= 0 ); - HarmShapeFIRPacked_Q12 = silk_RSHIFT( HarmShapeGain_Q12, 2 ); - HarmShapeFIRPacked_Q12 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q12, 1 ), 16 ); - Tilt_Q14 = psEncCtrl->Tilt_Q14[ k ]; - LF_shp_Q14 = psEncCtrl->LF_shp_Q14[ k ]; - AR1_shp_Q13 = &psEncCtrl->AR1_Q13[ k * MAX_SHAPE_LPC_ORDER ]; - - /* Short term FIR filtering*/ - silk_warped_LPC_analysis_filter_FIX( P->sAR_shp, st_res_Q2, AR1_shp_Q13, px, - psEnc->sCmn.warping_Q16, psEnc->sCmn.subfr_length, psEnc->sCmn.shapingLPCOrder ); - - /* Reduce (mainly) low frequencies during harmonic emphasis */ - B_Q10[ 0 ] = silk_RSHIFT_ROUND( psEncCtrl->GainsPre_Q14[ k ], 4 ); - tmp_32 = silk_SMLABB( SILK_FIX_CONST( INPUT_TILT, 26 ), psEncCtrl->HarmBoost_Q14[ k ], HarmShapeGain_Q12 ); /* Q26 */ - tmp_32 = silk_SMLABB( tmp_32, psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( HIGH_RATE_INPUT_TILT, 12 ) ); /* Q26 */ - tmp_32 = silk_SMULWB( tmp_32, -psEncCtrl->GainsPre_Q14[ k ] ); /* Q24 */ - tmp_32 = silk_RSHIFT_ROUND( tmp_32, 14 ); /* Q10 */ - B_Q10[ 1 ]= silk_SAT16( tmp_32 ); - x_filt_Q12[ 0 ] = silk_MLA( silk_MUL( st_res_Q2[ 0 ], B_Q10[ 0 ] ), P->sHarmHP_Q2, B_Q10[ 1 ] ); - for( j = 1; j < psEnc->sCmn.subfr_length; j++ ) { - x_filt_Q12[ j ] = silk_MLA( silk_MUL( st_res_Q2[ j ], B_Q10[ 0 ] ), st_res_Q2[ j - 1 ], B_Q10[ 1 ] ); - } - P->sHarmHP_Q2 = st_res_Q2[ psEnc->sCmn.subfr_length - 1 ]; - - silk_prefilt_FIX( P, x_filt_Q12, pxw_Q3, HarmShapeFIRPacked_Q12, Tilt_Q14, LF_shp_Q14, lag, psEnc->sCmn.subfr_length ); - - px += psEnc->sCmn.subfr_length; - pxw_Q3 += psEnc->sCmn.subfr_length; - } - - P->lagPrev = psEncCtrl->pitchL[ psEnc->sCmn.nb_subfr - 1 ]; -} - -/* Prefilter for finding Quantizer input signal */ -static inline void silk_prefilt_FIX( - silk_prefilter_state_FIX *P, /* I/O state */ - opus_int32 st_res_Q12[], /* I short term residual signal */ - opus_int32 xw_Q3[], /* O prefiltered signal */ - opus_int32 HarmShapeFIRPacked_Q12, /* I Harmonic shaping coeficients */ - opus_int Tilt_Q14, /* I Tilt shaping coeficient */ - opus_int32 LF_shp_Q14, /* I Low-frequancy shaping coeficients */ - opus_int lag, /* I Lag for harmonic shaping */ - opus_int length /* I Length of signals */ -) -{ - opus_int i, idx, LTP_shp_buf_idx; - opus_int32 n_LTP_Q12, n_Tilt_Q10, n_LF_Q10; - opus_int32 sLF_MA_shp_Q12, sLF_AR_shp_Q12; - opus_int16 *LTP_shp_buf; - - /* To speed up use temp variables instead of using the struct */ - LTP_shp_buf = P->sLTP_shp; - LTP_shp_buf_idx = P->sLTP_shp_buf_idx; - sLF_AR_shp_Q12 = P->sLF_AR_shp_Q12; - sLF_MA_shp_Q12 = P->sLF_MA_shp_Q12; - - for( i = 0; i < length; i++ ) { - if( lag > 0 ) { - /* unrolled loop */ - silk_assert( HARM_SHAPE_FIR_TAPS == 3 ); - idx = lag + LTP_shp_buf_idx; - n_LTP_Q12 = silk_SMULBB( LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 - 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 ); - n_LTP_Q12 = silk_SMLABT( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 ) & LTP_MASK ], HarmShapeFIRPacked_Q12 ); - n_LTP_Q12 = silk_SMLABB( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 + 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 ); - } else { - n_LTP_Q12 = 0; - } - - n_Tilt_Q10 = silk_SMULWB( sLF_AR_shp_Q12, Tilt_Q14 ); - n_LF_Q10 = silk_SMLAWB( silk_SMULWT( sLF_AR_shp_Q12, LF_shp_Q14 ), sLF_MA_shp_Q12, LF_shp_Q14 ); - - sLF_AR_shp_Q12 = silk_SUB32( st_res_Q12[ i ], silk_LSHIFT( n_Tilt_Q10, 2 ) ); - sLF_MA_shp_Q12 = silk_SUB32( sLF_AR_shp_Q12, silk_LSHIFT( n_LF_Q10, 2 ) ); - - LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK; - LTP_shp_buf[ LTP_shp_buf_idx ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sLF_MA_shp_Q12, 12 ) ); - - xw_Q3[i] = silk_RSHIFT_ROUND( silk_SUB32( sLF_MA_shp_Q12, n_LTP_Q12 ), 9 ); - } - - /* Copy temp variable back to state */ - P->sLF_AR_shp_Q12 = sLF_AR_shp_Q12; - P->sLF_MA_shp_Q12 = sLF_MA_shp_Q12; - P->sLTP_shp_buf_idx = LTP_shp_buf_idx; -} diff --git a/src/opus-1.0.2/silk/fixed/process_gains_FIX.c b/src/opus-1.0.2/silk/fixed/process_gains_FIX.c deleted file mode 100644 index 22d3a71a..00000000 --- a/src/opus-1.0.2/silk/fixed/process_gains_FIX.c +++ /dev/null @@ -1,117 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main_FIX.h" -#include "tuning_parameters.h" - -/* Processing of gains */ -void silk_process_gains_FIX( - silk_encoder_state_FIX *psEnc, /* I/O Encoder state */ - silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control */ - opus_int condCoding /* I The type of conditional coding to use */ -) -{ - silk_shape_state_FIX *psShapeSt = &psEnc->sShape; - opus_int k; - opus_int32 s_Q16, InvMaxSqrVal_Q16, gain, gain_squared, ResNrg, ResNrgPart, quant_offset_Q10; - - /* Gain reduction when LTP coding gain is high */ - if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - /*s = -0.5f * silk_sigmoid( 0.25f * ( psEncCtrl->LTPredCodGain - 12.0f ) ); */ - s_Q16 = -silk_sigm_Q15( silk_RSHIFT_ROUND( psEncCtrl->LTPredCodGain_Q7 - SILK_FIX_CONST( 12.0, 7 ), 4 ) ); - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - psEncCtrl->Gains_Q16[ k ] = silk_SMLAWB( psEncCtrl->Gains_Q16[ k ], psEncCtrl->Gains_Q16[ k ], s_Q16 ); - } - } - - /* Limit the quantized signal */ - /* InvMaxSqrVal = pow( 2.0f, 0.33f * ( 21.0f - SNR_dB ) ) / subfr_length; */ - InvMaxSqrVal_Q16 = silk_DIV32_16( silk_log2lin( - silk_SMULWB( SILK_FIX_CONST( 21 + 16 / 0.33, 7 ) - psEnc->sCmn.SNR_dB_Q7, SILK_FIX_CONST( 0.33, 16 ) ) ), psEnc->sCmn.subfr_length ); - - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - /* Soft limit on ratio residual energy and squared gains */ - ResNrg = psEncCtrl->ResNrg[ k ]; - ResNrgPart = silk_SMULWW( ResNrg, InvMaxSqrVal_Q16 ); - if( psEncCtrl->ResNrgQ[ k ] > 0 ) { - ResNrgPart = silk_RSHIFT_ROUND( ResNrgPart, psEncCtrl->ResNrgQ[ k ] ); - } else { - if( ResNrgPart >= silk_RSHIFT( silk_int32_MAX, -psEncCtrl->ResNrgQ[ k ] ) ) { - ResNrgPart = silk_int32_MAX; - } else { - ResNrgPart = silk_LSHIFT( ResNrgPart, -psEncCtrl->ResNrgQ[ k ] ); - } - } - gain = psEncCtrl->Gains_Q16[ k ]; - gain_squared = silk_ADD_SAT32( ResNrgPart, silk_SMMUL( gain, gain ) ); - if( gain_squared < silk_int16_MAX ) { - /* recalculate with higher precision */ - gain_squared = silk_SMLAWW( silk_LSHIFT( ResNrgPart, 16 ), gain, gain ); - silk_assert( gain_squared > 0 ); - gain = silk_SQRT_APPROX( gain_squared ); /* Q8 */ - gain = silk_min( gain, silk_int32_MAX >> 8 ); - psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT_SAT32( gain, 8 ); /* Q16 */ - } else { - gain = silk_SQRT_APPROX( gain_squared ); /* Q0 */ - gain = silk_min( gain, silk_int32_MAX >> 16 ); - psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT_SAT32( gain, 16 ); /* Q16 */ - } - } - - /* Save unquantized gains and gain Index */ - silk_memcpy( psEncCtrl->GainsUnq_Q16, psEncCtrl->Gains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) ); - psEncCtrl->lastGainIndexPrev = psShapeSt->LastGainIndex; - - /* Quantize gains */ - silk_gains_quant( psEnc->sCmn.indices.GainsIndices, psEncCtrl->Gains_Q16, - &psShapeSt->LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); - - /* Set quantizer offset for voiced signals. Larger offset when LTP coding gain is low or tilt is high (ie low-pass) */ - if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - if( psEncCtrl->LTPredCodGain_Q7 + silk_RSHIFT( psEnc->sCmn.input_tilt_Q15, 8 ) > SILK_FIX_CONST( 1.0, 7 ) ) { - psEnc->sCmn.indices.quantOffsetType = 0; - } else { - psEnc->sCmn.indices.quantOffsetType = 1; - } - } - - /* Quantizer boundary adjustment */ - quant_offset_Q10 = silk_Quantization_Offsets_Q10[ psEnc->sCmn.indices.signalType >> 1 ][ psEnc->sCmn.indices.quantOffsetType ]; - psEncCtrl->Lambda_Q10 = SILK_FIX_CONST( LAMBDA_OFFSET, 10 ) - + silk_SMULBB( SILK_FIX_CONST( LAMBDA_DELAYED_DECISIONS, 10 ), psEnc->sCmn.nStatesDelayedDecision ) - + silk_SMULWB( SILK_FIX_CONST( LAMBDA_SPEECH_ACT, 18 ), psEnc->sCmn.speech_activity_Q8 ) - + silk_SMULWB( SILK_FIX_CONST( LAMBDA_INPUT_QUALITY, 12 ), psEncCtrl->input_quality_Q14 ) - + silk_SMULWB( SILK_FIX_CONST( LAMBDA_CODING_QUALITY, 12 ), psEncCtrl->coding_quality_Q14 ) - + silk_SMULWB( SILK_FIX_CONST( LAMBDA_QUANT_OFFSET, 16 ), quant_offset_Q10 ); - - silk_assert( psEncCtrl->Lambda_Q10 > 0 ); - silk_assert( psEncCtrl->Lambda_Q10 < SILK_FIX_CONST( 2, 10 ) ); -} diff --git a/src/opus-1.0.2/silk/fixed/regularize_correlations_FIX.c b/src/opus-1.0.2/silk/fixed/regularize_correlations_FIX.c deleted file mode 100644 index 098c1509..00000000 --- a/src/opus-1.0.2/silk/fixed/regularize_correlations_FIX.c +++ /dev/null @@ -1,47 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main_FIX.h" - -/* Add noise to matrix diagonal */ -void silk_regularize_correlations_FIX( - opus_int32 *XX, /* I/O Correlation matrices */ - opus_int32 *xx, /* I/O Correlation values */ - opus_int32 noise, /* I Noise to add */ - opus_int D /* I Dimension of XX */ -) -{ - opus_int i; - for( i = 0; i < D; i++ ) { - matrix_ptr( &XX[ 0 ], i, i, D ) = silk_ADD32( matrix_ptr( &XX[ 0 ], i, i, D ), noise ); - } - xx[ 0 ] += noise; -} diff --git a/src/opus-1.0.2/silk/fixed/residual_energy16_FIX.c b/src/opus-1.0.2/silk/fixed/residual_energy16_FIX.c deleted file mode 100644 index d61e8493..00000000 --- a/src/opus-1.0.2/silk/fixed/residual_energy16_FIX.c +++ /dev/null @@ -1,103 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main_FIX.h" - -/* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */ -opus_int32 silk_residual_energy16_covar_FIX( - const opus_int16 *c, /* I Prediction vector */ - const opus_int32 *wXX, /* I Correlation matrix */ - const opus_int32 *wXx, /* I Correlation vector */ - opus_int32 wxx, /* I Signal energy */ - opus_int D, /* I Dimension */ - opus_int cQ /* I Q value for c vector 0 - 15 */ -) -{ - opus_int i, j, lshifts, Qxtra; - opus_int32 c_max, w_max, tmp, tmp2, nrg; - opus_int cn[ MAX_MATRIX_SIZE ]; - const opus_int32 *pRow; - - /* Safety checks */ - silk_assert( D >= 0 ); - silk_assert( D <= 16 ); - silk_assert( cQ > 0 ); - silk_assert( cQ < 16 ); - - lshifts = 16 - cQ; - Qxtra = lshifts; - - c_max = 0; - for( i = 0; i < D; i++ ) { - c_max = silk_max_32( c_max, silk_abs( (opus_int32)c[ i ] ) ); - } - Qxtra = silk_min_int( Qxtra, silk_CLZ32( c_max ) - 17 ); - - w_max = silk_max_32( wXX[ 0 ], wXX[ D * D - 1 ] ); - Qxtra = silk_min_int( Qxtra, silk_CLZ32( silk_MUL( D, silk_RSHIFT( silk_SMULWB( w_max, c_max ), 4 ) ) ) - 5 ); - Qxtra = silk_max_int( Qxtra, 0 ); - for( i = 0; i < D; i++ ) { - cn[ i ] = silk_LSHIFT( ( opus_int )c[ i ], Qxtra ); - silk_assert( silk_abs(cn[i]) <= ( silk_int16_MAX + 1 ) ); /* Check that silk_SMLAWB can be used */ - } - lshifts -= Qxtra; - - /* Compute wxx - 2 * wXx * c */ - tmp = 0; - for( i = 0; i < D; i++ ) { - tmp = silk_SMLAWB( tmp, wXx[ i ], cn[ i ] ); - } - nrg = silk_RSHIFT( wxx, 1 + lshifts ) - tmp; /* Q: -lshifts - 1 */ - - /* Add c' * wXX * c, assuming wXX is symmetric */ - tmp2 = 0; - for( i = 0; i < D; i++ ) { - tmp = 0; - pRow = &wXX[ i * D ]; - for( j = i + 1; j < D; j++ ) { - tmp = silk_SMLAWB( tmp, pRow[ j ], cn[ j ] ); - } - tmp = silk_SMLAWB( tmp, silk_RSHIFT( pRow[ i ], 1 ), cn[ i ] ); - tmp2 = silk_SMLAWB( tmp2, tmp, cn[ i ] ); - } - nrg = silk_ADD_LSHIFT32( nrg, tmp2, lshifts ); /* Q: -lshifts - 1 */ - - /* Keep one bit free always, because we add them for LSF interpolation */ - if( nrg < 1 ) { - nrg = 1; - } else if( nrg > silk_RSHIFT( silk_int32_MAX, lshifts + 2 ) ) { - nrg = silk_int32_MAX >> 1; - } else { - nrg = silk_LSHIFT( nrg, lshifts + 1 ); /* Q0 */ - } - return nrg; - -} diff --git a/src/opus-1.0.2/silk/fixed/residual_energy_FIX.c b/src/opus-1.0.2/silk/fixed/residual_energy_FIX.c deleted file mode 100644 index f284e51f..00000000 --- a/src/opus-1.0.2/silk/fixed/residual_energy_FIX.c +++ /dev/null @@ -1,91 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main_FIX.h" - -/* Calculates residual energies of input subframes where all subframes have LPC_order */ -/* of preceding samples */ -void silk_residual_energy_FIX( - opus_int32 nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */ - opus_int nrgsQ[ MAX_NB_SUBFR ], /* O Q value per subframe */ - const opus_int16 x[], /* I Input signal */ - opus_int16 a_Q12[ 2 ][ MAX_LPC_ORDER ], /* I AR coefs for each frame half */ - const opus_int32 gains[ MAX_NB_SUBFR ], /* I Quantization gains */ - const opus_int subfr_length, /* I Subframe length */ - const opus_int nb_subfr, /* I Number of subframes */ - const opus_int LPC_order /* I LPC order */ -) -{ - opus_int offset, i, j, rshift, lz1, lz2; - opus_int16 *LPC_res_ptr, LPC_res[ ( MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ) / 2 ]; - const opus_int16 *x_ptr; - opus_int32 tmp32; - - x_ptr = x; - offset = LPC_order + subfr_length; - - /* Filter input to create the LPC residual for each frame half, and measure subframe energies */ - for( i = 0; i < nb_subfr >> 1; i++ ) { - /* Calculate half frame LPC residual signal including preceding samples */ - silk_LPC_analysis_filter( LPC_res, x_ptr, a_Q12[ i ], ( MAX_NB_SUBFR >> 1 ) * offset, LPC_order ); - - /* Point to first subframe of the just calculated LPC residual signal */ - LPC_res_ptr = LPC_res + LPC_order; - for( j = 0; j < ( MAX_NB_SUBFR >> 1 ); j++ ) { - /* Measure subframe energy */ - silk_sum_sqr_shift( &nrgs[ i * ( MAX_NB_SUBFR >> 1 ) + j ], &rshift, LPC_res_ptr, subfr_length ); - - /* Set Q values for the measured energy */ - nrgsQ[ i * ( MAX_NB_SUBFR >> 1 ) + j ] = -rshift; - - /* Move to next subframe */ - LPC_res_ptr += offset; - } - /* Move to next frame half */ - x_ptr += ( MAX_NB_SUBFR >> 1 ) * offset; - } - - /* Apply the squared subframe gains */ - for( i = 0; i < nb_subfr; i++ ) { - /* Fully upscale gains and energies */ - lz1 = silk_CLZ32( nrgs[ i ] ) - 1; - lz2 = silk_CLZ32( gains[ i ] ) - 1; - - tmp32 = silk_LSHIFT32( gains[ i ], lz2 ); - - /* Find squared gains */ - tmp32 = silk_SMMUL( tmp32, tmp32 ); /* Q( 2 * lz2 - 32 )*/ - - /* Scale energies */ - nrgs[ i ] = silk_SMMUL( tmp32, silk_LSHIFT32( nrgs[ i ], lz1 ) ); /* Q( nrgsQ[ i ] + lz1 + 2 * lz2 - 32 - 32 )*/ - nrgsQ[ i ] += lz1 + 2 * lz2 - 32 - 32; - } -} diff --git a/src/opus-1.0.2/silk/fixed/schur64_FIX.c b/src/opus-1.0.2/silk/fixed/schur64_FIX.c deleted file mode 100644 index 5ff27567..00000000 --- a/src/opus-1.0.2/silk/fixed/schur64_FIX.c +++ /dev/null @@ -1,77 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "SigProc_FIX.h" - -/* Slower than schur(), but more accurate. */ -/* Uses SMULL(), available on armv4 */ -opus_int32 silk_schur64( /* O returns residual energy */ - opus_int32 rc_Q16[], /* O Reflection coefficients [order] Q16 */ - const opus_int32 c[], /* I Correlations [order+1] */ - opus_int32 order /* I Prediction order */ -) -{ - opus_int k, n; - opus_int32 C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ]; - opus_int32 Ctmp1_Q30, Ctmp2_Q30, rc_tmp_Q31; - - silk_assert( order==6||order==8||order==10||order==12||order==14||order==16 ); - - /* Check for invalid input */ - if( c[ 0 ] <= 0 ) { - silk_memset( rc_Q16, 0, order * sizeof( opus_int32 ) ); - return 0; - } - - for( k = 0; k < order + 1; k++ ) { - C[ k ][ 0 ] = C[ k ][ 1 ] = c[ k ]; - } - - for( k = 0; k < order; k++ ) { - /* Get reflection coefficient: divide two Q30 values and get result in Q31 */ - rc_tmp_Q31 = silk_DIV32_varQ( -C[ k + 1 ][ 0 ], C[ 0 ][ 1 ], 31 ); - - /* Save the output */ - rc_Q16[ k ] = silk_RSHIFT_ROUND( rc_tmp_Q31, 15 ); - - /* Update correlations */ - for( n = 0; n < order - k; n++ ) { - Ctmp1_Q30 = C[ n + k + 1 ][ 0 ]; - Ctmp2_Q30 = C[ n ][ 1 ]; - - /* Multiply and add the highest int32 */ - C[ n + k + 1 ][ 0 ] = Ctmp1_Q30 + silk_SMMUL( silk_LSHIFT( Ctmp2_Q30, 1 ), rc_tmp_Q31 ); - C[ n ][ 1 ] = Ctmp2_Q30 + silk_SMMUL( silk_LSHIFT( Ctmp1_Q30, 1 ), rc_tmp_Q31 ); - } - } - - return( C[ 0 ][ 1 ] ); -} diff --git a/src/opus-1.0.2/silk/fixed/schur_FIX.c b/src/opus-1.0.2/silk/fixed/schur_FIX.c deleted file mode 100644 index 43db5018..00000000 --- a/src/opus-1.0.2/silk/fixed/schur_FIX.c +++ /dev/null @@ -1,92 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "SigProc_FIX.h" - -/* Faster than schur64(), but much less accurate. */ -/* uses SMLAWB(), requiring armv5E and higher. */ -opus_int32 silk_schur( /* O Returns residual energy */ - opus_int16 *rc_Q15, /* O reflection coefficients [order] Q15 */ - const opus_int32 *c, /* I correlations [order+1] */ - const opus_int32 order /* I prediction order */ -) -{ - opus_int k, n, lz; - opus_int32 C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ]; - opus_int32 Ctmp1, Ctmp2, rc_tmp_Q15; - - silk_assert( order==6||order==8||order==10||order==12||order==14||order==16 ); - - /* Get number of leading zeros */ - lz = silk_CLZ32( c[ 0 ] ); - - /* Copy correlations and adjust level to Q30 */ - if( lz < 2 ) { - /* lz must be 1, so shift one to the right */ - for( k = 0; k < order + 1; k++ ) { - C[ k ][ 0 ] = C[ k ][ 1 ] = silk_RSHIFT( c[ k ], 1 ); - } - } else if( lz > 2 ) { - /* Shift to the left */ - lz -= 2; - for( k = 0; k < order + 1; k++ ) { - C[ k ][ 0 ] = C[ k ][ 1 ] = silk_LSHIFT( c[ k ], lz ); - } - } else { - /* No need to shift */ - for( k = 0; k < order + 1; k++ ) { - C[ k ][ 0 ] = C[ k ][ 1 ] = c[ k ]; - } - } - - for( k = 0; k < order; k++ ) { - - /* Get reflection coefficient */ - rc_tmp_Q15 = -silk_DIV32_16( C[ k + 1 ][ 0 ], silk_max_32( silk_RSHIFT( C[ 0 ][ 1 ], 15 ), 1 ) ); - - /* Clip (shouldn't happen for properly conditioned inputs) */ - rc_tmp_Q15 = silk_SAT16( rc_tmp_Q15 ); - - /* Store */ - rc_Q15[ k ] = (opus_int16)rc_tmp_Q15; - - /* Update correlations */ - for( n = 0; n < order - k; n++ ) { - Ctmp1 = C[ n + k + 1 ][ 0 ]; - Ctmp2 = C[ n ][ 1 ]; - C[ n + k + 1 ][ 0 ] = silk_SMLAWB( Ctmp1, silk_LSHIFT( Ctmp2, 1 ), rc_tmp_Q15 ); - C[ n ][ 1 ] = silk_SMLAWB( Ctmp2, silk_LSHIFT( Ctmp1, 1 ), rc_tmp_Q15 ); - } - } - - /* return residual energy */ - return C[ 0 ][ 1 ]; -} diff --git a/src/opus-1.0.2/silk/fixed/solve_LS_FIX.c b/src/opus-1.0.2/silk/fixed/solve_LS_FIX.c deleted file mode 100644 index fb913abe..00000000 --- a/src/opus-1.0.2/silk/fixed/solve_LS_FIX.c +++ /dev/null @@ -1,245 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main_FIX.h" -#include "tuning_parameters.h" - -/*****************************/ -/* Internal function headers */ -/*****************************/ - -typedef struct { - opus_int32 Q36_part; - opus_int32 Q48_part; -} inv_D_t; - -/* Factorize square matrix A into LDL form */ -static inline void silk_LDL_factorize_FIX( - opus_int32 *A, /* I/O Pointer to Symetric Square Matrix */ - opus_int M, /* I Size of Matrix */ - opus_int32 *L_Q16, /* I/O Pointer to Square Upper triangular Matrix */ - inv_D_t *inv_D /* I/O Pointer to vector holding inverted diagonal elements of D */ -); - -/* Solve Lx = b, when L is lower triangular and has ones on the diagonal */ -static inline void silk_LS_SolveFirst_FIX( - const opus_int32 *L_Q16, /* I Pointer to Lower Triangular Matrix */ - opus_int M, /* I Dim of Matrix equation */ - const opus_int32 *b, /* I b Vector */ - opus_int32 *x_Q16 /* O x Vector */ -); - -/* Solve L^t*x = b, where L is lower triangular with ones on the diagonal */ -static inline void silk_LS_SolveLast_FIX( - const opus_int32 *L_Q16, /* I Pointer to Lower Triangular Matrix */ - const opus_int M, /* I Dim of Matrix equation */ - const opus_int32 *b, /* I b Vector */ - opus_int32 *x_Q16 /* O x Vector */ -); - -static inline void silk_LS_divide_Q16_FIX( - opus_int32 T[], /* I/O Numenator vector */ - inv_D_t *inv_D, /* I 1 / D vector */ - opus_int M /* I dimension */ -); - -/* Solves Ax = b, assuming A is symmetric */ -void silk_solve_LDL_FIX( - opus_int32 *A, /* I Pointer to symetric square matrix A */ - opus_int M, /* I Size of matrix */ - const opus_int32 *b, /* I Pointer to b vector */ - opus_int32 *x_Q16 /* O Pointer to x solution vector */ -) -{ - opus_int32 L_Q16[ MAX_MATRIX_SIZE * MAX_MATRIX_SIZE ]; - opus_int32 Y[ MAX_MATRIX_SIZE ]; - inv_D_t inv_D[ MAX_MATRIX_SIZE ]; - - silk_assert( M <= MAX_MATRIX_SIZE ); - - /*************************************************** - Factorize A by LDL such that A = L*D*L', - where L is lower triangular with ones on diagonal - ****************************************************/ - silk_LDL_factorize_FIX( A, M, L_Q16, inv_D ); - - /**************************************************** - * substitute D*L'*x = Y. ie: - L*D*L'*x = b => L*Y = b <=> Y = inv(L)*b - ******************************************************/ - silk_LS_SolveFirst_FIX( L_Q16, M, b, Y ); - - /**************************************************** - D*L'*x = Y <=> L'*x = inv(D)*Y, because D is - diagonal just multiply with 1/d_i - ****************************************************/ - silk_LS_divide_Q16_FIX( Y, inv_D, M ); - - /**************************************************** - x = inv(L') * inv(D) * Y - *****************************************************/ - silk_LS_SolveLast_FIX( L_Q16, M, Y, x_Q16 ); -} - -static inline void silk_LDL_factorize_FIX( - opus_int32 *A, /* I/O Pointer to Symetric Square Matrix */ - opus_int M, /* I Size of Matrix */ - opus_int32 *L_Q16, /* I/O Pointer to Square Upper triangular Matrix */ - inv_D_t *inv_D /* I/O Pointer to vector holding inverted diagonal elements of D */ -) -{ - opus_int i, j, k, status, loop_count; - const opus_int32 *ptr1, *ptr2; - opus_int32 diag_min_value, tmp_32, err; - opus_int32 v_Q0[ MAX_MATRIX_SIZE ], D_Q0[ MAX_MATRIX_SIZE ]; - opus_int32 one_div_diag_Q36, one_div_diag_Q40, one_div_diag_Q48; - - silk_assert( M <= MAX_MATRIX_SIZE ); - - status = 1; - diag_min_value = silk_max_32( silk_SMMUL( silk_ADD_SAT32( A[ 0 ], A[ silk_SMULBB( M, M ) - 1 ] ), SILK_FIX_CONST( FIND_LTP_COND_FAC, 31 ) ), 1 << 9 ); - for( loop_count = 0; loop_count < M && status == 1; loop_count++ ) { - status = 0; - for( j = 0; j < M; j++ ) { - ptr1 = matrix_adr( L_Q16, j, 0, M ); - tmp_32 = 0; - for( i = 0; i < j; i++ ) { - v_Q0[ i ] = silk_SMULWW( D_Q0[ i ], ptr1[ i ] ); /* Q0 */ - tmp_32 = silk_SMLAWW( tmp_32, v_Q0[ i ], ptr1[ i ] ); /* Q0 */ - } - tmp_32 = silk_SUB32( matrix_ptr( A, j, j, M ), tmp_32 ); - - if( tmp_32 < diag_min_value ) { - tmp_32 = silk_SUB32( silk_SMULBB( loop_count + 1, diag_min_value ), tmp_32 ); - /* Matrix not positive semi-definite, or ill conditioned */ - for( i = 0; i < M; i++ ) { - matrix_ptr( A, i, i, M ) = silk_ADD32( matrix_ptr( A, i, i, M ), tmp_32 ); - } - status = 1; - break; - } - D_Q0[ j ] = tmp_32; /* always < max(Correlation) */ - - /* two-step division */ - one_div_diag_Q36 = silk_INVERSE32_varQ( tmp_32, 36 ); /* Q36 */ - one_div_diag_Q40 = silk_LSHIFT( one_div_diag_Q36, 4 ); /* Q40 */ - err = silk_SUB32( (opus_int32)1 << 24, silk_SMULWW( tmp_32, one_div_diag_Q40 ) ); /* Q24 */ - one_div_diag_Q48 = silk_SMULWW( err, one_div_diag_Q40 ); /* Q48 */ - - /* Save 1/Ds */ - inv_D[ j ].Q36_part = one_div_diag_Q36; - inv_D[ j ].Q48_part = one_div_diag_Q48; - - matrix_ptr( L_Q16, j, j, M ) = 65536; /* 1.0 in Q16 */ - ptr1 = matrix_adr( A, j, 0, M ); - ptr2 = matrix_adr( L_Q16, j + 1, 0, M ); - for( i = j + 1; i < M; i++ ) { - tmp_32 = 0; - for( k = 0; k < j; k++ ) { - tmp_32 = silk_SMLAWW( tmp_32, v_Q0[ k ], ptr2[ k ] ); /* Q0 */ - } - tmp_32 = silk_SUB32( ptr1[ i ], tmp_32 ); /* always < max(Correlation) */ - - /* tmp_32 / D_Q0[j] : Divide to Q16 */ - matrix_ptr( L_Q16, i, j, M ) = silk_ADD32( silk_SMMUL( tmp_32, one_div_diag_Q48 ), - silk_RSHIFT( silk_SMULWW( tmp_32, one_div_diag_Q36 ), 4 ) ); - - /* go to next column */ - ptr2 += M; - } - } - } - - silk_assert( status == 0 ); -} - -static inline void silk_LS_divide_Q16_FIX( - opus_int32 T[], /* I/O Numenator vector */ - inv_D_t *inv_D, /* I 1 / D vector */ - opus_int M /* I dimension */ -) -{ - opus_int i; - opus_int32 tmp_32; - opus_int32 one_div_diag_Q36, one_div_diag_Q48; - - for( i = 0; i < M; i++ ) { - one_div_diag_Q36 = inv_D[ i ].Q36_part; - one_div_diag_Q48 = inv_D[ i ].Q48_part; - - tmp_32 = T[ i ]; - T[ i ] = silk_ADD32( silk_SMMUL( tmp_32, one_div_diag_Q48 ), silk_RSHIFT( silk_SMULWW( tmp_32, one_div_diag_Q36 ), 4 ) ); - } -} - -/* Solve Lx = b, when L is lower triangular and has ones on the diagonal */ -static inline void silk_LS_SolveFirst_FIX( - const opus_int32 *L_Q16, /* I Pointer to Lower Triangular Matrix */ - opus_int M, /* I Dim of Matrix equation */ - const opus_int32 *b, /* I b Vector */ - opus_int32 *x_Q16 /* O x Vector */ -) -{ - opus_int i, j; - const opus_int32 *ptr32; - opus_int32 tmp_32; - - for( i = 0; i < M; i++ ) { - ptr32 = matrix_adr( L_Q16, i, 0, M ); - tmp_32 = 0; - for( j = 0; j < i; j++ ) { - tmp_32 = silk_SMLAWW( tmp_32, ptr32[ j ], x_Q16[ j ] ); - } - x_Q16[ i ] = silk_SUB32( b[ i ], tmp_32 ); - } -} - -/* Solve L^t*x = b, where L is lower triangular with ones on the diagonal */ -static inline void silk_LS_SolveLast_FIX( - const opus_int32 *L_Q16, /* I Pointer to Lower Triangular Matrix */ - const opus_int M, /* I Dim of Matrix equation */ - const opus_int32 *b, /* I b Vector */ - opus_int32 *x_Q16 /* O x Vector */ -) -{ - opus_int i, j; - const opus_int32 *ptr32; - opus_int32 tmp_32; - - for( i = M - 1; i >= 0; i-- ) { - ptr32 = matrix_adr( L_Q16, 0, i, M ); - tmp_32 = 0; - for( j = M - 1; j > i; j-- ) { - tmp_32 = silk_SMLAWW( tmp_32, ptr32[ silk_SMULBB( j, M ) ], x_Q16[ j ] ); - } - x_Q16[ i ] = silk_SUB32( b[ i ], tmp_32 ); - } -} diff --git a/src/opus-1.0.2/silk/fixed/structs_FIX.h b/src/opus-1.0.2/silk/fixed/structs_FIX.h deleted file mode 100644 index 4162608b..00000000 --- a/src/opus-1.0.2/silk/fixed/structs_FIX.h +++ /dev/null @@ -1,133 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifndef SILK_STRUCTS_FIX_H -#define SILK_STRUCTS_FIX_H - -#include "typedef.h" -#include "main.h" -#include "structs.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -/********************************/ -/* Noise shaping analysis state */ -/********************************/ -typedef struct { - opus_int8 LastGainIndex; - opus_int32 HarmBoost_smth_Q16; - opus_int32 HarmShapeGain_smth_Q16; - opus_int32 Tilt_smth_Q16; -} silk_shape_state_FIX; - -/********************************/ -/* Prefilter state */ -/********************************/ -typedef struct { - opus_int16 sLTP_shp[ LTP_BUF_LENGTH ]; - opus_int32 sAR_shp[ MAX_SHAPE_LPC_ORDER + 1 ]; - opus_int sLTP_shp_buf_idx; - opus_int32 sLF_AR_shp_Q12; - opus_int32 sLF_MA_shp_Q12; - opus_int32 sHarmHP_Q2; - opus_int32 rand_seed; - opus_int lagPrev; -} silk_prefilter_state_FIX; - -/********************************/ -/* Encoder state FIX */ -/********************************/ -typedef struct { - silk_encoder_state sCmn; /* Common struct, shared with floating-point code */ - silk_shape_state_FIX sShape; /* Shape state */ - silk_prefilter_state_FIX sPrefilt; /* Prefilter State */ - - /* Buffer for find pitch and noise shape analysis */ - silk_DWORD_ALIGN opus_int16 x_buf[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ];/* Buffer for find pitch and noise shape analysis */ - opus_int LTPCorr_Q15; /* Normalized correlation from pitch lag estimator */ -} silk_encoder_state_FIX; - -/************************/ -/* Encoder control FIX */ -/************************/ -typedef struct { - /* Prediction and coding parameters */ - opus_int32 Gains_Q16[ MAX_NB_SUBFR ]; - silk_DWORD_ALIGN opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ]; - opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ]; - opus_int LTP_scale_Q14; - opus_int pitchL[ MAX_NB_SUBFR ]; - - /* Noise shaping parameters */ - /* Testing */ - silk_DWORD_ALIGN opus_int16 AR1_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ]; - silk_DWORD_ALIGN opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ]; - opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ]; /* Packs two int16 coefficients per int32 value */ - opus_int GainsPre_Q14[ MAX_NB_SUBFR ]; - opus_int HarmBoost_Q14[ MAX_NB_SUBFR ]; - opus_int Tilt_Q14[ MAX_NB_SUBFR ]; - opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ]; - opus_int Lambda_Q10; - opus_int input_quality_Q14; - opus_int coding_quality_Q14; - - /* measures */ - opus_int sparseness_Q8; - opus_int32 predGain_Q16; - opus_int LTPredCodGain_Q7; - opus_int32 ResNrg[ MAX_NB_SUBFR ]; /* Residual energy per subframe */ - opus_int ResNrgQ[ MAX_NB_SUBFR ]; /* Q domain for the residual energy > 0 */ - - /* Parameters for CBR mode */ - opus_int32 GainsUnq_Q16[ MAX_NB_SUBFR ]; - opus_int8 lastGainIndexPrev; -} silk_encoder_control_FIX; - -/************************/ -/* Encoder Super Struct */ -/************************/ -typedef struct { - silk_encoder_state_FIX state_Fxx[ ENCODER_NUM_CHANNELS ]; - stereo_enc_state sStereo; - opus_int32 nBitsExceeded; - opus_int nChannelsAPI; - opus_int nChannelsInternal; - opus_int nPrevChannelsInternal; - opus_int timeSinceSwitchAllowed_ms; - opus_int allowBandwidthSwitch; - opus_int prev_decode_only_middle; -} silk_encoder; - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/opus-1.0.2/silk/fixed/vector_ops_FIX.c b/src/opus-1.0.2/silk/fixed/vector_ops_FIX.c deleted file mode 100644 index d6206024..00000000 --- a/src/opus-1.0.2/silk/fixed/vector_ops_FIX.c +++ /dev/null @@ -1,127 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "SigProc_FIX.h" - -/* Copy and multiply a vector by a constant */ -void silk_scale_copy_vector16( - opus_int16 *data_out, - const opus_int16 *data_in, - opus_int32 gain_Q16, /* I Gain in Q16 */ - const opus_int dataSize /* I Length */ -) -{ - opus_int i; - opus_int32 tmp32; - - for( i = 0; i < dataSize; i++ ) { - tmp32 = silk_SMULWB( gain_Q16, data_in[ i ] ); - data_out[ i ] = (opus_int16)silk_CHECK_FIT16( tmp32 ); - } -} - -/* Multiply a vector by a constant */ -void silk_scale_vector32_Q26_lshift_18( - opus_int32 *data1, /* I/O Q0/Q18 */ - opus_int32 gain_Q26, /* I Q26 */ - opus_int dataSize /* I length */ -) -{ - opus_int i; - - for( i = 0; i < dataSize; i++ ) { - data1[ i ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( silk_SMULL( data1[ i ], gain_Q26 ), 8 ) ); /* OUTPUT: Q18 */ - } -} - -/* sum = for(i=0;i6, memory access can be reduced by half. */ -opus_int32 silk_inner_prod_aligned( - const opus_int16 *const inVec1, /* I input vector 1 */ - const opus_int16 *const inVec2, /* I input vector 2 */ - const opus_int len /* I vector lengths */ -) -{ - opus_int i; - opus_int32 sum = 0; - for( i = 0; i < len; i++ ) { - sum = silk_SMLABB( sum, inVec1[ i ], inVec2[ i ] ); - } - return sum; -} - -opus_int64 silk_inner_prod16_aligned_64( - const opus_int16 *inVec1, /* I input vector 1 */ - const opus_int16 *inVec2, /* I input vector 2 */ - const opus_int len /* I vector lengths */ -) -{ - opus_int i; - opus_int64 sum = 0; - for( i = 0; i < len; i++ ) { - sum = silk_SMLALBB( sum, inVec1[ i ], inVec2[ i ] ); - } - return sum; -} - -/* Function that returns the maximum absolut value of the input vector */ -opus_int16 silk_int16_array_maxabs( /* O Maximum absolute value, max: 2^15-1 */ - const opus_int16 *vec, /* I Input vector [len] */ - const opus_int32 len /* I Length of input vector */ -) -{ - opus_int32 max = 0, i, lvl = 0, ind; - if( len == 0 ) return 0; - - ind = len - 1; - max = silk_SMULBB( vec[ ind ], vec[ ind ] ); - for( i = len - 2; i >= 0; i-- ) { - lvl = silk_SMULBB( vec[ i ], vec[ i ] ); - if( lvl > max ) { - max = lvl; - ind = i; - } - } - - /* Do not return 32768, as it will not fit in an int16 so may lead to problems later on */ - if( max >= 1073676289 ) { /* (2^15-1)^2 = 1073676289 */ - return( silk_int16_MAX ); - } else { - if( vec[ ind ] < 0 ) { - return( -vec[ ind ] ); - } else { - return( vec[ ind ] ); - } - } -} diff --git a/src/opus-1.0.2/silk/fixed/warped_autocorrelation_FIX.c b/src/opus-1.0.2/silk/fixed/warped_autocorrelation_FIX.c deleted file mode 100644 index d7a3944b..00000000 --- a/src/opus-1.0.2/silk/fixed/warped_autocorrelation_FIX.c +++ /dev/null @@ -1,88 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main_FIX.h" - -#define QC 10 -#define QS 14 - -/* Autocorrelations for a warped frequency axis */ -void silk_warped_autocorrelation_FIX( - opus_int32 *corr, /* O Result [order + 1] */ - opus_int *scale, /* O Scaling of the correlation vector */ - const opus_int16 *input, /* I Input data to correlate */ - const opus_int warping_Q16, /* I Warping coefficient */ - const opus_int length, /* I Length of input */ - const opus_int order /* I Correlation order (even) */ -) -{ - opus_int n, i, lsh; - opus_int32 tmp1_QS, tmp2_QS; - opus_int32 state_QS[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 }; - opus_int64 corr_QC[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 }; - - /* Order must be even */ - silk_assert( ( order & 1 ) == 0 ); - silk_assert( 2 * QS - QC >= 0 ); - - /* Loop over samples */ - for( n = 0; n < length; n++ ) { - tmp1_QS = silk_LSHIFT32( (opus_int32)input[ n ], QS ); - /* Loop over allpass sections */ - for( i = 0; i < order; i += 2 ) { - /* Output of allpass section */ - tmp2_QS = silk_SMLAWB( state_QS[ i ], state_QS[ i + 1 ] - tmp1_QS, warping_Q16 ); - state_QS[ i ] = tmp1_QS; - corr_QC[ i ] += silk_RSHIFT64( silk_SMULL( tmp1_QS, state_QS[ 0 ] ), 2 * QS - QC ); - /* Output of allpass section */ - tmp1_QS = silk_SMLAWB( state_QS[ i + 1 ], state_QS[ i + 2 ] - tmp2_QS, warping_Q16 ); - state_QS[ i + 1 ] = tmp2_QS; - corr_QC[ i + 1 ] += silk_RSHIFT64( silk_SMULL( tmp2_QS, state_QS[ 0 ] ), 2 * QS - QC ); - } - state_QS[ order ] = tmp1_QS; - corr_QC[ order ] += silk_RSHIFT64( silk_SMULL( tmp1_QS, state_QS[ 0 ] ), 2 * QS - QC ); - } - - lsh = silk_CLZ64( corr_QC[ 0 ] ) - 35; - lsh = silk_LIMIT( lsh, -12 - QC, 30 - QC ); - *scale = -( QC + lsh ); - silk_assert( *scale >= -30 && *scale <= 12 ); - if( lsh >= 0 ) { - for( i = 0; i < order + 1; i++ ) { - corr[ i ] = (opus_int32)silk_CHECK_FIT32( silk_LSHIFT64( corr_QC[ i ], lsh ) ); - } - } else { - for( i = 0; i < order + 1; i++ ) { - corr[ i ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( corr_QC[ i ], -lsh ) ); - } - } - silk_assert( corr_QC[ 0 ] >= 0 ); /* If breaking, decrease QC*/ -} diff --git a/src/opus-1.0.2/silk/float/LPC_analysis_filter_FLP.c b/src/opus-1.0.2/silk/float/LPC_analysis_filter_FLP.c deleted file mode 100644 index 9845655b..00000000 --- a/src/opus-1.0.2/silk/float/LPC_analysis_filter_FLP.c +++ /dev/null @@ -1,249 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "main_FLP.h" - -/************************************************/ -/* LPC analysis filter */ -/* NB! State is kept internally and the */ -/* filter always starts with zero state */ -/* first Order output samples are set to zero */ -/************************************************/ - -/* 16th order LPC analysis filter, does not write first 16 samples */ -static inline void silk_LPC_analysis_filter16_FLP( - silk_float r_LPC[], /* O LPC residual signal */ - const silk_float PredCoef[], /* I LPC coefficients */ - const silk_float s[], /* I Input signal */ - const opus_int length /* I Length of input signal */ -) -{ - opus_int ix; - silk_float LPC_pred; - const silk_float *s_ptr; - - for( ix = 16; ix < length; ix++ ) { - s_ptr = &s[ix - 1]; - - /* short-term prediction */ - LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] + - s_ptr[ -1 ] * PredCoef[ 1 ] + - s_ptr[ -2 ] * PredCoef[ 2 ] + - s_ptr[ -3 ] * PredCoef[ 3 ] + - s_ptr[ -4 ] * PredCoef[ 4 ] + - s_ptr[ -5 ] * PredCoef[ 5 ] + - s_ptr[ -6 ] * PredCoef[ 6 ] + - s_ptr[ -7 ] * PredCoef[ 7 ] + - s_ptr[ -8 ] * PredCoef[ 8 ] + - s_ptr[ -9 ] * PredCoef[ 9 ] + - s_ptr[ -10 ] * PredCoef[ 10 ] + - s_ptr[ -11 ] * PredCoef[ 11 ] + - s_ptr[ -12 ] * PredCoef[ 12 ] + - s_ptr[ -13 ] * PredCoef[ 13 ] + - s_ptr[ -14 ] * PredCoef[ 14 ] + - s_ptr[ -15 ] * PredCoef[ 15 ]; - - /* prediction error */ - r_LPC[ix] = s_ptr[ 1 ] - LPC_pred; - } -} - -/* 12th order LPC analysis filter, does not write first 12 samples */ -static inline void silk_LPC_analysis_filter12_FLP( - silk_float r_LPC[], /* O LPC residual signal */ - const silk_float PredCoef[], /* I LPC coefficients */ - const silk_float s[], /* I Input signal */ - const opus_int length /* I Length of input signal */ -) -{ - opus_int ix; - silk_float LPC_pred; - const silk_float *s_ptr; - - for( ix = 12; ix < length; ix++ ) { - s_ptr = &s[ix - 1]; - - /* short-term prediction */ - LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] + - s_ptr[ -1 ] * PredCoef[ 1 ] + - s_ptr[ -2 ] * PredCoef[ 2 ] + - s_ptr[ -3 ] * PredCoef[ 3 ] + - s_ptr[ -4 ] * PredCoef[ 4 ] + - s_ptr[ -5 ] * PredCoef[ 5 ] + - s_ptr[ -6 ] * PredCoef[ 6 ] + - s_ptr[ -7 ] * PredCoef[ 7 ] + - s_ptr[ -8 ] * PredCoef[ 8 ] + - s_ptr[ -9 ] * PredCoef[ 9 ] + - s_ptr[ -10 ] * PredCoef[ 10 ] + - s_ptr[ -11 ] * PredCoef[ 11 ]; - - /* prediction error */ - r_LPC[ix] = s_ptr[ 1 ] - LPC_pred; - } -} - -/* 10th order LPC analysis filter, does not write first 10 samples */ -static inline void silk_LPC_analysis_filter10_FLP( - silk_float r_LPC[], /* O LPC residual signal */ - const silk_float PredCoef[], /* I LPC coefficients */ - const silk_float s[], /* I Input signal */ - const opus_int length /* I Length of input signal */ -) -{ - opus_int ix; - silk_float LPC_pred; - const silk_float *s_ptr; - - for( ix = 10; ix < length; ix++ ) { - s_ptr = &s[ix - 1]; - - /* short-term prediction */ - LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] + - s_ptr[ -1 ] * PredCoef[ 1 ] + - s_ptr[ -2 ] * PredCoef[ 2 ] + - s_ptr[ -3 ] * PredCoef[ 3 ] + - s_ptr[ -4 ] * PredCoef[ 4 ] + - s_ptr[ -5 ] * PredCoef[ 5 ] + - s_ptr[ -6 ] * PredCoef[ 6 ] + - s_ptr[ -7 ] * PredCoef[ 7 ] + - s_ptr[ -8 ] * PredCoef[ 8 ] + - s_ptr[ -9 ] * PredCoef[ 9 ]; - - /* prediction error */ - r_LPC[ix] = s_ptr[ 1 ] - LPC_pred; - } -} - -/* 8th order LPC analysis filter, does not write first 8 samples */ -static inline void silk_LPC_analysis_filter8_FLP( - silk_float r_LPC[], /* O LPC residual signal */ - const silk_float PredCoef[], /* I LPC coefficients */ - const silk_float s[], /* I Input signal */ - const opus_int length /* I Length of input signal */ -) -{ - opus_int ix; - silk_float LPC_pred; - const silk_float *s_ptr; - - for( ix = 8; ix < length; ix++ ) { - s_ptr = &s[ix - 1]; - - /* short-term prediction */ - LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] + - s_ptr[ -1 ] * PredCoef[ 1 ] + - s_ptr[ -2 ] * PredCoef[ 2 ] + - s_ptr[ -3 ] * PredCoef[ 3 ] + - s_ptr[ -4 ] * PredCoef[ 4 ] + - s_ptr[ -5 ] * PredCoef[ 5 ] + - s_ptr[ -6 ] * PredCoef[ 6 ] + - s_ptr[ -7 ] * PredCoef[ 7 ]; - - /* prediction error */ - r_LPC[ix] = s_ptr[ 1 ] - LPC_pred; - } -} - -/* 6th order LPC analysis filter, does not write first 6 samples */ -static inline void silk_LPC_analysis_filter6_FLP( - silk_float r_LPC[], /* O LPC residual signal */ - const silk_float PredCoef[], /* I LPC coefficients */ - const silk_float s[], /* I Input signal */ - const opus_int length /* I Length of input signal */ -) -{ - opus_int ix; - silk_float LPC_pred; - const silk_float *s_ptr; - - for( ix = 6; ix < length; ix++ ) { - s_ptr = &s[ix - 1]; - - /* short-term prediction */ - LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] + - s_ptr[ -1 ] * PredCoef[ 1 ] + - s_ptr[ -2 ] * PredCoef[ 2 ] + - s_ptr[ -3 ] * PredCoef[ 3 ] + - s_ptr[ -4 ] * PredCoef[ 4 ] + - s_ptr[ -5 ] * PredCoef[ 5 ]; - - /* prediction error */ - r_LPC[ix] = s_ptr[ 1 ] - LPC_pred; - } -} - -/************************************************/ -/* LPC analysis filter */ -/* NB! State is kept internally and the */ -/* filter always starts with zero state */ -/* first Order output samples are set to zero */ -/************************************************/ -void silk_LPC_analysis_filter_FLP( - silk_float r_LPC[], /* O LPC residual signal */ - const silk_float PredCoef[], /* I LPC coefficients */ - const silk_float s[], /* I Input signal */ - const opus_int length, /* I Length of input signal */ - const opus_int Order /* I LPC order */ -) -{ - silk_assert( Order <= length ); - - switch( Order ) { - case 6: - silk_LPC_analysis_filter6_FLP( r_LPC, PredCoef, s, length ); - break; - - case 8: - silk_LPC_analysis_filter8_FLP( r_LPC, PredCoef, s, length ); - break; - - case 10: - silk_LPC_analysis_filter10_FLP( r_LPC, PredCoef, s, length ); - break; - - case 12: - silk_LPC_analysis_filter12_FLP( r_LPC, PredCoef, s, length ); - break; - - case 16: - silk_LPC_analysis_filter16_FLP( r_LPC, PredCoef, s, length ); - break; - - default: - silk_assert( 0 ); - break; - } - - /* Set first Order output samples to zero */ - silk_memset( r_LPC, 0, Order * sizeof( silk_float ) ); -} - diff --git a/src/opus-1.0.2/silk/float/LPC_inv_pred_gain_FLP.c b/src/opus-1.0.2/silk/float/LPC_inv_pred_gain_FLP.c deleted file mode 100644 index 8645f77f..00000000 --- a/src/opus-1.0.2/silk/float/LPC_inv_pred_gain_FLP.c +++ /dev/null @@ -1,76 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "SigProc_FIX.h" -#include "SigProc_FLP.h" - -#define RC_THRESHOLD 0.9999f - -/* compute inverse of LPC prediction gain, and */ -/* test if LPC coefficients are stable (all poles within unit circle) */ -/* this code is based on silk_a2k_FLP() */ -silk_float silk_LPC_inverse_pred_gain_FLP( /* O return inverse prediction gain, energy domain */ - const silk_float *A, /* I prediction coefficients [order] */ - opus_int32 order /* I prediction order */ -) -{ - opus_int k, n; - double invGain, rc, rc_mult1, rc_mult2; - silk_float Atmp[ 2 ][ SILK_MAX_ORDER_LPC ]; - silk_float *Aold, *Anew; - - Anew = Atmp[ order & 1 ]; - silk_memcpy( Anew, A, order * sizeof(silk_float) ); - - invGain = 1.0; - for( k = order - 1; k > 0; k-- ) { - rc = -Anew[ k ]; - if( rc > RC_THRESHOLD || rc < -RC_THRESHOLD ) { - return 0.0f; - } - rc_mult1 = 1.0f - rc * rc; - rc_mult2 = 1.0f / rc_mult1; - invGain *= rc_mult1; - /* swap pointers */ - Aold = Anew; - Anew = Atmp[ k & 1 ]; - for( n = 0; n < k; n++ ) { - Anew[ n ] = (silk_float)( ( Aold[ n ] - Aold[ k - n - 1 ] * rc ) * rc_mult2 ); - } - } - rc = -Anew[ 0 ]; - if( rc > RC_THRESHOLD || rc < -RC_THRESHOLD ) { - return 0.0f; - } - rc_mult1 = 1.0f - rc * rc; - invGain *= rc_mult1; - return (silk_float)invGain; -} diff --git a/src/opus-1.0.2/silk/float/LTP_analysis_filter_FLP.c b/src/opus-1.0.2/silk/float/LTP_analysis_filter_FLP.c deleted file mode 100644 index d3a6a5ae..00000000 --- a/src/opus-1.0.2/silk/float/LTP_analysis_filter_FLP.c +++ /dev/null @@ -1,75 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main_FLP.h" - -void silk_LTP_analysis_filter_FLP( - silk_float *LTP_res, /* O LTP res MAX_NB_SUBFR*(pre_lgth+subfr_lngth) */ - const silk_float *x, /* I Input signal, with preceding samples */ - const silk_float B[ LTP_ORDER * MAX_NB_SUBFR ], /* I LTP coefficients for each subframe */ - const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ - const silk_float invGains[ MAX_NB_SUBFR ], /* I Inverse quantization gains */ - const opus_int subfr_length, /* I Length of each subframe */ - const opus_int nb_subfr, /* I number of subframes */ - const opus_int pre_length /* I Preceding samples for each subframe */ -) -{ - const silk_float *x_ptr, *x_lag_ptr; - silk_float Btmp[ LTP_ORDER ]; - silk_float *LTP_res_ptr; - silk_float inv_gain; - opus_int k, i, j; - - x_ptr = x; - LTP_res_ptr = LTP_res; - for( k = 0; k < nb_subfr; k++ ) { - x_lag_ptr = x_ptr - pitchL[ k ]; - inv_gain = invGains[ k ]; - for( i = 0; i < LTP_ORDER; i++ ) { - Btmp[ i ] = B[ k * LTP_ORDER + i ]; - } - - /* LTP analysis FIR filter */ - for( i = 0; i < subfr_length + pre_length; i++ ) { - LTP_res_ptr[ i ] = x_ptr[ i ]; - /* Subtract long-term prediction */ - for( j = 0; j < LTP_ORDER; j++ ) { - LTP_res_ptr[ i ] -= Btmp[ j ] * x_lag_ptr[ LTP_ORDER / 2 - j ]; - } - LTP_res_ptr[ i ] *= inv_gain; - x_lag_ptr++; - } - - /* Update pointers */ - LTP_res_ptr += subfr_length + pre_length; - x_ptr += subfr_length; - } -} diff --git a/src/opus-1.0.2/silk/float/LTP_scale_ctrl_FLP.c b/src/opus-1.0.2/silk/float/LTP_scale_ctrl_FLP.c deleted file mode 100644 index f3f0c572..00000000 --- a/src/opus-1.0.2/silk/float/LTP_scale_ctrl_FLP.c +++ /dev/null @@ -1,52 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main_FLP.h" - -void silk_LTP_scale_ctrl_FLP( - silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ - silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ - opus_int condCoding /* I The type of conditional coding to use */ -) -{ - opus_int round_loss; - - if( condCoding == CODE_INDEPENDENTLY ) { - /* Only scale if first frame in packet */ - round_loss = psEnc->sCmn.PacketLoss_perc + psEnc->sCmn.nFramesPerPacket; - psEnc->sCmn.indices.LTP_scaleIndex = (opus_int8)silk_LIMIT( round_loss * psEncCtrl->LTPredCodGain * 0.1f, 0.0f, 2.0f ); - } else { - /* Default is minimum scaling */ - psEnc->sCmn.indices.LTP_scaleIndex = 0; - } - - psEncCtrl->LTP_scale = (silk_float)silk_LTPScales_table_Q14[ psEnc->sCmn.indices.LTP_scaleIndex ] / 16384.0f; -} diff --git a/src/opus-1.0.2/silk/float/SigProc_FLP.h b/src/opus-1.0.2/silk/float/SigProc_FLP.h deleted file mode 100644 index 036b46da..00000000 --- a/src/opus-1.0.2/silk/float/SigProc_FLP.h +++ /dev/null @@ -1,203 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifndef SILK_SIGPROC_FLP_H -#define SILK_SIGPROC_FLP_H - -#include "SigProc_FIX.h" -#include "float_cast.h" -#include - -#ifdef __cplusplus -extern "C" -{ -#endif - -/********************************************************************/ -/* SIGNAL PROCESSING FUNCTIONS */ -/********************************************************************/ - -/* Chirp (bw expand) LP AR filter */ -void silk_bwexpander_FLP( - silk_float *ar, /* I/O AR filter to be expanded (without leading 1) */ - const opus_int d, /* I length of ar */ - const silk_float chirp /* I chirp factor (typically in range (0..1) ) */ -); - -/* compute inverse of LPC prediction gain, and */ -/* test if LPC coefficients are stable (all poles within unit circle) */ -/* this code is based on silk_FLP_a2k() */ -silk_float silk_LPC_inverse_pred_gain_FLP( /* O return inverse prediction gain, energy domain */ - const silk_float *A, /* I prediction coefficients [order] */ - opus_int32 order /* I prediction order */ -); - -silk_float silk_schur_FLP( /* O returns residual energy */ - silk_float refl_coef[], /* O reflection coefficients (length order) */ - const silk_float auto_corr[], /* I autocorrelation sequence (length order+1) */ - opus_int order /* I order */ -); - -void silk_k2a_FLP( - silk_float *A, /* O prediction coefficients [order] */ - const silk_float *rc, /* I reflection coefficients [order] */ - opus_int32 order /* I prediction order */ -); - -/* Solve the normal equations using the Levinson-Durbin recursion */ -silk_float silk_levinsondurbin_FLP( /* O prediction error energy */ - silk_float A[], /* O prediction coefficients [order] */ - const silk_float corr[], /* I input auto-correlations [order + 1] */ - const opus_int order /* I prediction order */ -); - -/* compute autocorrelation */ -void silk_autocorrelation_FLP( - silk_float *results, /* O result (length correlationCount) */ - const silk_float *inputData, /* I input data to correlate */ - opus_int inputDataSize, /* I length of input */ - opus_int correlationCount /* I number of correlation taps to compute */ -); - -opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced, 1 unvoiced */ - const silk_float *frame, /* I Signal of length PE_FRAME_LENGTH_MS*Fs_kHz */ - opus_int *pitch_out, /* O Pitch lag values [nb_subfr] */ - opus_int16 *lagIndex, /* O Lag Index */ - opus_int8 *contourIndex, /* O Pitch contour Index */ - silk_float *LTPCorr, /* I/O Normalized correlation; input: value from previous frame */ - opus_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */ - const silk_float search_thres1, /* I First stage threshold for lag candidates 0 - 1 */ - const silk_float search_thres2, /* I Final threshold for lag candidates 0 - 1 */ - const opus_int Fs_kHz, /* I sample frequency (kHz) */ - const opus_int complexity, /* I Complexity setting, 0-2, where 2 is highest */ - const opus_int nb_subfr /* I Number of 5 ms subframes */ -); - -void silk_insertion_sort_decreasing_FLP( - silk_float *a, /* I/O Unsorted / Sorted vector */ - opus_int *idx, /* O Index vector for the sorted elements */ - const opus_int L, /* I Vector length */ - const opus_int K /* I Number of correctly sorted positions */ -); - -/* Compute reflection coefficients from input signal */ -silk_float silk_burg_modified_FLP( /* O returns residual energy */ - silk_float A[], /* O prediction coefficients (length order) */ - const silk_float x[], /* I input signal, length: nb_subfr*(D+L_sub) */ - const silk_float minInvGain, /* I minimum inverse prediction gain */ - const opus_int subfr_length, /* I input signal subframe length (incl. D preceding samples) */ - const opus_int nb_subfr, /* I number of subframes stacked in x */ - const opus_int D /* I order */ -); - -/* multiply a vector by a constant */ -void silk_scale_vector_FLP( - silk_float *data1, - silk_float gain, - opus_int dataSize -); - -/* copy and multiply a vector by a constant */ -void silk_scale_copy_vector_FLP( - silk_float *data_out, - const silk_float *data_in, - silk_float gain, - opus_int dataSize -); - -/* inner product of two silk_float arrays, with result as double */ -double silk_inner_product_FLP( - const silk_float *data1, - const silk_float *data2, - opus_int dataSize -); - -/* sum of squares of a silk_float array, with result as double */ -double silk_energy_FLP( - const silk_float *data, - opus_int dataSize -); - -/********************************************************************/ -/* MACROS */ -/********************************************************************/ - -#define PI (3.1415926536f) - -#define silk_min_float( a, b ) (((a) < (b)) ? (a) : (b)) -#define silk_max_float( a, b ) (((a) > (b)) ? (a) : (b)) -#define silk_abs_float( a ) ((silk_float)fabs(a)) - -/* sigmoid function */ -static inline silk_float silk_sigmoid( silk_float x ) -{ - return (silk_float)(1.0 / (1.0 + exp(-x))); -} - -/* floating-point to integer conversion (rounding) */ -static inline opus_int32 silk_float2int( silk_float x ) -{ - return (opus_int32)float2int( x ); -} - -/* floating-point to integer conversion (rounding) */ -static inline void silk_float2short_array( - opus_int16 *out, - const silk_float *in, - opus_int32 length -) -{ - opus_int32 k; - for( k = length - 1; k >= 0; k-- ) { - out[k] = silk_SAT16( (opus_int32)float2int( in[k] ) ); - } -} - -/* integer to floating-point conversion */ -static inline void silk_short2float_array( - silk_float *out, - const opus_int16 *in, - opus_int32 length -) -{ - opus_int32 k; - for( k = length - 1; k >= 0; k-- ) { - out[k] = (silk_float)in[k]; - } -} - -/* using log2() helps the fixed-point conversion */ -static inline silk_float silk_log2( double x ) -{ - return ( silk_float )( 3.32192809488736 * log10( x ) ); -} - -#ifdef __cplusplus -} -#endif - -#endif /* SILK_SIGPROC_FLP_H */ diff --git a/src/opus-1.0.2/silk/float/apply_sine_window_FLP.c b/src/opus-1.0.2/silk/float/apply_sine_window_FLP.c deleted file mode 100644 index e06333f7..00000000 --- a/src/opus-1.0.2/silk/float/apply_sine_window_FLP.c +++ /dev/null @@ -1,81 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main_FLP.h" - -/* Apply sine window to signal vector */ -/* Window types: */ -/* 1 -> sine window from 0 to pi/2 */ -/* 2 -> sine window from pi/2 to pi */ -void silk_apply_sine_window_FLP( - silk_float px_win[], /* O Pointer to windowed signal */ - const silk_float px[], /* I Pointer to input signal */ - const opus_int win_type, /* I Selects a window type */ - const opus_int length /* I Window length, multiple of 4 */ -) -{ - opus_int k; - silk_float freq, c, S0, S1; - - silk_assert( win_type == 1 || win_type == 2 ); - - /* Length must be multiple of 4 */ - silk_assert( ( length & 3 ) == 0 ); - - freq = PI / ( length + 1 ); - - /* Approximation of 2 * cos(f) */ - c = 2.0f - freq * freq; - - /* Initialize state */ - if( win_type < 2 ) { - /* Start from 0 */ - S0 = 0.0f; - /* Approximation of sin(f) */ - S1 = freq; - } else { - /* Start from 1 */ - S0 = 1.0f; - /* Approximation of cos(f) */ - S1 = 0.5f * c; - } - - /* Uses the recursive equation: sin(n*f) = 2 * cos(f) * sin((n-1)*f) - sin((n-2)*f) */ - /* 4 samples at a time */ - for( k = 0; k < length; k += 4 ) { - px_win[ k + 0 ] = px[ k + 0 ] * 0.5f * ( S0 + S1 ); - px_win[ k + 1 ] = px[ k + 1 ] * S1; - S0 = c * S1 - S0; - px_win[ k + 2 ] = px[ k + 2 ] * 0.5f * ( S1 + S0 ); - px_win[ k + 3 ] = px[ k + 3 ] * S0; - S1 = c * S0 - S1; - } -} diff --git a/src/opus-1.0.2/silk/float/autocorrelation_FLP.c b/src/opus-1.0.2/silk/float/autocorrelation_FLP.c deleted file mode 100644 index 9ce709e2..00000000 --- a/src/opus-1.0.2/silk/float/autocorrelation_FLP.c +++ /dev/null @@ -1,52 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "typedef.h" -#include "SigProc_FLP.h" - -/* compute autocorrelation */ -void silk_autocorrelation_FLP( - silk_float *results, /* O result (length correlationCount) */ - const silk_float *inputData, /* I input data to correlate */ - opus_int inputDataSize, /* I length of input */ - opus_int correlationCount /* I number of correlation taps to compute */ -) -{ - opus_int i; - - if( correlationCount > inputDataSize ) { - correlationCount = inputDataSize; - } - - for( i = 0; i < correlationCount; i++ ) { - results[ i ] = (silk_float)silk_inner_product_FLP( inputData, inputData + i, inputDataSize - i ); - } -} diff --git a/src/opus-1.0.2/silk/float/burg_modified_FLP.c b/src/opus-1.0.2/silk/float/burg_modified_FLP.c deleted file mode 100644 index 31c9b228..00000000 --- a/src/opus-1.0.2/silk/float/burg_modified_FLP.c +++ /dev/null @@ -1,186 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "SigProc_FLP.h" -#include "tuning_parameters.h" -#include "define.h" - -#define MAX_FRAME_SIZE 384 /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384*/ - -/* Compute reflection coefficients from input signal */ -silk_float silk_burg_modified_FLP( /* O returns residual energy */ - silk_float A[], /* O prediction coefficients (length order) */ - const silk_float x[], /* I input signal, length: nb_subfr*(D+L_sub) */ - const silk_float minInvGain, /* I minimum inverse prediction gain */ - const opus_int subfr_length, /* I input signal subframe length (incl. D preceding samples) */ - const opus_int nb_subfr, /* I number of subframes stacked in x */ - const opus_int D /* I order */ -) -{ - opus_int k, n, s, reached_max_gain; - double C0, invGain, num, nrg_f, nrg_b, rc, Atmp, tmp1, tmp2; - const silk_float *x_ptr; - double C_first_row[ SILK_MAX_ORDER_LPC ], C_last_row[ SILK_MAX_ORDER_LPC ]; - double CAf[ SILK_MAX_ORDER_LPC + 1 ], CAb[ SILK_MAX_ORDER_LPC + 1 ]; - double Af[ SILK_MAX_ORDER_LPC ]; - - silk_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE ); - - /* Compute autocorrelations, added over subframes */ - C0 = silk_energy_FLP( x, nb_subfr * subfr_length ); - silk_memset( C_first_row, 0, SILK_MAX_ORDER_LPC * sizeof( double ) ); - for( s = 0; s < nb_subfr; s++ ) { - x_ptr = x + s * subfr_length; - for( n = 1; n < D + 1; n++ ) { - C_first_row[ n - 1 ] += silk_inner_product_FLP( x_ptr, x_ptr + n, subfr_length - n ); - } - } - silk_memcpy( C_last_row, C_first_row, SILK_MAX_ORDER_LPC * sizeof( double ) ); - - /* Initialize */ - CAb[ 0 ] = CAf[ 0 ] = C0 + FIND_LPC_COND_FAC * C0 + 1e-9f; - invGain = 1.0f; - reached_max_gain = 0; - for( n = 0; n < D; n++ ) { - /* Update first row of correlation matrix (without first element) */ - /* Update last row of correlation matrix (without last element, stored in reversed order) */ - /* Update C * Af */ - /* Update C * flipud(Af) (stored in reversed order) */ - for( s = 0; s < nb_subfr; s++ ) { - x_ptr = x + s * subfr_length; - tmp1 = x_ptr[ n ]; - tmp2 = x_ptr[ subfr_length - n - 1 ]; - for( k = 0; k < n; k++ ) { - C_first_row[ k ] -= x_ptr[ n ] * x_ptr[ n - k - 1 ]; - C_last_row[ k ] -= x_ptr[ subfr_length - n - 1 ] * x_ptr[ subfr_length - n + k ]; - Atmp = Af[ k ]; - tmp1 += x_ptr[ n - k - 1 ] * Atmp; - tmp2 += x_ptr[ subfr_length - n + k ] * Atmp; - } - for( k = 0; k <= n; k++ ) { - CAf[ k ] -= tmp1 * x_ptr[ n - k ]; - CAb[ k ] -= tmp2 * x_ptr[ subfr_length - n + k - 1 ]; - } - } - tmp1 = C_first_row[ n ]; - tmp2 = C_last_row[ n ]; - for( k = 0; k < n; k++ ) { - Atmp = Af[ k ]; - tmp1 += C_last_row[ n - k - 1 ] * Atmp; - tmp2 += C_first_row[ n - k - 1 ] * Atmp; - } - CAf[ n + 1 ] = tmp1; - CAb[ n + 1 ] = tmp2; - - /* Calculate nominator and denominator for the next order reflection (parcor) coefficient */ - num = CAb[ n + 1 ]; - nrg_b = CAb[ 0 ]; - nrg_f = CAf[ 0 ]; - for( k = 0; k < n; k++ ) { - Atmp = Af[ k ]; - num += CAb[ n - k ] * Atmp; - nrg_b += CAb[ k + 1 ] * Atmp; - nrg_f += CAf[ k + 1 ] * Atmp; - } - silk_assert( nrg_f > 0.0 ); - silk_assert( nrg_b > 0.0 ); - - /* Calculate the next order reflection (parcor) coefficient */ - rc = -2.0 * num / ( nrg_f + nrg_b ); - silk_assert( rc > -1.0 && rc < 1.0 ); - - /* Update inverse prediction gain */ - tmp1 = invGain * ( 1.0 - rc * rc ); - if( tmp1 <= minInvGain ) { - /* Max prediction gain exceeded; set reflection coefficient such that max prediction gain is exactly hit */ - rc = sqrt( 1.0 - minInvGain / invGain ); - if( num > 0 ) { - /* Ensure adjusted reflection coefficients has the original sign */ - rc = -rc; - } - invGain = minInvGain; - reached_max_gain = 1; - } else { - invGain = tmp1; - } - - /* Update the AR coefficients */ - for( k = 0; k < (n + 1) >> 1; k++ ) { - tmp1 = Af[ k ]; - tmp2 = Af[ n - k - 1 ]; - Af[ k ] = tmp1 + rc * tmp2; - Af[ n - k - 1 ] = tmp2 + rc * tmp1; - } - Af[ n ] = rc; - - if( reached_max_gain ) { - /* Reached max prediction gain; set remaining coefficients to zero and exit loop */ - for( k = n + 1; k < D; k++ ) { - Af[ k ] = 0.0; - } - break; - } - - /* Update C * Af and C * Ab */ - for( k = 0; k <= n + 1; k++ ) { - tmp1 = CAf[ k ]; - CAf[ k ] += rc * CAb[ n - k + 1 ]; - CAb[ n - k + 1 ] += rc * tmp1; - } - } - - if( reached_max_gain ) { - /* Convert to silk_float */ - for( k = 0; k < D; k++ ) { - A[ k ] = (silk_float)( -Af[ k ] ); - } - /* Subtract energy of preceding samples from C0 */ - for( s = 0; s < nb_subfr; s++ ) { - C0 -= silk_energy_FLP( x + s * subfr_length, D ); - } - /* Approximate residual energy */ - nrg_f = C0 * invGain; - } else { - /* Compute residual energy and store coefficients as silk_float */ - nrg_f = CAf[ 0 ]; - tmp1 = 1.0; - for( k = 0; k < D; k++ ) { - Atmp = Af[ k ]; - nrg_f += CAf[ k + 1 ] * Atmp; - tmp1 += Atmp * Atmp; - A[ k ] = (silk_float)(-Atmp); - } - nrg_f -= FIND_LPC_COND_FAC * C0 * tmp1; - } - - /* Return residual energy */ - return (silk_float)nrg_f; -} diff --git a/src/opus-1.0.2/silk/float/bwexpander_FLP.c b/src/opus-1.0.2/silk/float/bwexpander_FLP.c deleted file mode 100644 index 59ca4eaf..00000000 --- a/src/opus-1.0.2/silk/float/bwexpander_FLP.c +++ /dev/null @@ -1,49 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "SigProc_FLP.h" - -/* Chirp (bw expand) LP AR filter */ -void silk_bwexpander_FLP( - silk_float *ar, /* I/O AR filter to be expanded (without leading 1) */ - const opus_int d, /* I length of ar */ - const silk_float chirp /* I chirp factor (typically in range (0..1) ) */ -) -{ - opus_int i; - silk_float cfac = chirp; - - for( i = 0; i < d - 1; i++ ) { - ar[ i ] *= cfac; - cfac *= chirp; - } - ar[ d - 1 ] *= cfac; -} diff --git a/src/opus-1.0.2/silk/float/corrMatrix_FLP.c b/src/opus-1.0.2/silk/float/corrMatrix_FLP.c deleted file mode 100644 index c59f73c3..00000000 --- a/src/opus-1.0.2/silk/float/corrMatrix_FLP.c +++ /dev/null @@ -1,93 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/********************************************************************** - * Correlation matrix computations for LS estimate. - **********************************************************************/ - -#include "main_FLP.h" - -/* Calculates correlation vector X'*t */ -void silk_corrVector_FLP( - const silk_float *x, /* I x vector [L+order-1] used to create X */ - const silk_float *t, /* I Target vector [L] */ - const opus_int L, /* I Length of vecors */ - const opus_int Order, /* I Max lag for correlation */ - silk_float *Xt /* O X'*t correlation vector [order] */ -) -{ - opus_int lag; - const silk_float *ptr1; - - ptr1 = &x[ Order - 1 ]; /* Points to first sample of column 0 of X: X[:,0] */ - for( lag = 0; lag < Order; lag++ ) { - /* Calculate X[:,lag]'*t */ - Xt[ lag ] = (silk_float)silk_inner_product_FLP( ptr1, t, L ); - ptr1--; /* Next column of X */ - } -} - -/* Calculates correlation matrix X'*X */ -void silk_corrMatrix_FLP( - const silk_float *x, /* I x vector [ L+order-1 ] used to create X */ - const opus_int L, /* I Length of vectors */ - const opus_int Order, /* I Max lag for correlation */ - silk_float *XX /* O X'*X correlation matrix [order x order] */ -) -{ - opus_int j, lag; - double energy; - const silk_float *ptr1, *ptr2; - - ptr1 = &x[ Order - 1 ]; /* First sample of column 0 of X */ - energy = silk_energy_FLP( ptr1, L ); /* X[:,0]'*X[:,0] */ - matrix_ptr( XX, 0, 0, Order ) = ( silk_float )energy; - for( j = 1; j < Order; j++ ) { - /* Calculate X[:,j]'*X[:,j] */ - energy += ptr1[ -j ] * ptr1[ -j ] - ptr1[ L - j ] * ptr1[ L - j ]; - matrix_ptr( XX, j, j, Order ) = ( silk_float )energy; - } - - ptr2 = &x[ Order - 2 ]; /* First sample of column 1 of X */ - for( lag = 1; lag < Order; lag++ ) { - /* Calculate X[:,0]'*X[:,lag] */ - energy = silk_inner_product_FLP( ptr1, ptr2, L ); - matrix_ptr( XX, lag, 0, Order ) = ( silk_float )energy; - matrix_ptr( XX, 0, lag, Order ) = ( silk_float )energy; - /* Calculate X[:,j]'*X[:,j + lag] */ - for( j = 1; j < ( Order - lag ); j++ ) { - energy += ptr1[ -j ] * ptr2[ -j ] - ptr1[ L - j ] * ptr2[ L - j ]; - matrix_ptr( XX, lag + j, j, Order ) = ( silk_float )energy; - matrix_ptr( XX, j, lag + j, Order ) = ( silk_float )energy; - } - ptr2--; /* Next column of X */ - } -} diff --git a/src/opus-1.0.2/silk/float/encode_frame_FLP.c b/src/opus-1.0.2/silk/float/encode_frame_FLP.c deleted file mode 100644 index 23260bc7..00000000 --- a/src/opus-1.0.2/silk/float/encode_frame_FLP.c +++ /dev/null @@ -1,372 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main_FLP.h" -#include "tuning_parameters.h" - -/* Low Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode with lower bitrate */ -static inline void silk_LBRR_encode_FLP( - silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ - silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ - const silk_float xfw[], /* I Input signal */ - opus_int condCoding /* I The type of conditional coding used so far for this frame */ -); - -void silk_encode_do_VAD_FLP( - silk_encoder_state_FLP *psEnc /* I/O Encoder state FLP */ -) -{ - /****************************/ - /* Voice Activity Detection */ - /****************************/ - silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf + 1 ); - - /**************************************************/ - /* Convert speech activity into VAD and DTX flags */ - /**************************************************/ - if( psEnc->sCmn.speech_activity_Q8 < SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ) ) { - psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY; - psEnc->sCmn.noSpeechCounter++; - if( psEnc->sCmn.noSpeechCounter < NB_SPEECH_FRAMES_BEFORE_DTX ) { - psEnc->sCmn.inDTX = 0; - } else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) { - psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX; - psEnc->sCmn.inDTX = 0; - } - psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 0; - } else { - psEnc->sCmn.noSpeechCounter = 0; - psEnc->sCmn.inDTX = 0; - psEnc->sCmn.indices.signalType = TYPE_UNVOICED; - psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 1; - } -} - -/****************/ -/* Encode frame */ -/****************/ -opus_int silk_encode_frame_FLP( - silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ - opus_int32 *pnBytesOut, /* O Number of payload bytes; */ - ec_enc *psRangeEnc, /* I/O compressor data structure */ - opus_int condCoding, /* I The type of conditional coding to use */ - opus_int maxBits, /* I If > 0: maximum number of output bits */ - opus_int useCBR /* I Flag to force constant-bitrate operation */ -) -{ - silk_encoder_control_FLP sEncCtrl; - opus_int i, iter, maxIter, found_upper, found_lower, ret = 0; - silk_float *x_frame, *res_pitch_frame; - silk_float xfw[ MAX_FRAME_LENGTH ]; - silk_float res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ]; - ec_enc sRangeEnc_copy, sRangeEnc_copy2; - silk_nsq_state sNSQ_copy, sNSQ_copy2; - opus_int32 seed_copy, nBits, nBits_lower, nBits_upper, gainMult_lower, gainMult_upper; - opus_int32 gainsID, gainsID_lower, gainsID_upper; - opus_int16 gainMult_Q8; - opus_int16 ec_prevLagIndex_copy; - opus_int ec_prevSignalType_copy; - opus_int8 LastGainIndex_copy2; - opus_int32 pGains_Q16[ MAX_NB_SUBFR ]; - opus_uint8 ec_buf_copy[ 1275 ]; - - /* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */ - LastGainIndex_copy2 = nBits_lower = nBits_upper = gainMult_lower = gainMult_upper = 0; - - psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3; - - /**************************************************************/ - /* Set up Input Pointers, and insert frame in input buffer */ - /**************************************************************/ - /* pointers aligned with start of frame to encode */ - x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length; /* start of frame to encode */ - res_pitch_frame = res_pitch + psEnc->sCmn.ltp_mem_length; /* start of pitch LPC residual frame */ - - /***************************************/ - /* Ensure smooth bandwidth transitions */ - /***************************************/ - silk_LP_variable_cutoff( &psEnc->sCmn.sLP, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length ); - - /*******************************************/ - /* Copy new frame to front of input buffer */ - /*******************************************/ - silk_short2float_array( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length ); - - /* Add tiny signal to avoid high CPU load from denormalized floating point numbers */ - for( i = 0; i < 8; i++ ) { - x_frame[ LA_SHAPE_MS * psEnc->sCmn.fs_kHz + i * ( psEnc->sCmn.frame_length >> 3 ) ] += ( 1 - ( i & 2 ) ) * 1e-6f; - } - - if( !psEnc->sCmn.prefillFlag ) { - /*****************************************/ - /* Find pitch lags, initial LPC analysis */ - /*****************************************/ - silk_find_pitch_lags_FLP( psEnc, &sEncCtrl, res_pitch, x_frame ); - - /************************/ - /* Noise shape analysis */ - /************************/ - silk_noise_shape_analysis_FLP( psEnc, &sEncCtrl, res_pitch_frame, x_frame ); - - /***************************************************/ - /* Find linear prediction coefficients (LPC + LTP) */ - /***************************************************/ - silk_find_pred_coefs_FLP( psEnc, &sEncCtrl, res_pitch, x_frame, condCoding ); - - /****************************************/ - /* Process gains */ - /****************************************/ - silk_process_gains_FLP( psEnc, &sEncCtrl, condCoding ); - - /*****************************************/ - /* Prefiltering for noise shaper */ - /*****************************************/ - silk_prefilter_FLP( psEnc, &sEncCtrl, xfw, x_frame ); - - /****************************************/ - /* Low Bitrate Redundant Encoding */ - /****************************************/ - silk_LBRR_encode_FLP( psEnc, &sEncCtrl, xfw, condCoding ); - - /* Loop over quantizer and entroy coding to control bitrate */ - maxIter = 6; - gainMult_Q8 = SILK_FIX_CONST( 1, 8 ); - found_lower = 0; - found_upper = 0; - gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr ); - gainsID_lower = -1; - gainsID_upper = -1; - /* Copy part of the input state */ - silk_memcpy( &sRangeEnc_copy, psRangeEnc, sizeof( ec_enc ) ); - silk_memcpy( &sNSQ_copy, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); - seed_copy = psEnc->sCmn.indices.Seed; - ec_prevLagIndex_copy = psEnc->sCmn.ec_prevLagIndex; - ec_prevSignalType_copy = psEnc->sCmn.ec_prevSignalType; - for( iter = 0; ; iter++ ) { - if( gainsID == gainsID_lower ) { - nBits = nBits_lower; - } else if( gainsID == gainsID_upper ) { - nBits = nBits_upper; - } else { - /* Restore part of the input state */ - if( iter > 0 ) { - silk_memcpy( psRangeEnc, &sRangeEnc_copy, sizeof( ec_enc ) ); - silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy, sizeof( silk_nsq_state ) ); - psEnc->sCmn.indices.Seed = seed_copy; - psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy; - psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy; - } - - /*****************************************/ - /* Noise shaping quantization */ - /*****************************************/ - silk_NSQ_wrapper_FLP( psEnc, &sEncCtrl, &psEnc->sCmn.indices, &psEnc->sCmn.sNSQ, psEnc->sCmn.pulses, xfw ); - - /****************************************/ - /* Encode Parameters */ - /****************************************/ - silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding ); - - /****************************************/ - /* Encode Excitation Signal */ - /****************************************/ - silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType, - psEnc->sCmn.pulses, psEnc->sCmn.frame_length ); - - nBits = ec_tell( psRangeEnc ); - - if( useCBR == 0 && iter == 0 && nBits <= maxBits ) { - break; - } - } - - if( iter == maxIter ) { - if( found_lower && ( gainsID == gainsID_lower || nBits > maxBits ) ) { - /* Restore output state from earlier iteration that did meet the bitrate budget */ - silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) ); - silk_assert( sRangeEnc_copy2.offs <= 1275 ); - silk_memcpy( psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs ); - silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy2, sizeof( silk_nsq_state ) ); - psEnc->sShape.LastGainIndex = LastGainIndex_copy2; - } - break; - } - - if( nBits > maxBits ) { - if( found_lower == 0 && iter >= 2 ) { - /* Adjust the quantizer's rate/distortion tradeoff and discard previous "upper" results */ - sEncCtrl.Lambda *= 1.5f; - found_upper = 0; - gainsID_upper = -1; - } else { - found_upper = 1; - nBits_upper = nBits; - gainMult_upper = gainMult_Q8; - gainsID_upper = gainsID; - } - } else if( nBits < maxBits - 5 ) { - found_lower = 1; - nBits_lower = nBits; - gainMult_lower = gainMult_Q8; - if( gainsID != gainsID_lower ) { - gainsID_lower = gainsID; - /* Copy part of the output state */ - silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) ); - silk_assert( psRangeEnc->offs <= 1275 ); - silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs ); - silk_memcpy( &sNSQ_copy2, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); - LastGainIndex_copy2 = psEnc->sShape.LastGainIndex; - } - } else { - /* Within 5 bits of budget: close enough */ - break; - } - - if( ( found_lower & found_upper ) == 0 ) { - /* Adjust gain according to high-rate rate/distortion curve */ - opus_int32 gain_factor_Q16; - gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) ); - gain_factor_Q16 = silk_min_32( gain_factor_Q16, SILK_FIX_CONST( 2, 16 ) ); - if( nBits > maxBits ) { - gain_factor_Q16 = silk_max_32( gain_factor_Q16, SILK_FIX_CONST( 1.3, 16 ) ); - } - gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 ); - } else { - /* Adjust gain by interpolating */ - gainMult_Q8 = gainMult_lower + ( ( gainMult_upper - gainMult_lower ) * ( maxBits - nBits_lower ) ) / ( nBits_upper - nBits_lower ); - /* New gain multplier must be between 25% and 75% of old range (note that gainMult_upper < gainMult_lower) */ - if( gainMult_Q8 > silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ) ) { - gainMult_Q8 = silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ); - } else - if( gainMult_Q8 < silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ) ) { - gainMult_Q8 = silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ); - } - } - - for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { - pGains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], gainMult_Q8 ), 8 ); - } - - /* Quantize gains */ - psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev; - silk_gains_quant( psEnc->sCmn.indices.GainsIndices, pGains_Q16, - &psEnc->sShape.LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); - - /* Unique identifier of gains vector */ - gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr ); - - /* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */ - for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { - sEncCtrl.Gains[ i ] = pGains_Q16[ i ] / 65536.0f; - } - } - } - - /* Update input buffer */ - silk_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ], - ( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( silk_float ) ); - - /* Parameters needed for next frame */ - psEnc->sCmn.prevLag = sEncCtrl.pitchL[ psEnc->sCmn.nb_subfr - 1 ]; - psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType; - - /* Exit without entropy coding */ - if( psEnc->sCmn.prefillFlag ) { - /* No payload */ - *pnBytesOut = 0; - return ret; - } - - /****************************************/ - /* Finalize payload */ - /****************************************/ - psEnc->sCmn.first_frame_after_reset = 0; - /* Payload size */ - *pnBytesOut = silk_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 ); - - return ret; -} - -/* Low-Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode excitation at lower bitrate */ -static inline void silk_LBRR_encode_FLP( - silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ - silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ - const silk_float xfw[], /* I Input signal */ - opus_int condCoding /* I The type of conditional coding used so far for this frame */ -) -{ - opus_int k; - opus_int32 Gains_Q16[ MAX_NB_SUBFR ]; - silk_float TempGains[ MAX_NB_SUBFR ]; - SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesEncoded ]; - silk_nsq_state sNSQ_LBRR; - - /*******************************************/ - /* Control use of inband LBRR */ - /*******************************************/ - if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SILK_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) { - psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded ] = 1; - - /* Copy noise shaping quantizer state and quantization indices from regular encoding */ - silk_memcpy( &sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); - silk_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) ); - - /* Save original gains */ - silk_memcpy( TempGains, psEncCtrl->Gains, psEnc->sCmn.nb_subfr * sizeof( silk_float ) ); - - if( psEnc->sCmn.nFramesEncoded == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded - 1 ] == 0 ) { - /* First frame in packet or previous frame not LBRR coded */ - psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex; - - /* Increase Gains to get target LBRR rate */ - psIndices_LBRR->GainsIndices[ 0 ] += psEnc->sCmn.LBRR_GainIncreases; - psIndices_LBRR->GainsIndices[ 0 ] = silk_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 ); - } - - /* Decode to get gains in sync with decoder */ - silk_gains_dequant( Gains_Q16, psIndices_LBRR->GainsIndices, - &psEnc->sCmn.LBRRprevLastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); - - /* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */ - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - psEncCtrl->Gains[ k ] = Gains_Q16[ k ] * ( 1.0f / 65536.0f ); - } - - /*****************************************/ - /* Noise shaping quantization */ - /*****************************************/ - silk_NSQ_wrapper_FLP( psEnc, psEncCtrl, psIndices_LBRR, &sNSQ_LBRR, - psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], xfw ); - - /* Restore original gains */ - silk_memcpy( psEncCtrl->Gains, TempGains, psEnc->sCmn.nb_subfr * sizeof( silk_float ) ); - } -} diff --git a/src/opus-1.0.2/silk/float/energy_FLP.c b/src/opus-1.0.2/silk/float/energy_FLP.c deleted file mode 100644 index e3eedf97..00000000 --- a/src/opus-1.0.2/silk/float/energy_FLP.c +++ /dev/null @@ -1,60 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "SigProc_FLP.h" - -/* sum of squares of a silk_float array, with result as double */ -double silk_energy_FLP( - const silk_float *data, - opus_int dataSize -) -{ - opus_int i, dataSize4; - double result; - - /* 4x unrolled loop */ - result = 0.0; - dataSize4 = dataSize & 0xFFFC; - for( i = 0; i < dataSize4; i += 4 ) { - result += data[ i + 0 ] * (double)data[ i + 0 ] + - data[ i + 1 ] * (double)data[ i + 1 ] + - data[ i + 2 ] * (double)data[ i + 2 ] + - data[ i + 3 ] * (double)data[ i + 3 ]; - } - - /* add any remaining products */ - for( ; i < dataSize; i++ ) { - result += data[ i ] * (double)data[ i ]; - } - - silk_assert( result >= 0.0 ); - return result; -} diff --git a/src/opus-1.0.2/silk/float/find_LPC_FLP.c b/src/opus-1.0.2/silk/float/find_LPC_FLP.c deleted file mode 100644 index 66fa7dd4..00000000 --- a/src/opus-1.0.2/silk/float/find_LPC_FLP.c +++ /dev/null @@ -1,104 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "define.h" -#include "main_FLP.h" -#include "tuning_parameters.h" - -/* LPC analysis */ -void silk_find_LPC_FLP( - silk_encoder_state *psEncC, /* I/O Encoder state */ - opus_int16 NLSF_Q15[], /* O NLSFs */ - const silk_float x[], /* I Input signal */ - const silk_float minInvGain /* I Inverse of max prediction gain */ -) -{ - opus_int k, subfr_length; - silk_float a[ MAX_LPC_ORDER ]; - - /* Used only for NLSF interpolation */ - silk_float res_nrg, res_nrg_2nd, res_nrg_interp; - opus_int16 NLSF0_Q15[ MAX_LPC_ORDER ]; - silk_float a_tmp[ MAX_LPC_ORDER ]; - silk_float LPC_res[ MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ]; - - subfr_length = psEncC->subfr_length + psEncC->predictLPCOrder; - - /* Default: No interpolation */ - psEncC->indices.NLSFInterpCoef_Q2 = 4; - - /* Burg AR analysis for the full frame */ - res_nrg = silk_burg_modified_FLP( a, x, minInvGain, subfr_length, psEncC->nb_subfr, psEncC->predictLPCOrder ); - - if( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) { - /* Optimal solution for last 10 ms; subtract residual energy here, as that's easier than */ - /* adding it to the residual energy of the first 10 ms in each iteration of the search below */ - res_nrg -= silk_burg_modified_FLP( a_tmp, x + ( MAX_NB_SUBFR / 2 ) * subfr_length, minInvGain, subfr_length, MAX_NB_SUBFR / 2, psEncC->predictLPCOrder ); - - /* Convert to NLSFs */ - silk_A2NLSF_FLP( NLSF_Q15, a_tmp, psEncC->predictLPCOrder ); - - /* Search over interpolation indices to find the one with lowest residual energy */ - res_nrg_2nd = silk_float_MAX; - for( k = 3; k >= 0; k-- ) { - /* Interpolate NLSFs for first half */ - silk_interpolate( NLSF0_Q15, psEncC->prev_NLSFq_Q15, NLSF_Q15, k, psEncC->predictLPCOrder ); - - /* Convert to LPC for residual energy evaluation */ - silk_NLSF2A_FLP( a_tmp, NLSF0_Q15, psEncC->predictLPCOrder ); - - /* Calculate residual energy with LSF interpolation */ - silk_LPC_analysis_filter_FLP( LPC_res, a_tmp, x, 2 * subfr_length, psEncC->predictLPCOrder ); - res_nrg_interp = (silk_float)( - silk_energy_FLP( LPC_res + psEncC->predictLPCOrder, subfr_length - psEncC->predictLPCOrder ) + - silk_energy_FLP( LPC_res + psEncC->predictLPCOrder + subfr_length, subfr_length - psEncC->predictLPCOrder ) ); - - /* Determine whether current interpolated NLSFs are best so far */ - if( res_nrg_interp < res_nrg ) { - /* Interpolation has lower residual energy */ - res_nrg = res_nrg_interp; - psEncC->indices.NLSFInterpCoef_Q2 = (opus_int8)k; - } else if( res_nrg_interp > res_nrg_2nd ) { - /* No reason to continue iterating - residual energies will continue to climb */ - break; - } - res_nrg_2nd = res_nrg_interp; - } - } - - if( psEncC->indices.NLSFInterpCoef_Q2 == 4 ) { - /* NLSF interpolation is currently inactive, calculate NLSFs from full frame AR coefficients */ - silk_A2NLSF_FLP( NLSF_Q15, a, psEncC->predictLPCOrder ); - } - - silk_assert( psEncC->indices.NLSFInterpCoef_Q2 == 4 || - ( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) ); -} diff --git a/src/opus-1.0.2/silk/float/find_LTP_FLP.c b/src/opus-1.0.2/silk/float/find_LTP_FLP.c deleted file mode 100644 index 0a3c71bb..00000000 --- a/src/opus-1.0.2/silk/float/find_LTP_FLP.c +++ /dev/null @@ -1,132 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main_FLP.h" -#include "tuning_parameters.h" - -void silk_find_LTP_FLP( - silk_float b[ MAX_NB_SUBFR * LTP_ORDER ], /* O LTP coefs */ - silk_float WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */ - silk_float *LTPredCodGain, /* O LTP coding gain */ - const silk_float r_lpc[], /* I LPC residual */ - const opus_int lag[ MAX_NB_SUBFR ], /* I LTP lags */ - const silk_float Wght[ MAX_NB_SUBFR ], /* I Weights */ - const opus_int subfr_length, /* I Subframe length */ - const opus_int nb_subfr, /* I number of subframes */ - const opus_int mem_offset /* I Number of samples in LTP memory */ -) -{ - opus_int i, k; - silk_float *b_ptr, temp, *WLTP_ptr; - silk_float LPC_res_nrg, LPC_LTP_res_nrg; - silk_float d[ MAX_NB_SUBFR ], m, g, delta_b[ LTP_ORDER ]; - silk_float w[ MAX_NB_SUBFR ], nrg[ MAX_NB_SUBFR ], regu; - silk_float Rr[ LTP_ORDER ], rr[ MAX_NB_SUBFR ]; - const silk_float *r_ptr, *lag_ptr; - - b_ptr = b; - WLTP_ptr = WLTP; - r_ptr = &r_lpc[ mem_offset ]; - for( k = 0; k < nb_subfr; k++ ) { - lag_ptr = r_ptr - ( lag[ k ] + LTP_ORDER / 2 ); - - silk_corrMatrix_FLP( lag_ptr, subfr_length, LTP_ORDER, WLTP_ptr ); - silk_corrVector_FLP( lag_ptr, r_ptr, subfr_length, LTP_ORDER, Rr ); - - rr[ k ] = ( silk_float )silk_energy_FLP( r_ptr, subfr_length ); - regu = 1.0f + rr[ k ] + - matrix_ptr( WLTP_ptr, 0, 0, LTP_ORDER ) + - matrix_ptr( WLTP_ptr, LTP_ORDER-1, LTP_ORDER-1, LTP_ORDER ); - regu *= LTP_DAMPING / 3; - silk_regularize_correlations_FLP( WLTP_ptr, &rr[ k ], regu, LTP_ORDER ); - silk_solve_LDL_FLP( WLTP_ptr, LTP_ORDER, Rr, b_ptr ); - - /* Calculate residual energy */ - nrg[ k ] = silk_residual_energy_covar_FLP( b_ptr, WLTP_ptr, Rr, rr[ k ], LTP_ORDER ); - - temp = Wght[ k ] / ( nrg[ k ] * Wght[ k ] + 0.01f * subfr_length ); - silk_scale_vector_FLP( WLTP_ptr, temp, LTP_ORDER * LTP_ORDER ); - w[ k ] = matrix_ptr( WLTP_ptr, LTP_ORDER / 2, LTP_ORDER / 2, LTP_ORDER ); - - r_ptr += subfr_length; - b_ptr += LTP_ORDER; - WLTP_ptr += LTP_ORDER * LTP_ORDER; - } - - /* Compute LTP coding gain */ - if( LTPredCodGain != NULL ) { - LPC_LTP_res_nrg = 1e-6f; - LPC_res_nrg = 0.0f; - for( k = 0; k < nb_subfr; k++ ) { - LPC_res_nrg += rr[ k ] * Wght[ k ]; - LPC_LTP_res_nrg += nrg[ k ] * Wght[ k ]; - } - - silk_assert( LPC_LTP_res_nrg > 0 ); - *LTPredCodGain = 3.0f * silk_log2( LPC_res_nrg / LPC_LTP_res_nrg ); - } - - /* Smoothing */ - /* d = sum( B, 1 ); */ - b_ptr = b; - for( k = 0; k < nb_subfr; k++ ) { - d[ k ] = 0; - for( i = 0; i < LTP_ORDER; i++ ) { - d[ k ] += b_ptr[ i ]; - } - b_ptr += LTP_ORDER; - } - /* m = ( w * d' ) / ( sum( w ) + 1e-3 ); */ - temp = 1e-3f; - for( k = 0; k < nb_subfr; k++ ) { - temp += w[ k ]; - } - m = 0; - for( k = 0; k < nb_subfr; k++ ) { - m += d[ k ] * w[ k ]; - } - m = m / temp; - - b_ptr = b; - for( k = 0; k < nb_subfr; k++ ) { - g = LTP_SMOOTHING / ( LTP_SMOOTHING + w[ k ] ) * ( m - d[ k ] ); - temp = 0; - for( i = 0; i < LTP_ORDER; i++ ) { - delta_b[ i ] = silk_max_float( b_ptr[ i ], 0.1f ); - temp += delta_b[ i ]; - } - temp = g / temp; - for( i = 0; i < LTP_ORDER; i++ ) { - b_ptr[ i ] = b_ptr[ i ] + delta_b[ i ] * temp; - } - b_ptr += LTP_ORDER; - } -} diff --git a/src/opus-1.0.2/silk/float/find_pitch_lags_FLP.c b/src/opus-1.0.2/silk/float/find_pitch_lags_FLP.c deleted file mode 100644 index 00862a6d..00000000 --- a/src/opus-1.0.2/silk/float/find_pitch_lags_FLP.c +++ /dev/null @@ -1,131 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "main_FLP.h" -#include "tuning_parameters.h" - -void silk_find_pitch_lags_FLP( - silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ - silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ - silk_float res[], /* O Residual */ - const silk_float x[] /* I Speech signal */ -) -{ - opus_int buf_len; - silk_float thrhld, res_nrg; - const silk_float *x_buf_ptr, *x_buf; - silk_float auto_corr[ MAX_FIND_PITCH_LPC_ORDER + 1 ]; - silk_float A[ MAX_FIND_PITCH_LPC_ORDER ]; - silk_float refl_coef[ MAX_FIND_PITCH_LPC_ORDER ]; - silk_float Wsig[ FIND_PITCH_LPC_WIN_MAX ]; - silk_float *Wsig_ptr; - - /******************************************/ - /* Set up buffer lengths etc based on Fs */ - /******************************************/ - buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length; - - /* Safety check */ - silk_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length ); - - x_buf = x - psEnc->sCmn.ltp_mem_length; - - /******************************************/ - /* Estimate LPC AR coeficients */ - /******************************************/ - - /* Calculate windowed signal */ - - /* First LA_LTP samples */ - x_buf_ptr = x_buf + buf_len - psEnc->sCmn.pitch_LPC_win_length; - Wsig_ptr = Wsig; - silk_apply_sine_window_FLP( Wsig_ptr, x_buf_ptr, 1, psEnc->sCmn.la_pitch ); - - /* Middle non-windowed samples */ - Wsig_ptr += psEnc->sCmn.la_pitch; - x_buf_ptr += psEnc->sCmn.la_pitch; - silk_memcpy( Wsig_ptr, x_buf_ptr, ( psEnc->sCmn.pitch_LPC_win_length - ( psEnc->sCmn.la_pitch << 1 ) ) * sizeof( silk_float ) ); - - /* Last LA_LTP samples */ - Wsig_ptr += psEnc->sCmn.pitch_LPC_win_length - ( psEnc->sCmn.la_pitch << 1 ); - x_buf_ptr += psEnc->sCmn.pitch_LPC_win_length - ( psEnc->sCmn.la_pitch << 1 ); - silk_apply_sine_window_FLP( Wsig_ptr, x_buf_ptr, 2, psEnc->sCmn.la_pitch ); - - /* Calculate autocorrelation sequence */ - silk_autocorrelation_FLP( auto_corr, Wsig, psEnc->sCmn.pitch_LPC_win_length, psEnc->sCmn.pitchEstimationLPCOrder + 1 ); - - /* Add white noise, as a fraction of the energy */ - auto_corr[ 0 ] += auto_corr[ 0 ] * FIND_PITCH_WHITE_NOISE_FRACTION + 1; - - /* Calculate the reflection coefficients using Schur */ - res_nrg = silk_schur_FLP( refl_coef, auto_corr, psEnc->sCmn.pitchEstimationLPCOrder ); - - /* Prediction gain */ - psEncCtrl->predGain = auto_corr[ 0 ] / silk_max_float( res_nrg, 1.0f ); - - /* Convert reflection coefficients to prediction coefficients */ - silk_k2a_FLP( A, refl_coef, psEnc->sCmn.pitchEstimationLPCOrder ); - - /* Bandwidth expansion */ - silk_bwexpander_FLP( A, psEnc->sCmn.pitchEstimationLPCOrder, FIND_PITCH_BANDWIDTH_EXPANSION ); - - /*****************************************/ - /* LPC analysis filtering */ - /*****************************************/ - silk_LPC_analysis_filter_FLP( res, A, x_buf, buf_len, psEnc->sCmn.pitchEstimationLPCOrder ); - - if( psEnc->sCmn.indices.signalType != TYPE_NO_VOICE_ACTIVITY && psEnc->sCmn.first_frame_after_reset == 0 ) { - /* Threshold for pitch estimator */ - thrhld = 0.6f; - thrhld -= 0.004f * psEnc->sCmn.pitchEstimationLPCOrder; - thrhld -= 0.1f * psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f ); - thrhld -= 0.15f * (psEnc->sCmn.prevSignalType >> 1); - thrhld -= 0.1f * psEnc->sCmn.input_tilt_Q15 * ( 1.0f / 32768.0f ); - - /*****************************************/ - /* Call Pitch estimator */ - /*****************************************/ - if( silk_pitch_analysis_core_FLP( res, psEncCtrl->pitchL, &psEnc->sCmn.indices.lagIndex, - &psEnc->sCmn.indices.contourIndex, &psEnc->LTPCorr, psEnc->sCmn.prevLag, psEnc->sCmn.pitchEstimationThreshold_Q16 / 65536.0f, - thrhld, psEnc->sCmn.fs_kHz, psEnc->sCmn.pitchEstimationComplexity, psEnc->sCmn.nb_subfr ) == 0 ) - { - psEnc->sCmn.indices.signalType = TYPE_VOICED; - } else { - psEnc->sCmn.indices.signalType = TYPE_UNVOICED; - } - } else { - silk_memset( psEncCtrl->pitchL, 0, sizeof( psEncCtrl->pitchL ) ); - psEnc->sCmn.indices.lagIndex = 0; - psEnc->sCmn.indices.contourIndex = 0; - psEnc->LTPCorr = 0; - } -} diff --git a/src/opus-1.0.2/silk/float/find_pred_coefs_FLP.c b/src/opus-1.0.2/silk/float/find_pred_coefs_FLP.c deleted file mode 100644 index 2156893a..00000000 --- a/src/opus-1.0.2/silk/float/find_pred_coefs_FLP.c +++ /dev/null @@ -1,116 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main_FLP.h" - -/* Find LPC and LTP coefficients */ -void silk_find_pred_coefs_FLP( - silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ - silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ - const silk_float res_pitch[], /* I Residual from pitch analysis */ - const silk_float x[], /* I Speech signal */ - opus_int condCoding /* I The type of conditional coding to use */ -) -{ - opus_int i; - silk_float WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ]; - silk_float invGains[ MAX_NB_SUBFR ], Wght[ MAX_NB_SUBFR ]; - opus_int16 NLSF_Q15[ MAX_LPC_ORDER ]; - const silk_float *x_ptr; - silk_float *x_pre_ptr, LPC_in_pre[ MAX_NB_SUBFR * MAX_LPC_ORDER + MAX_FRAME_LENGTH ]; - silk_float minInvGain; - - /* Weighting for weighted least squares */ - for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { - silk_assert( psEncCtrl->Gains[ i ] > 0.0f ); - invGains[ i ] = 1.0f / psEncCtrl->Gains[ i ]; - Wght[ i ] = invGains[ i ] * invGains[ i ]; - } - - if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - /**********/ - /* VOICED */ - /**********/ - silk_assert( psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->pitchL[ 0 ] + LTP_ORDER / 2 ); - - /* LTP analysis */ - silk_find_LTP_FLP( psEncCtrl->LTPCoef, WLTP, &psEncCtrl->LTPredCodGain, res_pitch, - psEncCtrl->pitchL, Wght, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.ltp_mem_length ); - - /* Quantize LTP gain parameters */ - silk_quant_LTP_gains_FLP( psEncCtrl->LTPCoef, psEnc->sCmn.indices.LTPIndex, &psEnc->sCmn.indices.PERIndex, - WLTP, psEnc->sCmn.mu_LTP_Q9, psEnc->sCmn.LTPQuantLowComplexity, psEnc->sCmn.nb_subfr ); - - /* Control LTP scaling */ - silk_LTP_scale_ctrl_FLP( psEnc, psEncCtrl, condCoding ); - - /* Create LTP residual */ - silk_LTP_analysis_filter_FLP( LPC_in_pre, x - psEnc->sCmn.predictLPCOrder, psEncCtrl->LTPCoef, - psEncCtrl->pitchL, invGains, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder ); - } else { - /************/ - /* UNVOICED */ - /************/ - /* Create signal with prepended subframes, scaled by inverse gains */ - x_ptr = x - psEnc->sCmn.predictLPCOrder; - x_pre_ptr = LPC_in_pre; - for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { - silk_scale_copy_vector_FLP( x_pre_ptr, x_ptr, invGains[ i ], - psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder ); - x_pre_ptr += psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder; - x_ptr += psEnc->sCmn.subfr_length; - } - silk_memset( psEncCtrl->LTPCoef, 0, psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( silk_float ) ); - psEncCtrl->LTPredCodGain = 0.0f; - } - - /* Limit on total predictive coding gain */ - if( psEnc->sCmn.first_frame_after_reset ) { - minInvGain = 1.0f / MAX_PREDICTION_POWER_GAIN_AFTER_RESET; - } else { - minInvGain = (silk_float)pow( 2, psEncCtrl->LTPredCodGain / 3 ) / MAX_PREDICTION_POWER_GAIN; - minInvGain /= 0.25f + 0.75f * psEncCtrl->coding_quality; - } - - /* LPC_in_pre contains the LTP-filtered input for voiced, and the unfiltered input for unvoiced */ - silk_find_LPC_FLP( &psEnc->sCmn, NLSF_Q15, LPC_in_pre, minInvGain ); - - /* Quantize LSFs */ - silk_process_NLSFs_FLP( &psEnc->sCmn, psEncCtrl->PredCoef, NLSF_Q15, psEnc->sCmn.prev_NLSFq_Q15 ); - - /* Calculate residual energy using quantized LPC coefficients */ - silk_residual_energy_FLP( psEncCtrl->ResNrg, LPC_in_pre, psEncCtrl->PredCoef, psEncCtrl->Gains, - psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder ); - - /* Copy to prediction struct for use in next frame for interpolation */ - silk_memcpy( psEnc->sCmn.prev_NLSFq_Q15, NLSF_Q15, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) ); -} - diff --git a/src/opus-1.0.2/silk/float/inner_product_FLP.c b/src/opus-1.0.2/silk/float/inner_product_FLP.c deleted file mode 100644 index 60823d6e..00000000 --- a/src/opus-1.0.2/silk/float/inner_product_FLP.c +++ /dev/null @@ -1,60 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "SigProc_FLP.h" - -/* inner product of two silk_float arrays, with result as double */ -double silk_inner_product_FLP( - const silk_float *data1, - const silk_float *data2, - opus_int dataSize -) -{ - opus_int i, dataSize4; - double result; - - /* 4x unrolled loop */ - result = 0.0; - dataSize4 = dataSize & 0xFFFC; - for( i = 0; i < dataSize4; i += 4 ) { - result += data1[ i + 0 ] * (double)data2[ i + 0 ] + - data1[ i + 1 ] * (double)data2[ i + 1 ] + - data1[ i + 2 ] * (double)data2[ i + 2 ] + - data1[ i + 3 ] * (double)data2[ i + 3 ]; - } - - /* add any remaining products */ - for( ; i < dataSize; i++ ) { - result += data1[ i ] * (double)data2[ i ]; - } - - return result; -} diff --git a/src/opus-1.0.2/silk/float/k2a_FLP.c b/src/opus-1.0.2/silk/float/k2a_FLP.c deleted file mode 100644 index 6f05d4b9..00000000 --- a/src/opus-1.0.2/silk/float/k2a_FLP.c +++ /dev/null @@ -1,53 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "SigProc_FLP.h" - -/* step up function, converts reflection coefficients to prediction coefficients */ -void silk_k2a_FLP( - silk_float *A, /* O prediction coefficients [order] */ - const silk_float *rc, /* I reflection coefficients [order] */ - opus_int32 order /* I prediction order */ -) -{ - opus_int k, n; - silk_float Atmp[ SILK_MAX_ORDER_LPC ]; - - for( k = 0; k < order; k++ ) { - for( n = 0; n < k; n++ ) { - Atmp[ n ] = A[ n ]; - } - for( n = 0; n < k; n++ ) { - A[ n ] += Atmp[ k - n - 1 ] * rc[ k ]; - } - A[ k ] = -rc[ k ]; - } -} diff --git a/src/opus-1.0.2/silk/float/levinsondurbin_FLP.c b/src/opus-1.0.2/silk/float/levinsondurbin_FLP.c deleted file mode 100644 index b4cd34e2..00000000 --- a/src/opus-1.0.2/silk/float/levinsondurbin_FLP.c +++ /dev/null @@ -1,81 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "SigProc_FLP.h" - -/* Solve the normal equations using the Levinson-Durbin recursion */ -silk_float silk_levinsondurbin_FLP( /* O prediction error energy */ - silk_float A[], /* O prediction coefficients [order] */ - const silk_float corr[], /* I input auto-correlations [order + 1] */ - const opus_int order /* I prediction order */ -) -{ - opus_int i, mHalf, m; - silk_float min_nrg, nrg, t, km, Atmp1, Atmp2; - - min_nrg = 1e-12f * corr[ 0 ] + 1e-9f; - nrg = corr[ 0 ]; - nrg = silk_max_float(min_nrg, nrg); - A[ 0 ] = corr[ 1 ] / nrg; - nrg -= A[ 0 ] * corr[ 1 ]; - nrg = silk_max_float(min_nrg, nrg); - - for( m = 1; m < order; m++ ) - { - t = corr[ m + 1 ]; - for( i = 0; i < m; i++ ) { - t -= A[ i ] * corr[ m - i ]; - } - - /* reflection coefficient */ - km = t / nrg; - - /* residual energy */ - nrg -= km * t; - nrg = silk_max_float(min_nrg, nrg); - - mHalf = m >> 1; - for( i = 0; i < mHalf; i++ ) { - Atmp1 = A[ i ]; - Atmp2 = A[ m - i - 1 ]; - A[ m - i - 1 ] -= km * Atmp1; - A[ i ] -= km * Atmp2; - } - if( m & 1 ) { - A[ mHalf ] -= km * A[ mHalf ]; - } - A[ m ] = km; - } - - /* return the residual energy */ - return nrg; -} - diff --git a/src/opus-1.0.2/silk/float/main_FLP.h b/src/opus-1.0.2/silk/float/main_FLP.h deleted file mode 100644 index 93455d4d..00000000 --- a/src/opus-1.0.2/silk/float/main_FLP.h +++ /dev/null @@ -1,309 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifndef SILK_MAIN_FLP_H -#define SILK_MAIN_FLP_H - -#include "SigProc_FLP.h" -#include "SigProc_FIX.h" -#include "structs_FLP.h" -#include "main.h" -#include "define.h" -#include "debug.h" -#include "entenc.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -#define silk_encoder_state_Fxx silk_encoder_state_FLP -#define silk_encode_do_VAD_Fxx silk_encode_do_VAD_FLP -#define silk_encode_frame_Fxx silk_encode_frame_FLP - -/*********************/ -/* Encoder Functions */ -/*********************/ - -/* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */ -void silk_HP_variable_cutoff( - silk_encoder_state_Fxx state_Fxx[] /* I/O Encoder states */ -); - -/* Encoder main function */ -void silk_encode_do_VAD_FLP( - silk_encoder_state_FLP *psEnc /* I/O Encoder state FLP */ -); - -/* Encoder main function */ -opus_int silk_encode_frame_FLP( - silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ - opus_int32 *pnBytesOut, /* O Number of payload bytes; */ - ec_enc *psRangeEnc, /* I/O compressor data structure */ - opus_int condCoding, /* I The type of conditional coding to use */ - opus_int maxBits, /* I If > 0: maximum number of output bits */ - opus_int useCBR /* I Flag to force constant-bitrate operation */ -); - -/* Initializes the Silk encoder state */ -opus_int silk_init_encoder( - silk_encoder_state_FLP *psEnc /* I/O Encoder state FLP */ -); - -/* Control the Silk encoder */ -opus_int silk_control_encoder( - silk_encoder_state_FLP *psEnc, /* I/O Pointer to Silk encoder state FLP */ - silk_EncControlStruct *encControl, /* I Control structure */ - const opus_int32 TargetRate_bps, /* I Target max bitrate (bps) */ - const opus_int allow_bw_switch, /* I Flag to allow switching audio bandwidth */ - const opus_int channelNb, /* I Channel number */ - const opus_int force_fs_kHz -); - -/****************/ -/* Prefiltering */ -/****************/ -void silk_prefilter_FLP( - silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ - const silk_encoder_control_FLP *psEncCtrl, /* I Encoder control FLP */ - silk_float xw[], /* O Weighted signal */ - const silk_float x[] /* I Speech signal */ -); - -/**************************/ -/* Noise shaping analysis */ -/**************************/ -/* Compute noise shaping coefficients and initial gain values */ -void silk_noise_shape_analysis_FLP( - silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ - silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ - const silk_float *pitch_res, /* I LPC residual from pitch analysis */ - const silk_float *x /* I Input signal [frame_length + la_shape] */ -); - -/* Autocorrelations for a warped frequency axis */ -void silk_warped_autocorrelation_FLP( - silk_float *corr, /* O Result [order + 1] */ - const silk_float *input, /* I Input data to correlate */ - const silk_float warping, /* I Warping coefficient */ - const opus_int length, /* I Length of input */ - const opus_int order /* I Correlation order (even) */ -); - -/* Calculation of LTP state scaling */ -void silk_LTP_scale_ctrl_FLP( - silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ - silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ - opus_int condCoding /* I The type of conditional coding to use */ -); - -/**********************************************/ -/* Prediction Analysis */ -/**********************************************/ -/* Find pitch lags */ -void silk_find_pitch_lags_FLP( - silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ - silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ - silk_float res[], /* O Residual */ - const silk_float x[] /* I Speech signal */ -); - -/* Find LPC and LTP coefficients */ -void silk_find_pred_coefs_FLP( - silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ - silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ - const silk_float res_pitch[], /* I Residual from pitch analysis */ - const silk_float x[], /* I Speech signal */ - opus_int condCoding /* I The type of conditional coding to use */ -); - -/* LPC analysis */ -void silk_find_LPC_FLP( - silk_encoder_state *psEncC, /* I/O Encoder state */ - opus_int16 NLSF_Q15[], /* O NLSFs */ - const silk_float x[], /* I Input signal */ - const silk_float minInvGain /* I Prediction gain from LTP (dB) */ -); - -/* LTP analysis */ -void silk_find_LTP_FLP( - silk_float b[ MAX_NB_SUBFR * LTP_ORDER ], /* O LTP coefs */ - silk_float WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */ - silk_float *LTPredCodGain, /* O LTP coding gain */ - const silk_float r_lpc[], /* I LPC residual */ - const opus_int lag[ MAX_NB_SUBFR ], /* I LTP lags */ - const silk_float Wght[ MAX_NB_SUBFR ], /* I Weights */ - const opus_int subfr_length, /* I Subframe length */ - const opus_int nb_subfr, /* I number of subframes */ - const opus_int mem_offset /* I Number of samples in LTP memory */ -); - -void silk_LTP_analysis_filter_FLP( - silk_float *LTP_res, /* O LTP res MAX_NB_SUBFR*(pre_lgth+subfr_lngth) */ - const silk_float *x, /* I Input signal, with preceding samples */ - const silk_float B[ LTP_ORDER * MAX_NB_SUBFR ], /* I LTP coefficients for each subframe */ - const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ - const silk_float invGains[ MAX_NB_SUBFR ], /* I Inverse quantization gains */ - const opus_int subfr_length, /* I Length of each subframe */ - const opus_int nb_subfr, /* I number of subframes */ - const opus_int pre_length /* I Preceding samples for each subframe */ -); - -/* Calculates residual energies of input subframes where all subframes have LPC_order */ -/* of preceding samples */ -void silk_residual_energy_FLP( - silk_float nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */ - const silk_float x[], /* I Input signal */ - silk_float a[ 2 ][ MAX_LPC_ORDER ], /* I AR coefs for each frame half */ - const silk_float gains[], /* I Quantization gains */ - const opus_int subfr_length, /* I Subframe length */ - const opus_int nb_subfr, /* I number of subframes */ - const opus_int LPC_order /* I LPC order */ -); - -/* 16th order LPC analysis filter */ -void silk_LPC_analysis_filter_FLP( - silk_float r_LPC[], /* O LPC residual signal */ - const silk_float PredCoef[], /* I LPC coefficients */ - const silk_float s[], /* I Input signal */ - const opus_int length, /* I Length of input signal */ - const opus_int Order /* I LPC order */ -); - -/* LTP tap quantizer */ -void silk_quant_LTP_gains_FLP( - silk_float B[ MAX_NB_SUBFR * LTP_ORDER ], /* I/O (Un-)quantized LTP gains */ - opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook index */ - opus_int8 *periodicity_index, /* O Periodicity index */ - const silk_float W[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* I Error weights */ - const opus_int mu_Q10, /* I Mu value (R/D tradeoff) */ - const opus_int lowComplexity, /* I Flag for low complexity */ - const opus_int nb_subfr /* I number of subframes */ -); - -/* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */ -silk_float silk_residual_energy_covar_FLP( /* O Weighted residual energy */ - const silk_float *c, /* I Filter coefficients */ - silk_float *wXX, /* I/O Weighted correlation matrix, reg. out */ - const silk_float *wXx, /* I Weighted correlation vector */ - const silk_float wxx, /* I Weighted correlation value */ - const opus_int D /* I Dimension */ -); - -/* Processing of gains */ -void silk_process_gains_FLP( - silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ - silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ - opus_int condCoding /* I The type of conditional coding to use */ -); - -/******************/ -/* Linear Algebra */ -/******************/ -/* Calculates correlation matrix X'*X */ -void silk_corrMatrix_FLP( - const silk_float *x, /* I x vector [ L+order-1 ] used to create X */ - const opus_int L, /* I Length of vectors */ - const opus_int Order, /* I Max lag for correlation */ - silk_float *XX /* O X'*X correlation matrix [order x order] */ -); - -/* Calculates correlation vector X'*t */ -void silk_corrVector_FLP( - const silk_float *x, /* I x vector [L+order-1] used to create X */ - const silk_float *t, /* I Target vector [L] */ - const opus_int L, /* I Length of vecors */ - const opus_int Order, /* I Max lag for correlation */ - silk_float *Xt /* O X'*t correlation vector [order] */ -); - -/* Add noise to matrix diagonal */ -void silk_regularize_correlations_FLP( - silk_float *XX, /* I/O Correlation matrices */ - silk_float *xx, /* I/O Correlation values */ - const silk_float noise, /* I Noise energy to add */ - const opus_int D /* I Dimension of XX */ -); - -/* Function to solve linear equation Ax = b, where A is an MxM symmetric matrix */ -void silk_solve_LDL_FLP( - silk_float *A, /* I/O Symmetric square matrix, out: reg. */ - const opus_int M, /* I Size of matrix */ - const silk_float *b, /* I Pointer to b vector */ - silk_float *x /* O Pointer to x solution vector */ -); - -/* Apply sine window to signal vector. */ -/* Window types: */ -/* 1 -> sine window from 0 to pi/2 */ -/* 2 -> sine window from pi/2 to pi */ -void silk_apply_sine_window_FLP( - silk_float px_win[], /* O Pointer to windowed signal */ - const silk_float px[], /* I Pointer to input signal */ - const opus_int win_type, /* I Selects a window type */ - const opus_int length /* I Window length, multiple of 4 */ -); - -/* Wrapper functions. Call flp / fix code */ - -/* Convert AR filter coefficients to NLSF parameters */ -void silk_A2NLSF_FLP( - opus_int16 *NLSF_Q15, /* O NLSF vector [ LPC_order ] */ - const silk_float *pAR, /* I LPC coefficients [ LPC_order ] */ - const opus_int LPC_order /* I LPC order */ -); - -/* Convert NLSF parameters to AR prediction filter coefficients */ -void silk_NLSF2A_FLP( - silk_float *pAR, /* O LPC coefficients [ LPC_order ] */ - const opus_int16 *NLSF_Q15, /* I NLSF vector [ LPC_order ] */ - const opus_int LPC_order /* I LPC order */ -); - -/* Limit, stabilize, and quantize NLSFs */ -void silk_process_NLSFs_FLP( - silk_encoder_state *psEncC, /* I/O Encoder state */ - silk_float PredCoef[ 2 ][ MAX_LPC_ORDER ], /* O Prediction coefficients */ - opus_int16 NLSF_Q15[ MAX_LPC_ORDER ], /* I/O Normalized LSFs (quant out) (0 - (2^15-1)) */ - const opus_int16 prev_NLSF_Q15[ MAX_LPC_ORDER ] /* I Previous Normalized LSFs (0 - (2^15-1)) */ -); - -/* Floating-point Silk NSQ wrapper */ -void silk_NSQ_wrapper_FLP( - silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ - silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ - SideInfoIndices *psIndices, /* I/O Quantization indices */ - silk_nsq_state *psNSQ, /* I/O Noise Shaping Quantzation state */ - opus_int8 pulses[], /* O Quantized pulse signal */ - const silk_float x[] /* I Prefiltered input signal */ -); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/opus-1.0.2/silk/float/noise_shape_analysis_FLP.c b/src/opus-1.0.2/silk/float/noise_shape_analysis_FLP.c deleted file mode 100644 index 33bfd20d..00000000 --- a/src/opus-1.0.2/silk/float/noise_shape_analysis_FLP.c +++ /dev/null @@ -1,365 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main_FLP.h" -#include "tuning_parameters.h" - -/* Compute gain to make warped filter coefficients have a zero mean log frequency response on a */ -/* non-warped frequency scale. (So that it can be implemented with a minimum-phase monic filter.) */ -/* Note: A monic filter is one with the first coefficient equal to 1.0. In Silk we omit the first */ -/* coefficient in an array of coefficients, for monic filters. */ -static inline silk_float warped_gain( - const silk_float *coefs, - silk_float lambda, - opus_int order -) { - opus_int i; - silk_float gain; - - lambda = -lambda; - gain = coefs[ order - 1 ]; - for( i = order - 2; i >= 0; i-- ) { - gain = lambda * gain + coefs[ i ]; - } - return (silk_float)( 1.0f / ( 1.0f - lambda * gain ) ); -} - -/* Convert warped filter coefficients to monic pseudo-warped coefficients and limit maximum */ -/* amplitude of monic warped coefficients by using bandwidth expansion on the true coefficients */ -static inline void warped_true2monic_coefs( - silk_float *coefs_syn, - silk_float *coefs_ana, - silk_float lambda, - silk_float limit, - opus_int order -) { - opus_int i, iter, ind = 0; - silk_float tmp, maxabs, chirp, gain_syn, gain_ana; - - /* Convert to monic coefficients */ - for( i = order - 1; i > 0; i-- ) { - coefs_syn[ i - 1 ] -= lambda * coefs_syn[ i ]; - coefs_ana[ i - 1 ] -= lambda * coefs_ana[ i ]; - } - gain_syn = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_syn[ 0 ] ); - gain_ana = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_ana[ 0 ] ); - for( i = 0; i < order; i++ ) { - coefs_syn[ i ] *= gain_syn; - coefs_ana[ i ] *= gain_ana; - } - - /* Limit */ - for( iter = 0; iter < 10; iter++ ) { - /* Find maximum absolute value */ - maxabs = -1.0f; - for( i = 0; i < order; i++ ) { - tmp = silk_max( silk_abs_float( coefs_syn[ i ] ), silk_abs_float( coefs_ana[ i ] ) ); - if( tmp > maxabs ) { - maxabs = tmp; - ind = i; - } - } - if( maxabs <= limit ) { - /* Coefficients are within range - done */ - return; - } - - /* Convert back to true warped coefficients */ - for( i = 1; i < order; i++ ) { - coefs_syn[ i - 1 ] += lambda * coefs_syn[ i ]; - coefs_ana[ i - 1 ] += lambda * coefs_ana[ i ]; - } - gain_syn = 1.0f / gain_syn; - gain_ana = 1.0f / gain_ana; - for( i = 0; i < order; i++ ) { - coefs_syn[ i ] *= gain_syn; - coefs_ana[ i ] *= gain_ana; - } - - /* Apply bandwidth expansion */ - chirp = 0.99f - ( 0.8f + 0.1f * iter ) * ( maxabs - limit ) / ( maxabs * ( ind + 1 ) ); - silk_bwexpander_FLP( coefs_syn, order, chirp ); - silk_bwexpander_FLP( coefs_ana, order, chirp ); - - /* Convert to monic warped coefficients */ - for( i = order - 1; i > 0; i-- ) { - coefs_syn[ i - 1 ] -= lambda * coefs_syn[ i ]; - coefs_ana[ i - 1 ] -= lambda * coefs_ana[ i ]; - } - gain_syn = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_syn[ 0 ] ); - gain_ana = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_ana[ 0 ] ); - for( i = 0; i < order; i++ ) { - coefs_syn[ i ] *= gain_syn; - coefs_ana[ i ] *= gain_ana; - } - } - silk_assert( 0 ); -} - -/* Compute noise shaping coefficients and initial gain values */ -void silk_noise_shape_analysis_FLP( - silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ - silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ - const silk_float *pitch_res, /* I LPC residual from pitch analysis */ - const silk_float *x /* I Input signal [frame_length + la_shape] */ -) -{ - silk_shape_state_FLP *psShapeSt = &psEnc->sShape; - opus_int k, nSamples; - silk_float SNR_adj_dB, HarmBoost, HarmShapeGain, Tilt; - silk_float nrg, pre_nrg, log_energy, log_energy_prev, energy_variation; - silk_float delta, BWExp1, BWExp2, gain_mult, gain_add, strength, b, warping; - silk_float x_windowed[ SHAPE_LPC_WIN_MAX ]; - silk_float auto_corr[ MAX_SHAPE_LPC_ORDER + 1 ]; - const silk_float *x_ptr, *pitch_res_ptr; - - /* Point to start of first LPC analysis block */ - x_ptr = x - psEnc->sCmn.la_shape; - - /****************/ - /* GAIN CONTROL */ - /****************/ - SNR_adj_dB = psEnc->sCmn.SNR_dB_Q7 * ( 1 / 128.0f ); - - /* Input quality is the average of the quality in the lowest two VAD bands */ - psEncCtrl->input_quality = 0.5f * ( psEnc->sCmn.input_quality_bands_Q15[ 0 ] + psEnc->sCmn.input_quality_bands_Q15[ 1 ] ) * ( 1.0f / 32768.0f ); - - /* Coding quality level, between 0.0 and 1.0 */ - psEncCtrl->coding_quality = silk_sigmoid( 0.25f * ( SNR_adj_dB - 20.0f ) ); - - if( psEnc->sCmn.useCBR == 0 ) { - /* Reduce coding SNR during low speech activity */ - b = 1.0f - psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f ); - SNR_adj_dB -= BG_SNR_DECR_dB * psEncCtrl->coding_quality * ( 0.5f + 0.5f * psEncCtrl->input_quality ) * b * b; - } - - if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - /* Reduce gains for periodic signals */ - SNR_adj_dB += HARM_SNR_INCR_dB * psEnc->LTPCorr; - } else { - /* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */ - SNR_adj_dB += ( -0.4f * psEnc->sCmn.SNR_dB_Q7 * ( 1 / 128.0f ) + 6.0f ) * ( 1.0f - psEncCtrl->input_quality ); - } - - /*************************/ - /* SPARSENESS PROCESSING */ - /*************************/ - /* Set quantizer offset */ - if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - /* Initially set to 0; may be overruled in process_gains(..) */ - psEnc->sCmn.indices.quantOffsetType = 0; - psEncCtrl->sparseness = 0.0f; - } else { - /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */ - nSamples = 2 * psEnc->sCmn.fs_kHz; - energy_variation = 0.0f; - log_energy_prev = 0.0f; - pitch_res_ptr = pitch_res; - for( k = 0; k < silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2; k++ ) { - nrg = ( silk_float )nSamples + ( silk_float )silk_energy_FLP( pitch_res_ptr, nSamples ); - log_energy = silk_log2( nrg ); - if( k > 0 ) { - energy_variation += silk_abs_float( log_energy - log_energy_prev ); - } - log_energy_prev = log_energy; - pitch_res_ptr += nSamples; - } - psEncCtrl->sparseness = silk_sigmoid( 0.4f * ( energy_variation - 5.0f ) ); - - /* Set quantization offset depending on sparseness measure */ - if( psEncCtrl->sparseness > SPARSENESS_THRESHOLD_QNT_OFFSET ) { - psEnc->sCmn.indices.quantOffsetType = 0; - } else { - psEnc->sCmn.indices.quantOffsetType = 1; - } - - /* Increase coding SNR for sparse signals */ - SNR_adj_dB += SPARSE_SNR_INCR_dB * ( psEncCtrl->sparseness - 0.5f ); - } - - /*******************************/ - /* Control bandwidth expansion */ - /*******************************/ - /* More BWE for signals with high prediction gain */ - strength = FIND_PITCH_WHITE_NOISE_FRACTION * psEncCtrl->predGain; /* between 0.0 and 1.0 */ - BWExp1 = BWExp2 = BANDWIDTH_EXPANSION / ( 1.0f + strength * strength ); - delta = LOW_RATE_BANDWIDTH_EXPANSION_DELTA * ( 1.0f - 0.75f * psEncCtrl->coding_quality ); - BWExp1 -= delta; - BWExp2 += delta; - /* BWExp1 will be applied after BWExp2, so make it relative */ - BWExp1 /= BWExp2; - - if( psEnc->sCmn.warping_Q16 > 0 ) { - /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */ - warping = (silk_float)psEnc->sCmn.warping_Q16 / 65536.0f + 0.01f * psEncCtrl->coding_quality; - } else { - warping = 0.0f; - } - - /********************************************/ - /* Compute noise shaping AR coefs and gains */ - /********************************************/ - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - /* Apply window: sine slope followed by flat part followed by cosine slope */ - opus_int shift, slope_part, flat_part; - flat_part = psEnc->sCmn.fs_kHz * 3; - slope_part = ( psEnc->sCmn.shapeWinLength - flat_part ) / 2; - - silk_apply_sine_window_FLP( x_windowed, x_ptr, 1, slope_part ); - shift = slope_part; - silk_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(silk_float) ); - shift += flat_part; - silk_apply_sine_window_FLP( x_windowed + shift, x_ptr + shift, 2, slope_part ); - - /* Update pointer: next LPC analysis block */ - x_ptr += psEnc->sCmn.subfr_length; - - if( psEnc->sCmn.warping_Q16 > 0 ) { - /* Calculate warped auto correlation */ - silk_warped_autocorrelation_FLP( auto_corr, x_windowed, warping, - psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder ); - } else { - /* Calculate regular auto correlation */ - silk_autocorrelation_FLP( auto_corr, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1 ); - } - - /* Add white noise, as a fraction of energy */ - auto_corr[ 0 ] += auto_corr[ 0 ] * SHAPE_WHITE_NOISE_FRACTION; - - /* Convert correlations to prediction coefficients, and compute residual energy */ - nrg = silk_levinsondurbin_FLP( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], auto_corr, psEnc->sCmn.shapingLPCOrder ); - psEncCtrl->Gains[ k ] = ( silk_float )sqrt( nrg ); - - if( psEnc->sCmn.warping_Q16 > 0 ) { - /* Adjust gain for warping */ - psEncCtrl->Gains[ k ] *= warped_gain( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], warping, psEnc->sCmn.shapingLPCOrder ); - } - - /* Bandwidth expansion for synthesis filter shaping */ - silk_bwexpander_FLP( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder, BWExp2 ); - - /* Compute noise shaping filter coefficients */ - silk_memcpy( - &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ], - &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], - psEnc->sCmn.shapingLPCOrder * sizeof( silk_float ) ); - - /* Bandwidth expansion for analysis filter shaping */ - silk_bwexpander_FLP( &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder, BWExp1 ); - - /* Ratio of prediction gains, in energy domain */ - pre_nrg = silk_LPC_inverse_pred_gain_FLP( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder ); - nrg = silk_LPC_inverse_pred_gain_FLP( &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder ); - psEncCtrl->GainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg ); - - /* Convert to monic warped prediction coefficients and limit absolute values */ - warped_true2monic_coefs( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ], - warping, 3.999f, psEnc->sCmn.shapingLPCOrder ); - } - - /*****************/ - /* Gain tweaking */ - /*****************/ - /* Increase gains during low speech activity */ - gain_mult = (silk_float)pow( 2.0f, -0.16f * SNR_adj_dB ); - gain_add = (silk_float)pow( 2.0f, 0.16f * MIN_QGAIN_DB ); - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - psEncCtrl->Gains[ k ] *= gain_mult; - psEncCtrl->Gains[ k ] += gain_add; - } - - gain_mult = 1.0f + INPUT_TILT + psEncCtrl->coding_quality * HIGH_RATE_INPUT_TILT; - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - psEncCtrl->GainsPre[ k ] *= gain_mult; - } - - /************************************************/ - /* Control low-frequency shaping and noise tilt */ - /************************************************/ - /* Less low frequency shaping for noisy inputs */ - strength = LOW_FREQ_SHAPING * ( 1.0f + LOW_QUALITY_LOW_FREQ_SHAPING_DECR * ( psEnc->sCmn.input_quality_bands_Q15[ 0 ] * ( 1.0f / 32768.0f ) - 1.0f ) ); - strength *= psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f ); - if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - /* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */ - /*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/ - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - b = 0.2f / psEnc->sCmn.fs_kHz + 3.0f / psEncCtrl->pitchL[ k ]; - psEncCtrl->LF_MA_shp[ k ] = -1.0f + b; - psEncCtrl->LF_AR_shp[ k ] = 1.0f - b - b * strength; - } - Tilt = - HP_NOISE_COEF - - (1 - HP_NOISE_COEF) * HARM_HP_NOISE_COEF * psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f ); - } else { - b = 1.3f / psEnc->sCmn.fs_kHz; - psEncCtrl->LF_MA_shp[ 0 ] = -1.0f + b; - psEncCtrl->LF_AR_shp[ 0 ] = 1.0f - b - b * strength * 0.6f; - for( k = 1; k < psEnc->sCmn.nb_subfr; k++ ) { - psEncCtrl->LF_MA_shp[ k ] = psEncCtrl->LF_MA_shp[ 0 ]; - psEncCtrl->LF_AR_shp[ k ] = psEncCtrl->LF_AR_shp[ 0 ]; - } - Tilt = -HP_NOISE_COEF; - } - - /****************************/ - /* HARMONIC SHAPING CONTROL */ - /****************************/ - /* Control boosting of harmonic frequencies */ - HarmBoost = LOW_RATE_HARMONIC_BOOST * ( 1.0f - psEncCtrl->coding_quality ) * psEnc->LTPCorr; - - /* More harmonic boost for noisy input signals */ - HarmBoost += LOW_INPUT_QUALITY_HARMONIC_BOOST * ( 1.0f - psEncCtrl->input_quality ); - - if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - /* Harmonic noise shaping */ - HarmShapeGain = HARMONIC_SHAPING; - - /* More harmonic noise shaping for high bitrates or noisy input */ - HarmShapeGain += HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING * - ( 1.0f - ( 1.0f - psEncCtrl->coding_quality ) * psEncCtrl->input_quality ); - - /* Less harmonic noise shaping for less periodic signals */ - HarmShapeGain *= ( silk_float )sqrt( psEnc->LTPCorr ); - } else { - HarmShapeGain = 0.0f; - } - - /*************************/ - /* Smooth over subframes */ - /*************************/ - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - psShapeSt->HarmBoost_smth += SUBFR_SMTH_COEF * ( HarmBoost - psShapeSt->HarmBoost_smth ); - psEncCtrl->HarmBoost[ k ] = psShapeSt->HarmBoost_smth; - psShapeSt->HarmShapeGain_smth += SUBFR_SMTH_COEF * ( HarmShapeGain - psShapeSt->HarmShapeGain_smth ); - psEncCtrl->HarmShapeGain[ k ] = psShapeSt->HarmShapeGain_smth; - psShapeSt->Tilt_smth += SUBFR_SMTH_COEF * ( Tilt - psShapeSt->Tilt_smth ); - psEncCtrl->Tilt[ k ] = psShapeSt->Tilt_smth; - } -} diff --git a/src/opus-1.0.2/silk/float/pitch_analysis_core_FLP.c b/src/opus-1.0.2/silk/float/pitch_analysis_core_FLP.c deleted file mode 100644 index fbff90c3..00000000 --- a/src/opus-1.0.2/silk/float/pitch_analysis_core_FLP.c +++ /dev/null @@ -1,630 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/***************************************************************************** -* Pitch analyser function -******************************************************************************/ -#include "SigProc_FLP.h" -#include "SigProc_FIX.h" -#include "pitch_est_defines.h" - -#define SCRATCH_SIZE 22 -#define eps 1.192092896e-07f - -/************************************************************/ -/* Internally used functions */ -/************************************************************/ -static void silk_P_Ana_calc_corr_st3( - silk_float cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */ - const silk_float frame[], /* I vector to correlate */ - opus_int start_lag, /* I start lag */ - opus_int sf_length, /* I sub frame length */ - opus_int nb_subfr, /* I number of subframes */ - opus_int complexity /* I Complexity setting */ -); - -static void silk_P_Ana_calc_energy_st3( - silk_float energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */ - const silk_float frame[], /* I vector to correlate */ - opus_int start_lag, /* I start lag */ - opus_int sf_length, /* I sub frame length */ - opus_int nb_subfr, /* I number of subframes */ - opus_int complexity /* I Complexity setting */ -); - -/************************************************************/ -/* CORE PITCH ANALYSIS FUNCTION */ -/************************************************************/ -opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced, 1 unvoiced */ - const silk_float *frame, /* I Signal of length PE_FRAME_LENGTH_MS*Fs_kHz */ - opus_int *pitch_out, /* O Pitch lag values [nb_subfr] */ - opus_int16 *lagIndex, /* O Lag Index */ - opus_int8 *contourIndex, /* O Pitch contour Index */ - silk_float *LTPCorr, /* I/O Normalized correlation; input: value from previous frame */ - opus_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */ - const silk_float search_thres1, /* I First stage threshold for lag candidates 0 - 1 */ - const silk_float search_thres2, /* I Final threshold for lag candidates 0 - 1 */ - const opus_int Fs_kHz, /* I sample frequency (kHz) */ - const opus_int complexity, /* I Complexity setting, 0-2, where 2 is highest */ - const opus_int nb_subfr /* I Number of 5 ms subframes */ -) -{ - opus_int i, k, d, j; - silk_float frame_8kHz[ PE_MAX_FRAME_LENGTH_MS * 8 ]; - silk_float frame_4kHz[ PE_MAX_FRAME_LENGTH_MS * 4 ]; - opus_int16 frame_8_FIX[ PE_MAX_FRAME_LENGTH_MS * 8 ]; - opus_int16 frame_4_FIX[ PE_MAX_FRAME_LENGTH_MS * 4 ]; - opus_int32 filt_state[ 6 ]; - silk_float threshold, contour_bias; - silk_float C[ PE_MAX_NB_SUBFR][ (PE_MAX_LAG >> 1) + 5 ]; - silk_float CC[ PE_NB_CBKS_STAGE2_EXT ]; - const silk_float *target_ptr, *basis_ptr; - double cross_corr, normalizer, energy, energy_tmp; - opus_int d_srch[ PE_D_SRCH_LENGTH ]; - opus_int16 d_comp[ (PE_MAX_LAG >> 1) + 5 ]; - opus_int length_d_srch, length_d_comp; - silk_float Cmax, CCmax, CCmax_b, CCmax_new_b, CCmax_new; - opus_int CBimax, CBimax_new, lag, start_lag, end_lag, lag_new; - opus_int cbk_size; - silk_float lag_log2, prevLag_log2, delta_lag_log2_sqr; - silk_float energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ]; - silk_float cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ]; - opus_int lag_counter; - opus_int frame_length, frame_length_8kHz, frame_length_4kHz; - opus_int sf_length, sf_length_8kHz, sf_length_4kHz; - opus_int min_lag, min_lag_8kHz, min_lag_4kHz; - opus_int max_lag, max_lag_8kHz, max_lag_4kHz; - opus_int nb_cbk_search; - const opus_int8 *Lag_CB_ptr; - - /* Check for valid sampling frequency */ - silk_assert( Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16 ); - - /* Check for valid complexity setting */ - silk_assert( complexity >= SILK_PE_MIN_COMPLEX ); - silk_assert( complexity <= SILK_PE_MAX_COMPLEX ); - - silk_assert( search_thres1 >= 0.0f && search_thres1 <= 1.0f ); - silk_assert( search_thres2 >= 0.0f && search_thres2 <= 1.0f ); - - /* Set up frame lengths max / min lag for the sampling frequency */ - frame_length = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * Fs_kHz; - frame_length_4kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 4; - frame_length_8kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 8; - sf_length = PE_SUBFR_LENGTH_MS * Fs_kHz; - sf_length_4kHz = PE_SUBFR_LENGTH_MS * 4; - sf_length_8kHz = PE_SUBFR_LENGTH_MS * 8; - min_lag = PE_MIN_LAG_MS * Fs_kHz; - min_lag_4kHz = PE_MIN_LAG_MS * 4; - min_lag_8kHz = PE_MIN_LAG_MS * 8; - max_lag = PE_MAX_LAG_MS * Fs_kHz - 1; - max_lag_4kHz = PE_MAX_LAG_MS * 4; - max_lag_8kHz = PE_MAX_LAG_MS * 8 - 1; - - silk_memset(C, 0, sizeof(silk_float) * nb_subfr * ((PE_MAX_LAG >> 1) + 5)); - - /* Resample from input sampled at Fs_kHz to 8 kHz */ - if( Fs_kHz == 16 ) { - /* Resample to 16 -> 8 khz */ - opus_int16 frame_16_FIX[ 16 * PE_MAX_FRAME_LENGTH_MS ]; - silk_float2short_array( frame_16_FIX, frame, frame_length ); - silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) ); - silk_resampler_down2( filt_state, frame_8_FIX, frame_16_FIX, frame_length ); - silk_short2float_array( frame_8kHz, frame_8_FIX, frame_length_8kHz ); - } else if( Fs_kHz == 12 ) { - /* Resample to 12 -> 8 khz */ - opus_int16 frame_12_FIX[ 12 * PE_MAX_FRAME_LENGTH_MS ]; - silk_float2short_array( frame_12_FIX, frame, frame_length ); - silk_memset( filt_state, 0, 6 * sizeof( opus_int32 ) ); - silk_resampler_down2_3( filt_state, frame_8_FIX, frame_12_FIX, frame_length ); - silk_short2float_array( frame_8kHz, frame_8_FIX, frame_length_8kHz ); - } else { - silk_assert( Fs_kHz == 8 ); - silk_float2short_array( frame_8_FIX, frame, frame_length_8kHz ); - } - - /* Decimate again to 4 kHz */ - silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) ); - silk_resampler_down2( filt_state, frame_4_FIX, frame_8_FIX, frame_length_8kHz ); - silk_short2float_array( frame_4kHz, frame_4_FIX, frame_length_4kHz ); - - /* Low-pass filter */ - for( i = frame_length_4kHz - 1; i > 0; i-- ) { - frame_4kHz[ i ] += frame_4kHz[ i - 1 ]; - } - - /****************************************************************************** - * FIRST STAGE, operating in 4 khz - ******************************************************************************/ - target_ptr = &frame_4kHz[ silk_LSHIFT( sf_length_4kHz, 2 ) ]; - for( k = 0; k < nb_subfr >> 1; k++ ) { - /* Check that we are within range of the array */ - silk_assert( target_ptr >= frame_4kHz ); - silk_assert( target_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz ); - - basis_ptr = target_ptr - min_lag_4kHz; - - /* Check that we are within range of the array */ - silk_assert( basis_ptr >= frame_4kHz ); - silk_assert( basis_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz ); - - /* Calculate first vector products before loop */ - cross_corr = silk_inner_product_FLP( target_ptr, basis_ptr, sf_length_8kHz ); - normalizer = silk_energy_FLP( basis_ptr, sf_length_8kHz ) + sf_length_8kHz * 4000.0f; - - C[ 0 ][ min_lag_4kHz ] += (silk_float)(cross_corr / sqrt(normalizer)); - - /* From now on normalizer is computed recursively */ - for(d = min_lag_4kHz + 1; d <= max_lag_4kHz; d++) { - basis_ptr--; - - /* Check that we are within range of the array */ - silk_assert( basis_ptr >= frame_4kHz ); - silk_assert( basis_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz ); - - cross_corr = silk_inner_product_FLP(target_ptr, basis_ptr, sf_length_8kHz); - - /* Add contribution of new sample and remove contribution from oldest sample */ - normalizer += - basis_ptr[ 0 ] * (double)basis_ptr[ 0 ] - - basis_ptr[ sf_length_8kHz ] * (double)basis_ptr[ sf_length_8kHz ]; - C[ 0 ][ d ] += (silk_float)(cross_corr / sqrt( normalizer )); - } - /* Update target pointer */ - target_ptr += sf_length_8kHz; - } - - /* Apply short-lag bias */ - for( i = max_lag_4kHz; i >= min_lag_4kHz; i-- ) { - C[ 0 ][ i ] -= C[ 0 ][ i ] * i / 4096.0f; - } - - /* Sort */ - length_d_srch = 4 + 2 * complexity; - silk_assert( 3 * length_d_srch <= PE_D_SRCH_LENGTH ); - silk_insertion_sort_decreasing_FLP( &C[ 0 ][ min_lag_4kHz ], d_srch, max_lag_4kHz - min_lag_4kHz + 1, length_d_srch ); - - /* Escape if correlation is very low already here */ - Cmax = C[ 0 ][ min_lag_4kHz ]; - target_ptr = &frame_4kHz[ silk_SMULBB( sf_length_4kHz, nb_subfr ) ]; - energy = 1000.0f; - for( i = 0; i < silk_LSHIFT( sf_length_4kHz, 2 ); i++ ) { - energy += target_ptr[i] * (double)target_ptr[i]; - } - threshold = Cmax * Cmax; - if( energy / 16.0f > threshold ) { - silk_memset( pitch_out, 0, nb_subfr * sizeof( opus_int ) ); - *LTPCorr = 0.0f; - *lagIndex = 0; - *contourIndex = 0; - return 1; - } - - threshold = search_thres1 * Cmax; - for( i = 0; i < length_d_srch; i++ ) { - /* Convert to 8 kHz indices for the sorted correlation that exceeds the threshold */ - if( C[ 0 ][ min_lag_4kHz + i ] > threshold ) { - d_srch[ i ] = silk_LSHIFT( d_srch[ i ] + min_lag_4kHz, 1 ); - } else { - length_d_srch = i; - break; - } - } - silk_assert( length_d_srch > 0 ); - - for( i = min_lag_8kHz - 5; i < max_lag_8kHz + 5; i++ ) { - d_comp[ i ] = 0; - } - for( i = 0; i < length_d_srch; i++ ) { - d_comp[ d_srch[ i ] ] = 1; - } - - /* Convolution */ - for( i = max_lag_8kHz + 3; i >= min_lag_8kHz; i-- ) { - d_comp[ i ] += d_comp[ i - 1 ] + d_comp[ i - 2 ]; - } - - length_d_srch = 0; - for( i = min_lag_8kHz; i < max_lag_8kHz + 1; i++ ) { - if( d_comp[ i + 1 ] > 0 ) { - d_srch[ length_d_srch ] = i; - length_d_srch++; - } - } - - /* Convolution */ - for( i = max_lag_8kHz + 3; i >= min_lag_8kHz; i-- ) { - d_comp[ i ] += d_comp[ i - 1 ] + d_comp[ i - 2 ] + d_comp[ i - 3 ]; - } - - length_d_comp = 0; - for( i = min_lag_8kHz; i < max_lag_8kHz + 4; i++ ) { - if( d_comp[ i ] > 0 ) { - d_comp[ length_d_comp ] = (opus_int16)( i - 2 ); - length_d_comp++; - } - } - - /********************************************************************************** - ** SECOND STAGE, operating at 8 kHz, on lag sections with high correlation - *************************************************************************************/ - /********************************************************************************* - * Find energy of each subframe projected onto its history, for a range of delays - *********************************************************************************/ - silk_memset( C, 0, PE_MAX_NB_SUBFR*((PE_MAX_LAG >> 1) + 5) * sizeof(silk_float)); - - if( Fs_kHz == 8 ) { - target_ptr = &frame[ PE_LTP_MEM_LENGTH_MS * 8 ]; - } else { - target_ptr = &frame_8kHz[ PE_LTP_MEM_LENGTH_MS * 8 ]; - } - for( k = 0; k < nb_subfr; k++ ) { - energy_tmp = silk_energy_FLP( target_ptr, sf_length_8kHz ); - for( j = 0; j < length_d_comp; j++ ) { - d = d_comp[ j ]; - basis_ptr = target_ptr - d; - cross_corr = silk_inner_product_FLP( basis_ptr, target_ptr, sf_length_8kHz ); - energy = silk_energy_FLP( basis_ptr, sf_length_8kHz ); - if( cross_corr > 0.0f ) { - C[ k ][ d ] = (silk_float)(cross_corr * cross_corr / (energy * energy_tmp + eps)); - } else { - C[ k ][ d ] = 0.0f; - } - } - target_ptr += sf_length_8kHz; - } - - /* search over lag range and lags codebook */ - /* scale factor for lag codebook, as a function of center lag */ - - CCmax = 0.0f; /* This value doesn't matter */ - CCmax_b = -1000.0f; - - CBimax = 0; /* To avoid returning undefined lag values */ - lag = -1; /* To check if lag with strong enough correlation has been found */ - - if( prevLag > 0 ) { - if( Fs_kHz == 12 ) { - prevLag = silk_LSHIFT( prevLag, 1 ) / 3; - } else if( Fs_kHz == 16 ) { - prevLag = silk_RSHIFT( prevLag, 1 ); - } - prevLag_log2 = silk_log2((silk_float)prevLag); - } else { - prevLag_log2 = 0; - } - - /* Set up stage 2 codebook based on number of subframes */ - if( nb_subfr == PE_MAX_NB_SUBFR ) { - cbk_size = PE_NB_CBKS_STAGE2_EXT; - Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ]; - if( Fs_kHz == 8 && complexity > SILK_PE_MIN_COMPLEX ) { - /* If input is 8 khz use a larger codebook here because it is last stage */ - nb_cbk_search = PE_NB_CBKS_STAGE2_EXT; - } else { - nb_cbk_search = PE_NB_CBKS_STAGE2; - } - } else { - cbk_size = PE_NB_CBKS_STAGE2_10MS; - Lag_CB_ptr = &silk_CB_lags_stage2_10_ms[ 0 ][ 0 ]; - nb_cbk_search = PE_NB_CBKS_STAGE2_10MS; - } - - for( k = 0; k < length_d_srch; k++ ) { - d = d_srch[ k ]; - for( j = 0; j < nb_cbk_search; j++ ) { - CC[j] = 0.0f; - for( i = 0; i < nb_subfr; i++ ) { - /* Try all codebooks */ - CC[ j ] += C[ i ][ d + matrix_ptr( Lag_CB_ptr, i, j, cbk_size )]; - } - } - /* Find best codebook */ - CCmax_new = -1000.0f; - CBimax_new = 0; - for( i = 0; i < nb_cbk_search; i++ ) { - if( CC[ i ] > CCmax_new ) { - CCmax_new = CC[ i ]; - CBimax_new = i; - } - } - CCmax_new = silk_max_float(CCmax_new, 0.0f); /* To avoid taking square root of negative number later */ - CCmax_new_b = CCmax_new; - - /* Bias towards shorter lags */ - lag_log2 = silk_log2((silk_float)d); - CCmax_new_b -= PE_SHORTLAG_BIAS * nb_subfr * lag_log2; - - /* Bias towards previous lag */ - if( prevLag > 0 ) { - delta_lag_log2_sqr = lag_log2 - prevLag_log2; - delta_lag_log2_sqr *= delta_lag_log2_sqr; - CCmax_new_b -= PE_PREVLAG_BIAS * nb_subfr * (*LTPCorr) * delta_lag_log2_sqr / (delta_lag_log2_sqr + 0.5f); - } - - if( CCmax_new_b > CCmax_b && /* Find maximum biased correlation */ - CCmax_new > nb_subfr * search_thres2 * search_thres2 && /* Correlation needs to be high enough to be voiced */ - silk_CB_lags_stage2[ 0 ][ CBimax_new ] <= min_lag_8kHz /* Lag must be in range */ - ) { - CCmax_b = CCmax_new_b; - CCmax = CCmax_new; - lag = d; - CBimax = CBimax_new; - } - } - - if( lag == -1 ) { - /* No suitable candidate found */ - silk_memset( pitch_out, 0, PE_MAX_NB_SUBFR * sizeof(opus_int) ); - *LTPCorr = 0.0f; - *lagIndex = 0; - *contourIndex = 0; - return 1; - } - - if( Fs_kHz > 8 ) { - /* Search in original signal */ - - /* Compensate for decimation */ - silk_assert( lag == silk_SAT16( lag ) ); - if( Fs_kHz == 12 ) { - lag = silk_RSHIFT_ROUND( silk_SMULBB( lag, 3 ), 1 ); - } else { /* Fs_kHz == 16 */ - lag = silk_LSHIFT( lag, 1 ); - } - - lag = silk_LIMIT_int( lag, min_lag, max_lag ); - start_lag = silk_max_int( lag - 2, min_lag ); - end_lag = silk_min_int( lag + 2, max_lag ); - lag_new = lag; /* to avoid undefined lag */ - CBimax = 0; /* to avoid undefined lag */ - silk_assert( CCmax >= 0.0f ); - *LTPCorr = (silk_float)sqrt( CCmax / nb_subfr ); /* Output normalized correlation */ - - CCmax = -1000.0f; - - /* Calculate the correlations and energies needed in stage 3 */ - silk_P_Ana_calc_corr_st3( cross_corr_st3, frame, start_lag, sf_length, nb_subfr, complexity ); - silk_P_Ana_calc_energy_st3( energies_st3, frame, start_lag, sf_length, nb_subfr, complexity ); - - lag_counter = 0; - silk_assert( lag == silk_SAT16( lag ) ); - contour_bias = PE_FLATCONTOUR_BIAS / lag; - - /* Set up cbk parameters according to complexity setting and frame length */ - if( nb_subfr == PE_MAX_NB_SUBFR ) { - nb_cbk_search = (opus_int)silk_nb_cbk_searchs_stage3[ complexity ]; - cbk_size = PE_NB_CBKS_STAGE3_MAX; - Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ]; - } else { - nb_cbk_search = PE_NB_CBKS_STAGE3_10MS; - cbk_size = PE_NB_CBKS_STAGE3_10MS; - Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ]; - } - - for( d = start_lag; d <= end_lag; d++ ) { - for( j = 0; j < nb_cbk_search; j++ ) { - cross_corr = 0.0; - energy = eps; - for( k = 0; k < nb_subfr; k++ ) { - energy += energies_st3[ k ][ j ][ lag_counter ]; - cross_corr += cross_corr_st3[ k ][ j ][ lag_counter ]; - } - if( cross_corr > 0.0 ) { - CCmax_new = (silk_float)(cross_corr * cross_corr / energy); - /* Reduce depending on flatness of contour */ - CCmax_new *= 1.0f - contour_bias * j; - } else { - CCmax_new = 0.0f; - } - - if( CCmax_new > CCmax && - ( d + (opus_int)silk_CB_lags_stage3[ 0 ][ j ] ) <= max_lag - ) { - CCmax = CCmax_new; - lag_new = d; - CBimax = j; - } - } - lag_counter++; - } - - for( k = 0; k < nb_subfr; k++ ) { - pitch_out[ k ] = lag_new + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size ); - pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], min_lag, PE_MAX_LAG_MS * Fs_kHz ); - } - *lagIndex = (opus_int16)( lag_new - min_lag ); - *contourIndex = (opus_int8)CBimax; - } else { /* Fs_kHz == 8 */ - /* Save Lags and correlation */ - silk_assert( CCmax >= 0.0f ); - *LTPCorr = (silk_float)sqrt( CCmax / nb_subfr ); /* Output normalized correlation */ - for( k = 0; k < nb_subfr; k++ ) { - pitch_out[ k ] = lag + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size ); - pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], min_lag_8kHz, PE_MAX_LAG_MS * Fs_kHz ); - } - *lagIndex = (opus_int16)( lag - min_lag_8kHz ); - *contourIndex = (opus_int8)CBimax; - } - silk_assert( *lagIndex >= 0 ); - /* return as voiced */ - return 0; -} - -static void silk_P_Ana_calc_corr_st3( - silk_float cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */ - const silk_float frame[], /* I vector to correlate */ - opus_int start_lag, /* I start lag */ - opus_int sf_length, /* I sub frame length */ - opus_int nb_subfr, /* I number of subframes */ - opus_int complexity /* I Complexity setting */ -) - /*********************************************************************** - Calculates the correlations used in stage 3 search. In order to cover - the whole lag codebook for all the searched offset lags (lag +- 2), - the following correlations are needed in each sub frame: - - sf1: lag range [-8,...,7] total 16 correlations - sf2: lag range [-4,...,4] total 9 correlations - sf3: lag range [-3,....4] total 8 correltions - sf4: lag range [-6,....8] total 15 correlations - - In total 48 correlations. The direct implementation computed in worst case - 4*12*5 = 240 correlations, but more likely around 120. - **********************************************************************/ -{ - const silk_float *target_ptr, *basis_ptr; - opus_int i, j, k, lag_counter, lag_low, lag_high; - opus_int nb_cbk_search, delta, idx, cbk_size; - silk_float scratch_mem[ SCRATCH_SIZE ]; - const opus_int8 *Lag_range_ptr, *Lag_CB_ptr; - - silk_assert( complexity >= SILK_PE_MIN_COMPLEX ); - silk_assert( complexity <= SILK_PE_MAX_COMPLEX ); - - if( nb_subfr == PE_MAX_NB_SUBFR ) { - Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ]; - Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ]; - nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ]; - cbk_size = PE_NB_CBKS_STAGE3_MAX; - } else { - silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1); - Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ]; - Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ]; - nb_cbk_search = PE_NB_CBKS_STAGE3_10MS; - cbk_size = PE_NB_CBKS_STAGE3_10MS; - } - - target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ]; /* Pointer to middle of frame */ - for( k = 0; k < nb_subfr; k++ ) { - lag_counter = 0; - - /* Calculate the correlations for each subframe */ - lag_low = matrix_ptr( Lag_range_ptr, k, 0, 2 ); - lag_high = matrix_ptr( Lag_range_ptr, k, 1, 2 ); - for( j = lag_low; j <= lag_high; j++ ) { - basis_ptr = target_ptr - ( start_lag + j ); - silk_assert( lag_counter < SCRATCH_SIZE ); - scratch_mem[ lag_counter ] = (silk_float)silk_inner_product_FLP( target_ptr, basis_ptr, sf_length ); - lag_counter++; - } - - delta = matrix_ptr( Lag_range_ptr, k, 0, 2 ); - for( i = 0; i < nb_cbk_search; i++ ) { - /* Fill out the 3 dim array that stores the correlations for */ - /* each code_book vector for each start lag */ - idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta; - for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) { - silk_assert( idx + j < SCRATCH_SIZE ); - silk_assert( idx + j < lag_counter ); - cross_corr_st3[ k ][ i ][ j ] = scratch_mem[ idx + j ]; - } - } - target_ptr += sf_length; - } -} - -static void silk_P_Ana_calc_energy_st3( - silk_float energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */ - const silk_float frame[], /* I vector to correlate */ - opus_int start_lag, /* I start lag */ - opus_int sf_length, /* I sub frame length */ - opus_int nb_subfr, /* I number of subframes */ - opus_int complexity /* I Complexity setting */ -) -/**************************************************************** -Calculate the energies for first two subframes. The energies are -calculated recursively. -****************************************************************/ -{ - const silk_float *target_ptr, *basis_ptr; - double energy; - opus_int k, i, j, lag_counter; - opus_int nb_cbk_search, delta, idx, cbk_size, lag_diff; - silk_float scratch_mem[ SCRATCH_SIZE ]; - const opus_int8 *Lag_range_ptr, *Lag_CB_ptr; - - silk_assert( complexity >= SILK_PE_MIN_COMPLEX ); - silk_assert( complexity <= SILK_PE_MAX_COMPLEX ); - - if( nb_subfr == PE_MAX_NB_SUBFR ) { - Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ]; - Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ]; - nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ]; - cbk_size = PE_NB_CBKS_STAGE3_MAX; - } else { - silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1); - Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ]; - Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ]; - nb_cbk_search = PE_NB_CBKS_STAGE3_10MS; - cbk_size = PE_NB_CBKS_STAGE3_10MS; - } - - target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ]; - for( k = 0; k < nb_subfr; k++ ) { - lag_counter = 0; - - /* Calculate the energy for first lag */ - basis_ptr = target_ptr - ( start_lag + matrix_ptr( Lag_range_ptr, k, 0, 2 ) ); - energy = silk_energy_FLP( basis_ptr, sf_length ) + 1e-3; - silk_assert( energy >= 0.0 ); - scratch_mem[lag_counter] = (silk_float)energy; - lag_counter++; - - lag_diff = ( matrix_ptr( Lag_range_ptr, k, 1, 2 ) - matrix_ptr( Lag_range_ptr, k, 0, 2 ) + 1 ); - for( i = 1; i < lag_diff; i++ ) { - /* remove part outside new window */ - energy -= basis_ptr[sf_length - i] * (double)basis_ptr[sf_length - i]; - silk_assert( energy >= 0.0 ); - - /* add part that comes into window */ - energy += basis_ptr[ -i ] * (double)basis_ptr[ -i ]; - silk_assert( energy >= 0.0 ); - silk_assert( lag_counter < SCRATCH_SIZE ); - scratch_mem[lag_counter] = (silk_float)energy; - lag_counter++; - } - - delta = matrix_ptr( Lag_range_ptr, k, 0, 2 ); - for( i = 0; i < nb_cbk_search; i++ ) { - /* Fill out the 3 dim array that stores the correlations for */ - /* each code_book vector for each start lag */ - idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta; - for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) { - silk_assert( idx + j < SCRATCH_SIZE ); - silk_assert( idx + j < lag_counter ); - energies_st3[ k ][ i ][ j ] = scratch_mem[ idx + j ]; - silk_assert( energies_st3[ k ][ i ][ j ] >= 0.0f ); - } - } - target_ptr += sf_length; - } -} diff --git a/src/opus-1.0.2/silk/float/prefilter_FLP.c b/src/opus-1.0.2/silk/float/prefilter_FLP.c deleted file mode 100644 index d6c84398..00000000 --- a/src/opus-1.0.2/silk/float/prefilter_FLP.c +++ /dev/null @@ -1,206 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main_FLP.h" -#include "tuning_parameters.h" - -/* -* Prefilter for finding Quantizer input signal -*/ -static inline void silk_prefilt_FLP( - silk_prefilter_state_FLP *P, /* I/O state */ - silk_float st_res[], /* I */ - silk_float xw[], /* O */ - silk_float *HarmShapeFIR, /* I */ - silk_float Tilt, /* I */ - silk_float LF_MA_shp, /* I */ - silk_float LF_AR_shp, /* I */ - opus_int lag, /* I */ - opus_int length /* I */ -); - -static void silk_warped_LPC_analysis_filter_FLP( - silk_float state[], /* I/O State [order + 1] */ - silk_float res[], /* O Residual signal [length] */ - const silk_float coef[], /* I Coefficients [order] */ - const silk_float input[], /* I Input signal [length] */ - const silk_float lambda, /* I Warping factor */ - const opus_int length, /* I Length of input signal */ - const opus_int order /* I Filter order (even) */ -) -{ - opus_int n, i; - silk_float acc, tmp1, tmp2; - - /* Order must be even */ - silk_assert( ( order & 1 ) == 0 ); - - for( n = 0; n < length; n++ ) { - /* Output of lowpass section */ - tmp2 = state[ 0 ] + lambda * state[ 1 ]; - state[ 0 ] = input[ n ]; - /* Output of allpass section */ - tmp1 = state[ 1 ] + lambda * ( state[ 2 ] - tmp2 ); - state[ 1 ] = tmp2; - acc = coef[ 0 ] * tmp2; - /* Loop over allpass sections */ - for( i = 2; i < order; i += 2 ) { - /* Output of allpass section */ - tmp2 = state[ i ] + lambda * ( state[ i + 1 ] - tmp1 ); - state[ i ] = tmp1; - acc += coef[ i - 1 ] * tmp1; - /* Output of allpass section */ - tmp1 = state[ i + 1 ] + lambda * ( state[ i + 2 ] - tmp2 ); - state[ i + 1 ] = tmp2; - acc += coef[ i ] * tmp2; - } - state[ order ] = tmp1; - acc += coef[ order - 1 ] * tmp1; - res[ n ] = input[ n ] - acc; - } -} - -/* -* silk_prefilter. Main prefilter function -*/ -void silk_prefilter_FLP( - silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ - const silk_encoder_control_FLP *psEncCtrl, /* I Encoder control FLP */ - silk_float xw[], /* O Weighted signal */ - const silk_float x[] /* I Speech signal */ -) -{ - silk_prefilter_state_FLP *P = &psEnc->sPrefilt; - opus_int j, k, lag; - silk_float HarmShapeGain, Tilt, LF_MA_shp, LF_AR_shp; - silk_float B[ 2 ]; - const silk_float *AR1_shp; - const silk_float *px; - silk_float *pxw; - silk_float HarmShapeFIR[ 3 ]; - silk_float st_res[ MAX_SUB_FRAME_LENGTH + MAX_LPC_ORDER ]; - - /* Set up pointers */ - px = x; - pxw = xw; - lag = P->lagPrev; - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - /* Update Variables that change per sub frame */ - if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - lag = psEncCtrl->pitchL[ k ]; - } - - /* Noise shape parameters */ - HarmShapeGain = psEncCtrl->HarmShapeGain[ k ] * ( 1.0f - psEncCtrl->HarmBoost[ k ] ); - HarmShapeFIR[ 0 ] = 0.25f * HarmShapeGain; - HarmShapeFIR[ 1 ] = 32767.0f / 65536.0f * HarmShapeGain; - HarmShapeFIR[ 2 ] = 0.25f * HarmShapeGain; - Tilt = psEncCtrl->Tilt[ k ]; - LF_MA_shp = psEncCtrl->LF_MA_shp[ k ]; - LF_AR_shp = psEncCtrl->LF_AR_shp[ k ]; - AR1_shp = &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ]; - - /* Short term FIR filtering */ - silk_warped_LPC_analysis_filter_FLP( P->sAR_shp, st_res, AR1_shp, px, - (silk_float)psEnc->sCmn.warping_Q16 / 65536.0f, psEnc->sCmn.subfr_length, psEnc->sCmn.shapingLPCOrder ); - - /* Reduce (mainly) low frequencies during harmonic emphasis */ - B[ 0 ] = psEncCtrl->GainsPre[ k ]; - B[ 1 ] = -psEncCtrl->GainsPre[ k ] * - ( psEncCtrl->HarmBoost[ k ] * HarmShapeGain + INPUT_TILT + psEncCtrl->coding_quality * HIGH_RATE_INPUT_TILT ); - pxw[ 0 ] = B[ 0 ] * st_res[ 0 ] + B[ 1 ] * P->sHarmHP; - for( j = 1; j < psEnc->sCmn.subfr_length; j++ ) { - pxw[ j ] = B[ 0 ] * st_res[ j ] + B[ 1 ] * st_res[ j - 1 ]; - } - P->sHarmHP = st_res[ psEnc->sCmn.subfr_length - 1 ]; - - silk_prefilt_FLP( P, pxw, pxw, HarmShapeFIR, Tilt, LF_MA_shp, LF_AR_shp, lag, psEnc->sCmn.subfr_length ); - - px += psEnc->sCmn.subfr_length; - pxw += psEnc->sCmn.subfr_length; - } - P->lagPrev = psEncCtrl->pitchL[ psEnc->sCmn.nb_subfr - 1 ]; -} - -/* -* Prefilter for finding Quantizer input signal -*/ -static inline void silk_prefilt_FLP( - silk_prefilter_state_FLP *P, /* I/O state */ - silk_float st_res[], /* I */ - silk_float xw[], /* O */ - silk_float *HarmShapeFIR, /* I */ - silk_float Tilt, /* I */ - silk_float LF_MA_shp, /* I */ - silk_float LF_AR_shp, /* I */ - opus_int lag, /* I */ - opus_int length /* I */ -) -{ - opus_int i; - opus_int idx, LTP_shp_buf_idx; - silk_float n_Tilt, n_LF, n_LTP; - silk_float sLF_AR_shp, sLF_MA_shp; - silk_float *LTP_shp_buf; - - /* To speed up use temp variables instead of using the struct */ - LTP_shp_buf = P->sLTP_shp; - LTP_shp_buf_idx = P->sLTP_shp_buf_idx; - sLF_AR_shp = P->sLF_AR_shp; - sLF_MA_shp = P->sLF_MA_shp; - - for( i = 0; i < length; i++ ) { - if( lag > 0 ) { - silk_assert( HARM_SHAPE_FIR_TAPS == 3 ); - idx = lag + LTP_shp_buf_idx; - n_LTP = LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 - 1) & LTP_MASK ] * HarmShapeFIR[ 0 ]; - n_LTP += LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 ) & LTP_MASK ] * HarmShapeFIR[ 1 ]; - n_LTP += LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 + 1) & LTP_MASK ] * HarmShapeFIR[ 2 ]; - } else { - n_LTP = 0; - } - - n_Tilt = sLF_AR_shp * Tilt; - n_LF = sLF_AR_shp * LF_AR_shp + sLF_MA_shp * LF_MA_shp; - - sLF_AR_shp = st_res[ i ] - n_Tilt; - sLF_MA_shp = sLF_AR_shp - n_LF; - - LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK; - LTP_shp_buf[ LTP_shp_buf_idx ] = sLF_MA_shp; - - xw[ i ] = sLF_MA_shp - n_LTP; - } - /* Copy temp variable back to state */ - P->sLF_AR_shp = sLF_AR_shp; - P->sLF_MA_shp = sLF_MA_shp; - P->sLTP_shp_buf_idx = LTP_shp_buf_idx; -} diff --git a/src/opus-1.0.2/silk/float/process_gains_FLP.c b/src/opus-1.0.2/silk/float/process_gains_FLP.c deleted file mode 100644 index d572a4cd..00000000 --- a/src/opus-1.0.2/silk/float/process_gains_FLP.c +++ /dev/null @@ -1,103 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main_FLP.h" -#include "tuning_parameters.h" - -/* Processing of gains */ -void silk_process_gains_FLP( - silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ - silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ - opus_int condCoding /* I The type of conditional coding to use */ -) -{ - silk_shape_state_FLP *psShapeSt = &psEnc->sShape; - opus_int k; - opus_int32 pGains_Q16[ MAX_NB_SUBFR ]; - silk_float s, InvMaxSqrVal, gain, quant_offset; - - /* Gain reduction when LTP coding gain is high */ - if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - s = 1.0f - 0.5f * silk_sigmoid( 0.25f * ( psEncCtrl->LTPredCodGain - 12.0f ) ); - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - psEncCtrl->Gains[ k ] *= s; - } - } - - /* Limit the quantized signal */ - InvMaxSqrVal = ( silk_float )( pow( 2.0f, 0.33f * ( 21.0f - psEnc->sCmn.SNR_dB_Q7 * ( 1 / 128.0f ) ) ) / psEnc->sCmn.subfr_length ); - - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - /* Soft limit on ratio residual energy and squared gains */ - gain = psEncCtrl->Gains[ k ]; - gain = ( silk_float )sqrt( gain * gain + psEncCtrl->ResNrg[ k ] * InvMaxSqrVal ); - psEncCtrl->Gains[ k ] = silk_min_float( gain, 32767.0f ); - } - - /* Prepare gains for noise shaping quantization */ - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - pGains_Q16[ k ] = (opus_int32)( psEncCtrl->Gains[ k ] * 65536.0f ); - } - - /* Save unquantized gains and gain Index */ - silk_memcpy( psEncCtrl->GainsUnq_Q16, pGains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) ); - psEncCtrl->lastGainIndexPrev = psShapeSt->LastGainIndex; - - /* Quantize gains */ - silk_gains_quant( psEnc->sCmn.indices.GainsIndices, pGains_Q16, - &psShapeSt->LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); - - /* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */ - for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { - psEncCtrl->Gains[ k ] = pGains_Q16[ k ] / 65536.0f; - } - - /* Set quantizer offset for voiced signals. Larger offset when LTP coding gain is low or tilt is high (ie low-pass) */ - if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { - if( psEncCtrl->LTPredCodGain + psEnc->sCmn.input_tilt_Q15 * ( 1.0f / 32768.0f ) > 1.0f ) { - psEnc->sCmn.indices.quantOffsetType = 0; - } else { - psEnc->sCmn.indices.quantOffsetType = 1; - } - } - - /* Quantizer boundary adjustment */ - quant_offset = silk_Quantization_Offsets_Q10[ psEnc->sCmn.indices.signalType >> 1 ][ psEnc->sCmn.indices.quantOffsetType ] / 1024.0f; - psEncCtrl->Lambda = LAMBDA_OFFSET - + LAMBDA_DELAYED_DECISIONS * psEnc->sCmn.nStatesDelayedDecision - + LAMBDA_SPEECH_ACT * psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f ) - + LAMBDA_INPUT_QUALITY * psEncCtrl->input_quality - + LAMBDA_CODING_QUALITY * psEncCtrl->coding_quality - + LAMBDA_QUANT_OFFSET * quant_offset; - - silk_assert( psEncCtrl->Lambda > 0.0f ); - silk_assert( psEncCtrl->Lambda < 2.0f ); -} diff --git a/src/opus-1.0.2/silk/float/regularize_correlations_FLP.c b/src/opus-1.0.2/silk/float/regularize_correlations_FLP.c deleted file mode 100644 index f5684637..00000000 --- a/src/opus-1.0.2/silk/float/regularize_correlations_FLP.c +++ /dev/null @@ -1,48 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main_FLP.h" - -/* Add noise to matrix diagonal */ -void silk_regularize_correlations_FLP( - silk_float *XX, /* I/O Correlation matrices */ - silk_float *xx, /* I/O Correlation values */ - const silk_float noise, /* I Noise energy to add */ - const opus_int D /* I Dimension of XX */ -) -{ - opus_int i; - - for( i = 0; i < D; i++ ) { - matrix_ptr( &XX[ 0 ], i, i, D ) += noise; - } - xx[ 0 ] += noise; -} diff --git a/src/opus-1.0.2/silk/float/residual_energy_FLP.c b/src/opus-1.0.2/silk/float/residual_energy_FLP.c deleted file mode 100644 index e65457ab..00000000 --- a/src/opus-1.0.2/silk/float/residual_energy_FLP.c +++ /dev/null @@ -1,117 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main_FLP.h" - -#define MAX_ITERATIONS_RESIDUAL_NRG 10 -#define REGULARIZATION_FACTOR 1e-8f - -/* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */ -silk_float silk_residual_energy_covar_FLP( /* O Weighted residual energy */ - const silk_float *c, /* I Filter coefficients */ - silk_float *wXX, /* I/O Weighted correlation matrix, reg. out */ - const silk_float *wXx, /* I Weighted correlation vector */ - const silk_float wxx, /* I Weighted correlation value */ - const opus_int D /* I Dimension */ -) -{ - opus_int i, j, k; - silk_float tmp, nrg = 0.0f, regularization; - - /* Safety checks */ - silk_assert( D >= 0 ); - - regularization = REGULARIZATION_FACTOR * ( wXX[ 0 ] + wXX[ D * D - 1 ] ); - for( k = 0; k < MAX_ITERATIONS_RESIDUAL_NRG; k++ ) { - nrg = wxx; - - tmp = 0.0f; - for( i = 0; i < D; i++ ) { - tmp += wXx[ i ] * c[ i ]; - } - nrg -= 2.0f * tmp; - - /* compute c' * wXX * c, assuming wXX is symmetric */ - for( i = 0; i < D; i++ ) { - tmp = 0.0f; - for( j = i + 1; j < D; j++ ) { - tmp += matrix_c_ptr( wXX, i, j, D ) * c[ j ]; - } - nrg += c[ i ] * ( 2.0f * tmp + matrix_c_ptr( wXX, i, i, D ) * c[ i ] ); - } - if( nrg > 0 ) { - break; - } else { - /* Add white noise */ - for( i = 0; i < D; i++ ) { - matrix_c_ptr( wXX, i, i, D ) += regularization; - } - /* Increase noise for next run */ - regularization *= 2.0f; - } - } - if( k == MAX_ITERATIONS_RESIDUAL_NRG ) { - silk_assert( nrg == 0 ); - nrg = 1.0f; - } - - return nrg; -} - -/* Calculates residual energies of input subframes where all subframes have LPC_order */ -/* of preceding samples */ -void silk_residual_energy_FLP( - silk_float nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */ - const silk_float x[], /* I Input signal */ - silk_float a[ 2 ][ MAX_LPC_ORDER ], /* I AR coefs for each frame half */ - const silk_float gains[], /* I Quantization gains */ - const opus_int subfr_length, /* I Subframe length */ - const opus_int nb_subfr, /* I number of subframes */ - const opus_int LPC_order /* I LPC order */ -) -{ - opus_int shift; - silk_float *LPC_res_ptr, LPC_res[ ( MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ) / 2 ]; - - LPC_res_ptr = LPC_res + LPC_order; - shift = LPC_order + subfr_length; - - /* Filter input to create the LPC residual for each frame half, and measure subframe energies */ - silk_LPC_analysis_filter_FLP( LPC_res, a[ 0 ], x + 0 * shift, 2 * shift, LPC_order ); - nrgs[ 0 ] = ( silk_float )( gains[ 0 ] * gains[ 0 ] * silk_energy_FLP( LPC_res_ptr + 0 * shift, subfr_length ) ); - nrgs[ 1 ] = ( silk_float )( gains[ 1 ] * gains[ 1 ] * silk_energy_FLP( LPC_res_ptr + 1 * shift, subfr_length ) ); - - if( nb_subfr == MAX_NB_SUBFR ) { - silk_LPC_analysis_filter_FLP( LPC_res, a[ 1 ], x + 2 * shift, 2 * shift, LPC_order ); - nrgs[ 2 ] = ( silk_float )( gains[ 2 ] * gains[ 2 ] * silk_energy_FLP( LPC_res_ptr + 0 * shift, subfr_length ) ); - nrgs[ 3 ] = ( silk_float )( gains[ 3 ] * gains[ 3 ] * silk_energy_FLP( LPC_res_ptr + 1 * shift, subfr_length ) ); - } -} diff --git a/src/opus-1.0.2/silk/float/scale_copy_vector_FLP.c b/src/opus-1.0.2/silk/float/scale_copy_vector_FLP.c deleted file mode 100644 index 988795a6..00000000 --- a/src/opus-1.0.2/silk/float/scale_copy_vector_FLP.c +++ /dev/null @@ -1,57 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "SigProc_FLP.h" - -/* copy and multiply a vector by a constant */ -void silk_scale_copy_vector_FLP( - silk_float *data_out, - const silk_float *data_in, - silk_float gain, - opus_int dataSize -) -{ - opus_int i, dataSize4; - - /* 4x unrolled loop */ - dataSize4 = dataSize & 0xFFFC; - for( i = 0; i < dataSize4; i += 4 ) { - data_out[ i + 0 ] = gain * data_in[ i + 0 ]; - data_out[ i + 1 ] = gain * data_in[ i + 1 ]; - data_out[ i + 2 ] = gain * data_in[ i + 2 ]; - data_out[ i + 3 ] = gain * data_in[ i + 3 ]; - } - - /* any remaining elements */ - for( ; i < dataSize; i++ ) { - data_out[ i ] = gain * data_in[ i ]; - } -} diff --git a/src/opus-1.0.2/silk/float/scale_vector_FLP.c b/src/opus-1.0.2/silk/float/scale_vector_FLP.c deleted file mode 100644 index 387eb4ba..00000000 --- a/src/opus-1.0.2/silk/float/scale_vector_FLP.c +++ /dev/null @@ -1,56 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "SigProc_FLP.h" - -/* multiply a vector by a constant */ -void silk_scale_vector_FLP( - silk_float *data1, - silk_float gain, - opus_int dataSize -) -{ - opus_int i, dataSize4; - - /* 4x unrolled loop */ - dataSize4 = dataSize & 0xFFFC; - for( i = 0; i < dataSize4; i += 4 ) { - data1[ i + 0 ] *= gain; - data1[ i + 1 ] *= gain; - data1[ i + 2 ] *= gain; - data1[ i + 3 ] *= gain; - } - - /* any remaining elements */ - for( ; i < dataSize; i++ ) { - data1[ i ] *= gain; - } -} diff --git a/src/opus-1.0.2/silk/float/schur_FLP.c b/src/opus-1.0.2/silk/float/schur_FLP.c deleted file mode 100644 index 90c3a18b..00000000 --- a/src/opus-1.0.2/silk/float/schur_FLP.c +++ /dev/null @@ -1,70 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "SigProc_FLP.h" - -silk_float silk_schur_FLP( /* O returns residual energy */ - silk_float refl_coef[], /* O reflection coefficients (length order) */ - const silk_float auto_corr[], /* I autocorrelation sequence (length order+1) */ - opus_int order /* I order */ -) -{ - opus_int k, n; - silk_float C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ]; - silk_float Ctmp1, Ctmp2, rc_tmp; - - silk_assert( order==6||order==8||order==10||order==12||order==14||order==16 ); - - /* Copy correlations */ - for( k = 0; k < order+1; k++ ) { - C[ k ][ 0 ] = C[ k ][ 1 ] = auto_corr[ k ]; - } - - for( k = 0; k < order; k++ ) { - /* Get reflection coefficient */ - rc_tmp = -C[ k + 1 ][ 0 ] / silk_max_float( C[ 0 ][ 1 ], 1e-9f ); - - /* Save the output */ - refl_coef[ k ] = rc_tmp; - - /* Update correlations */ - for( n = 0; n < order - k; n++ ) { - Ctmp1 = C[ n + k + 1 ][ 0 ]; - Ctmp2 = C[ n ][ 1 ]; - C[ n + k + 1 ][ 0 ] = Ctmp1 + Ctmp2 * rc_tmp; - C[ n ][ 1 ] = Ctmp2 + Ctmp1 * rc_tmp; - } - } - - /* Return residual energy */ - return C[ 0 ][ 1 ]; -} - diff --git a/src/opus-1.0.2/silk/float/solve_LS_FLP.c b/src/opus-1.0.2/silk/float/solve_LS_FLP.c deleted file mode 100644 index a4bb0525..00000000 --- a/src/opus-1.0.2/silk/float/solve_LS_FLP.c +++ /dev/null @@ -1,207 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main_FLP.h" -#include "tuning_parameters.h" - -/********************************************************************** - * LDL Factorisation. Finds the upper triangular matrix L and the diagonal - * Matrix D (only the diagonal elements returned in a vector)such that - * the symmetric matric A is given by A = L*D*L'. - **********************************************************************/ -static inline void silk_LDL_FLP( - silk_float *A, /* I/O Pointer to Symetric Square Matrix */ - opus_int M, /* I Size of Matrix */ - silk_float *L, /* I/O Pointer to Square Upper triangular Matrix */ - silk_float *Dinv /* I/O Pointer to vector holding the inverse diagonal elements of D */ -); - -/********************************************************************** - * Function to solve linear equation Ax = b, when A is a MxM lower - * triangular matrix, with ones on the diagonal. - **********************************************************************/ -static inline void silk_SolveWithLowerTriangularWdiagOnes_FLP( - const silk_float *L, /* I Pointer to Lower Triangular Matrix */ - opus_int M, /* I Dim of Matrix equation */ - const silk_float *b, /* I b Vector */ - silk_float *x /* O x Vector */ -); - -/********************************************************************** - * Function to solve linear equation (A^T)x = b, when A is a MxM lower - * triangular, with ones on the diagonal. (ie then A^T is upper triangular) - **********************************************************************/ -static inline void silk_SolveWithUpperTriangularFromLowerWdiagOnes_FLP( - const silk_float *L, /* I Pointer to Lower Triangular Matrix */ - opus_int M, /* I Dim of Matrix equation */ - const silk_float *b, /* I b Vector */ - silk_float *x /* O x Vector */ -); - -/********************************************************************** - * Function to solve linear equation Ax = b, when A is a MxM - * symmetric square matrix - using LDL factorisation - **********************************************************************/ -void silk_solve_LDL_FLP( - silk_float *A, /* I/O Symmetric square matrix, out: reg. */ - const opus_int M, /* I Size of matrix */ - const silk_float *b, /* I Pointer to b vector */ - silk_float *x /* O Pointer to x solution vector */ -) -{ - opus_int i; - silk_float L[ MAX_MATRIX_SIZE ][ MAX_MATRIX_SIZE ]; - silk_float T[ MAX_MATRIX_SIZE ]; - silk_float Dinv[ MAX_MATRIX_SIZE ]; /* inverse diagonal elements of D*/ - - silk_assert( M <= MAX_MATRIX_SIZE ); - - /*************************************************** - Factorize A by LDL such that A = L*D*(L^T), - where L is lower triangular with ones on diagonal - ****************************************************/ - silk_LDL_FLP( A, M, &L[ 0 ][ 0 ], Dinv ); - - /**************************************************** - * substitute D*(L^T) = T. ie: - L*D*(L^T)*x = b => L*T = b <=> T = inv(L)*b - ******************************************************/ - silk_SolveWithLowerTriangularWdiagOnes_FLP( &L[ 0 ][ 0 ], M, b, T ); - - /**************************************************** - D*(L^T)*x = T <=> (L^T)*x = inv(D)*T, because D is - diagonal just multiply with 1/d_i - ****************************************************/ - for( i = 0; i < M; i++ ) { - T[ i ] = T[ i ] * Dinv[ i ]; - } - /**************************************************** - x = inv(L') * inv(D) * T - *****************************************************/ - silk_SolveWithUpperTriangularFromLowerWdiagOnes_FLP( &L[ 0 ][ 0 ], M, T, x ); -} - -static inline void silk_SolveWithUpperTriangularFromLowerWdiagOnes_FLP( - const silk_float *L, /* I Pointer to Lower Triangular Matrix */ - opus_int M, /* I Dim of Matrix equation */ - const silk_float *b, /* I b Vector */ - silk_float *x /* O x Vector */ -) -{ - opus_int i, j; - silk_float temp; - const silk_float *ptr1; - - for( i = M - 1; i >= 0; i-- ) { - ptr1 = matrix_adr( L, 0, i, M ); - temp = 0; - for( j = M - 1; j > i ; j-- ) { - temp += ptr1[ j * M ] * x[ j ]; - } - temp = b[ i ] - temp; - x[ i ] = temp; - } -} - -static inline void silk_SolveWithLowerTriangularWdiagOnes_FLP( - const silk_float *L, /* I Pointer to Lower Triangular Matrix */ - opus_int M, /* I Dim of Matrix equation */ - const silk_float *b, /* I b Vector */ - silk_float *x /* O x Vector */ -) -{ - opus_int i, j; - silk_float temp; - const silk_float *ptr1; - - for( i = 0; i < M; i++ ) { - ptr1 = matrix_adr( L, i, 0, M ); - temp = 0; - for( j = 0; j < i; j++ ) { - temp += ptr1[ j ] * x[ j ]; - } - temp = b[ i ] - temp; - x[ i ] = temp; - } -} - -static inline void silk_LDL_FLP( - silk_float *A, /* I/O Pointer to Symetric Square Matrix */ - opus_int M, /* I Size of Matrix */ - silk_float *L, /* I/O Pointer to Square Upper triangular Matrix */ - silk_float *Dinv /* I/O Pointer to vector holding the inverse diagonal elements of D */ -) -{ - opus_int i, j, k, loop_count, err = 1; - silk_float *ptr1, *ptr2; - double temp, diag_min_value; - silk_float v[ MAX_MATRIX_SIZE ], D[ MAX_MATRIX_SIZE ]; /* temp arrays*/ - - silk_assert( M <= MAX_MATRIX_SIZE ); - - diag_min_value = FIND_LTP_COND_FAC * 0.5f * ( A[ 0 ] + A[ M * M - 1 ] ); - for( loop_count = 0; loop_count < M && err == 1; loop_count++ ) { - err = 0; - for( j = 0; j < M; j++ ) { - ptr1 = matrix_adr( L, j, 0, M ); - temp = matrix_ptr( A, j, j, M ); /* element in row j column j*/ - for( i = 0; i < j; i++ ) { - v[ i ] = ptr1[ i ] * D[ i ]; - temp -= ptr1[ i ] * v[ i ]; - } - if( temp < diag_min_value ) { - /* Badly conditioned matrix: add white noise and run again */ - temp = ( loop_count + 1 ) * diag_min_value - temp; - for( i = 0; i < M; i++ ) { - matrix_ptr( A, i, i, M ) += ( silk_float )temp; - } - err = 1; - break; - } - D[ j ] = ( silk_float )temp; - Dinv[ j ] = ( silk_float )( 1.0f / temp ); - matrix_ptr( L, j, j, M ) = 1.0f; - - ptr1 = matrix_adr( A, j, 0, M ); - ptr2 = matrix_adr( L, j + 1, 0, M); - for( i = j + 1; i < M; i++ ) { - temp = 0.0; - for( k = 0; k < j; k++ ) { - temp += ptr2[ k ] * v[ k ]; - } - matrix_ptr( L, i, j, M ) = ( silk_float )( ( ptr1[ i ] - temp ) * Dinv[ j ] ); - ptr2 += M; /* go to next column*/ - } - } - } - silk_assert( err == 0 ); -} - diff --git a/src/opus-1.0.2/silk/float/sort_FLP.c b/src/opus-1.0.2/silk/float/sort_FLP.c deleted file mode 100644 index e290c380..00000000 --- a/src/opus-1.0.2/silk/float/sort_FLP.c +++ /dev/null @@ -1,83 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* Insertion sort (fast for already almost sorted arrays): */ -/* Best case: O(n) for an already sorted array */ -/* Worst case: O(n^2) for an inversely sorted array */ - -#include "typedef.h" -#include "SigProc_FLP.h" - -void silk_insertion_sort_decreasing_FLP( - silk_float *a, /* I/O Unsorted / Sorted vector */ - opus_int *idx, /* O Index vector for the sorted elements */ - const opus_int L, /* I Vector length */ - const opus_int K /* I Number of correctly sorted positions */ -) -{ - silk_float value; - opus_int i, j; - - /* Safety checks */ - silk_assert( K > 0 ); - silk_assert( L > 0 ); - silk_assert( L >= K ); - - /* Write start indices in index vector */ - for( i = 0; i < K; i++ ) { - idx[ i ] = i; - } - - /* Sort vector elements by value, decreasing order */ - for( i = 1; i < K; i++ ) { - value = a[ i ]; - for( j = i - 1; ( j >= 0 ) && ( value > a[ j ] ); j-- ) { - a[ j + 1 ] = a[ j ]; /* Shift value */ - idx[ j + 1 ] = idx[ j ]; /* Shift index */ - } - a[ j + 1 ] = value; /* Write value */ - idx[ j + 1 ] = i; /* Write index */ - } - - /* If less than L values are asked check the remaining values, */ - /* but only spend CPU to ensure that the K first values are correct */ - for( i = K; i < L; i++ ) { - value = a[ i ]; - if( value > a[ K - 1 ] ) { - for( j = K - 2; ( j >= 0 ) && ( value > a[ j ] ); j-- ) { - a[ j + 1 ] = a[ j ]; /* Shift value */ - idx[ j + 1 ] = idx[ j ]; /* Shift index */ - } - a[ j + 1 ] = value; /* Write value */ - idx[ j + 1 ] = i; /* Write index */ - } - } -} diff --git a/src/opus-1.0.2/silk/float/structs_FLP.h b/src/opus-1.0.2/silk/float/structs_FLP.h deleted file mode 100644 index c71e7bc3..00000000 --- a/src/opus-1.0.2/silk/float/structs_FLP.h +++ /dev/null @@ -1,131 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifndef SILK_STRUCTS_FLP_H -#define SILK_STRUCTS_FLP_H - -#include "typedef.h" -#include "main.h" -#include "structs.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -/********************************/ -/* Noise shaping analysis state */ -/********************************/ -typedef struct { - opus_int8 LastGainIndex; - silk_float HarmBoost_smth; - silk_float HarmShapeGain_smth; - silk_float Tilt_smth; -} silk_shape_state_FLP; - -/********************************/ -/* Prefilter state */ -/********************************/ -typedef struct { - silk_float sLTP_shp[ LTP_BUF_LENGTH ]; - silk_float sAR_shp[ MAX_SHAPE_LPC_ORDER + 1 ]; - opus_int sLTP_shp_buf_idx; - silk_float sLF_AR_shp; - silk_float sLF_MA_shp; - silk_float sHarmHP; - opus_int32 rand_seed; - opus_int lagPrev; -} silk_prefilter_state_FLP; - -/********************************/ -/* Encoder state FLP */ -/********************************/ -typedef struct { - silk_encoder_state sCmn; /* Common struct, shared with fixed-point code */ - silk_shape_state_FLP sShape; /* Noise shaping state */ - silk_prefilter_state_FLP sPrefilt; /* Prefilter State */ - - /* Buffer for find pitch and noise shape analysis */ - silk_float x_buf[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ];/* Buffer for find pitch and noise shape analysis */ - silk_float LTPCorr; /* Normalized correlation from pitch lag estimator */ -} silk_encoder_state_FLP; - -/************************/ -/* Encoder control FLP */ -/************************/ -typedef struct { - /* Prediction and coding parameters */ - silk_float Gains[ MAX_NB_SUBFR ]; - silk_float PredCoef[ 2 ][ MAX_LPC_ORDER ]; /* holds interpolated and final coefficients */ - silk_float LTPCoef[LTP_ORDER * MAX_NB_SUBFR]; - silk_float LTP_scale; - opus_int pitchL[ MAX_NB_SUBFR ]; - - /* Noise shaping parameters */ - silk_float AR1[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ]; - silk_float AR2[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ]; - silk_float LF_MA_shp[ MAX_NB_SUBFR ]; - silk_float LF_AR_shp[ MAX_NB_SUBFR ]; - silk_float GainsPre[ MAX_NB_SUBFR ]; - silk_float HarmBoost[ MAX_NB_SUBFR ]; - silk_float Tilt[ MAX_NB_SUBFR ]; - silk_float HarmShapeGain[ MAX_NB_SUBFR ]; - silk_float Lambda; - silk_float input_quality; - silk_float coding_quality; - - /* Measures */ - silk_float sparseness; - silk_float predGain; - silk_float LTPredCodGain; - silk_float ResNrg[ MAX_NB_SUBFR ]; /* Residual energy per subframe */ - - /* Parameters for CBR mode */ - opus_int32 GainsUnq_Q16[ MAX_NB_SUBFR ]; - opus_int8 lastGainIndexPrev; -} silk_encoder_control_FLP; - -/************************/ -/* Encoder Super Struct */ -/************************/ -typedef struct { - silk_encoder_state_FLP state_Fxx[ ENCODER_NUM_CHANNELS ]; - stereo_enc_state sStereo; - opus_int32 nBitsExceeded; - opus_int nChannelsAPI; - opus_int nChannelsInternal; - opus_int nPrevChannelsInternal; - opus_int timeSinceSwitchAllowed_ms; - opus_int allowBandwidthSwitch; - opus_int prev_decode_only_middle; -} silk_encoder; - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/opus-1.0.2/silk/float/warped_autocorrelation_FLP.c b/src/opus-1.0.2/silk/float/warped_autocorrelation_FLP.c deleted file mode 100644 index e9ecc2a3..00000000 --- a/src/opus-1.0.2/silk/float/warped_autocorrelation_FLP.c +++ /dev/null @@ -1,73 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main_FLP.h" - -/* Autocorrelations for a warped frequency axis */ -void silk_warped_autocorrelation_FLP( - silk_float *corr, /* O Result [order + 1] */ - const silk_float *input, /* I Input data to correlate */ - const silk_float warping, /* I Warping coefficient */ - const opus_int length, /* I Length of input */ - const opus_int order /* I Correlation order (even) */ -) -{ - opus_int n, i; - double tmp1, tmp2; - double state[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; - double C[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; - - /* Order must be even */ - silk_assert( ( order & 1 ) == 0 ); - - /* Loop over samples */ - for( n = 0; n < length; n++ ) { - tmp1 = input[ n ]; - /* Loop over allpass sections */ - for( i = 0; i < order; i += 2 ) { - /* Output of allpass section */ - tmp2 = state[ i ] + warping * ( state[ i + 1 ] - tmp1 ); - state[ i ] = tmp1; - C[ i ] += state[ 0 ] * tmp1; - /* Output of allpass section */ - tmp1 = state[ i + 1 ] + warping * ( state[ i + 2 ] - tmp2 ); - state[ i + 1 ] = tmp2; - C[ i + 1 ] += state[ 0 ] * tmp2; - } - state[ order ] = tmp1; - C[ order ] += state[ 0 ] * tmp1; - } - - /* Copy correlations in silk_float output format */ - for( i = 0; i < order + 1; i++ ) { - corr[ i ] = ( silk_float )C[ i ]; - } -} diff --git a/src/opus-1.0.2/silk/float/wrappers_FLP.c b/src/opus-1.0.2/silk/float/wrappers_FLP.c deleted file mode 100644 index 4259e90e..00000000 --- a/src/opus-1.0.2/silk/float/wrappers_FLP.c +++ /dev/null @@ -1,200 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main_FLP.h" - -/* Wrappers. Calls flp / fix code */ - -/* Convert AR filter coefficients to NLSF parameters */ -void silk_A2NLSF_FLP( - opus_int16 *NLSF_Q15, /* O NLSF vector [ LPC_order ] */ - const silk_float *pAR, /* I LPC coefficients [ LPC_order ] */ - const opus_int LPC_order /* I LPC order */ -) -{ - opus_int i; - opus_int32 a_fix_Q16[ MAX_LPC_ORDER ]; - - for( i = 0; i < LPC_order; i++ ) { - a_fix_Q16[ i ] = silk_float2int( pAR[ i ] * 65536.0f ); - } - - silk_A2NLSF( NLSF_Q15, a_fix_Q16, LPC_order ); -} - -/* Convert LSF parameters to AR prediction filter coefficients */ -void silk_NLSF2A_FLP( - silk_float *pAR, /* O LPC coefficients [ LPC_order ] */ - const opus_int16 *NLSF_Q15, /* I NLSF vector [ LPC_order ] */ - const opus_int LPC_order /* I LPC order */ -) -{ - opus_int i; - opus_int16 a_fix_Q12[ MAX_LPC_ORDER ]; - - silk_NLSF2A( a_fix_Q12, NLSF_Q15, LPC_order ); - - for( i = 0; i < LPC_order; i++ ) { - pAR[ i ] = ( silk_float )a_fix_Q12[ i ] * ( 1.0f / 4096.0f ); - } -} - -/******************************************/ -/* Floating-point NLSF processing wrapper */ -/******************************************/ -void silk_process_NLSFs_FLP( - silk_encoder_state *psEncC, /* I/O Encoder state */ - silk_float PredCoef[ 2 ][ MAX_LPC_ORDER ], /* O Prediction coefficients */ - opus_int16 NLSF_Q15[ MAX_LPC_ORDER ], /* I/O Normalized LSFs (quant out) (0 - (2^15-1)) */ - const opus_int16 prev_NLSF_Q15[ MAX_LPC_ORDER ] /* I Previous Normalized LSFs (0 - (2^15-1)) */ -) -{ - opus_int i, j; - opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ]; - - silk_process_NLSFs( psEncC, PredCoef_Q12, NLSF_Q15, prev_NLSF_Q15); - - for( j = 0; j < 2; j++ ) { - for( i = 0; i < psEncC->predictLPCOrder; i++ ) { - PredCoef[ j ][ i ] = ( silk_float )PredCoef_Q12[ j ][ i ] * ( 1.0f / 4096.0f ); - } - } -} - -/****************************************/ -/* Floating-point Silk NSQ wrapper */ -/****************************************/ -void silk_NSQ_wrapper_FLP( - silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ - silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ - SideInfoIndices *psIndices, /* I/O Quantization indices */ - silk_nsq_state *psNSQ, /* I/O Noise Shaping Quantzation state */ - opus_int8 pulses[], /* O Quantized pulse signal */ - const silk_float x[] /* I Prefiltered input signal */ -) -{ - opus_int i, j; - opus_int32 x_Q3[ MAX_FRAME_LENGTH ]; - opus_int32 Gains_Q16[ MAX_NB_SUBFR ]; - silk_DWORD_ALIGN opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ]; - opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ]; - opus_int LTP_scale_Q14; - - /* Noise shaping parameters */ - opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ]; - opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ]; /* Packs two int16 coefficients per int32 value */ - opus_int Lambda_Q10; - opus_int Tilt_Q14[ MAX_NB_SUBFR ]; - opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ]; - - /* Convert control struct to fix control struct */ - /* Noise shape parameters */ - for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { - for( j = 0; j < psEnc->sCmn.shapingLPCOrder; j++ ) { - AR2_Q13[ i * MAX_SHAPE_LPC_ORDER + j ] = silk_float2int( psEncCtrl->AR2[ i * MAX_SHAPE_LPC_ORDER + j ] * 8192.0f ); - } - } - - for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { - LF_shp_Q14[ i ] = silk_LSHIFT32( silk_float2int( psEncCtrl->LF_AR_shp[ i ] * 16384.0f ), 16 ) | - (opus_uint16)silk_float2int( psEncCtrl->LF_MA_shp[ i ] * 16384.0f ); - Tilt_Q14[ i ] = (opus_int)silk_float2int( psEncCtrl->Tilt[ i ] * 16384.0f ); - HarmShapeGain_Q14[ i ] = (opus_int)silk_float2int( psEncCtrl->HarmShapeGain[ i ] * 16384.0f ); - } - Lambda_Q10 = ( opus_int )silk_float2int( psEncCtrl->Lambda * 1024.0f ); - - /* prediction and coding parameters */ - for( i = 0; i < psEnc->sCmn.nb_subfr * LTP_ORDER; i++ ) { - LTPCoef_Q14[ i ] = (opus_int16)silk_float2int( psEncCtrl->LTPCoef[ i ] * 16384.0f ); - } - - for( j = 0; j < 2; j++ ) { - for( i = 0; i < psEnc->sCmn.predictLPCOrder; i++ ) { - PredCoef_Q12[ j ][ i ] = (opus_int16)silk_float2int( psEncCtrl->PredCoef[ j ][ i ] * 4096.0f ); - } - } - - for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { - Gains_Q16[ i ] = silk_float2int( psEncCtrl->Gains[ i ] * 65536.0f ); - silk_assert( Gains_Q16[ i ] > 0 ); - } - - if( psIndices->signalType == TYPE_VOICED ) { - LTP_scale_Q14 = silk_LTPScales_table_Q14[ psIndices->LTP_scaleIndex ]; - } else { - LTP_scale_Q14 = 0; - } - - /* Convert input to fix */ - for( i = 0; i < psEnc->sCmn.frame_length; i++ ) { - x_Q3[ i ] = silk_float2int( 8.0f * x[ i ] ); - } - - /* Call NSQ */ - if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) { - silk_NSQ_del_dec( &psEnc->sCmn, psNSQ, psIndices, x_Q3, pulses, PredCoef_Q12[ 0 ], LTPCoef_Q14, - AR2_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, psEncCtrl->pitchL, Lambda_Q10, LTP_scale_Q14 ); - } else { - silk_NSQ( &psEnc->sCmn, psNSQ, psIndices, x_Q3, pulses, PredCoef_Q12[ 0 ], LTPCoef_Q14, - AR2_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, psEncCtrl->pitchL, Lambda_Q10, LTP_scale_Q14 ); - } -} - -/***********************************************/ -/* Floating-point Silk LTP quantiation wrapper */ -/***********************************************/ -void silk_quant_LTP_gains_FLP( - silk_float B[ MAX_NB_SUBFR * LTP_ORDER ], /* I/O (Un-)quantized LTP gains */ - opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook index */ - opus_int8 *periodicity_index, /* O Periodicity index */ - const silk_float W[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* I Error weights */ - const opus_int mu_Q10, /* I Mu value (R/D tradeoff) */ - const opus_int lowComplexity, /* I Flag for low complexity */ - const opus_int nb_subfr /* I number of subframes */ -) -{ - opus_int i; - opus_int16 B_Q14[ MAX_NB_SUBFR * LTP_ORDER ]; - opus_int32 W_Q18[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ]; - - for( i = 0; i < nb_subfr * LTP_ORDER; i++ ) { - B_Q14[ i ] = (opus_int16)silk_float2int( B[ i ] * 16384.0f ); - } - for( i = 0; i < nb_subfr * LTP_ORDER * LTP_ORDER; i++ ) { - W_Q18[ i ] = (opus_int32)silk_float2int( W[ i ] * 262144.0f ); - } - - silk_quant_LTP_gains( B_Q14, cbk_index, periodicity_index, W_Q18, mu_Q10, lowComplexity, nb_subfr ); - - for( i = 0; i < nb_subfr * LTP_ORDER; i++ ) { - B[ i ] = (silk_float)B_Q14[ i ] * ( 1.0f / 16384.0f ); - } -} diff --git a/src/opus-1.0.2/silk/gain_quant.c b/src/opus-1.0.2/silk/gain_quant.c deleted file mode 100644 index b2f73735..00000000 --- a/src/opus-1.0.2/silk/gain_quant.c +++ /dev/null @@ -1,141 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main.h" - -#define OFFSET ( ( MIN_QGAIN_DB * 128 ) / 6 + 16 * 128 ) -#define SCALE_Q16 ( ( 65536 * ( N_LEVELS_QGAIN - 1 ) ) / ( ( ( MAX_QGAIN_DB - MIN_QGAIN_DB ) * 128 ) / 6 ) ) -#define INV_SCALE_Q16 ( ( 65536 * ( ( ( MAX_QGAIN_DB - MIN_QGAIN_DB ) * 128 ) / 6 ) ) / ( N_LEVELS_QGAIN - 1 ) ) - -/* Gain scalar quantization with hysteresis, uniform on log scale */ -void silk_gains_quant( - opus_int8 ind[ MAX_NB_SUBFR ], /* O gain indices */ - opus_int32 gain_Q16[ MAX_NB_SUBFR ], /* I/O gains (quantized out) */ - opus_int8 *prev_ind, /* I/O last index in previous frame */ - const opus_int conditional, /* I first gain is delta coded if 1 */ - const opus_int nb_subfr /* I number of subframes */ -) -{ - opus_int k, double_step_size_threshold; - - for( k = 0; k < nb_subfr; k++ ) { - /* Convert to log scale, scale, floor() */ - ind[ k ] = silk_SMULWB( SCALE_Q16, silk_lin2log( gain_Q16[ k ] ) - OFFSET ); - - /* Round towards previous quantized gain (hysteresis) */ - if( ind[ k ] < *prev_ind ) { - ind[ k ]++; - } - ind[ k ] = silk_LIMIT_int( ind[ k ], 0, N_LEVELS_QGAIN - 1 ); - - /* Compute delta indices and limit */ - if( k == 0 && conditional == 0 ) { - /* Full index */ - ind[ k ] = silk_LIMIT_int( ind[ k ], *prev_ind + MIN_DELTA_GAIN_QUANT, N_LEVELS_QGAIN - 1 ); - *prev_ind = ind[ k ]; - } else { - /* Delta index */ - ind[ k ] = ind[ k ] - *prev_ind; - - /* Double the quantization step size for large gain increases, so that the max gain level can be reached */ - double_step_size_threshold = 2 * MAX_DELTA_GAIN_QUANT - N_LEVELS_QGAIN + *prev_ind; - if( ind[ k ] > double_step_size_threshold ) { - ind[ k ] = double_step_size_threshold + silk_RSHIFT( ind[ k ] - double_step_size_threshold + 1, 1 ); - } - - ind[ k ] = silk_LIMIT_int( ind[ k ], MIN_DELTA_GAIN_QUANT, MAX_DELTA_GAIN_QUANT ); - - /* Accumulate deltas */ - if( ind[ k ] > double_step_size_threshold ) { - *prev_ind += silk_LSHIFT( ind[ k ], 1 ) - double_step_size_threshold; - } else { - *prev_ind += ind[ k ]; - } - - /* Shift to make non-negative */ - ind[ k ] -= MIN_DELTA_GAIN_QUANT; - } - - /* Scale and convert to linear scale */ - gain_Q16[ k ] = silk_log2lin( silk_min_32( silk_SMULWB( INV_SCALE_Q16, *prev_ind ) + OFFSET, 3967 ) ); /* 3967 = 31 in Q7 */ - } -} - -/* Gains scalar dequantization, uniform on log scale */ -void silk_gains_dequant( - opus_int32 gain_Q16[ MAX_NB_SUBFR ], /* O quantized gains */ - const opus_int8 ind[ MAX_NB_SUBFR ], /* I gain indices */ - opus_int8 *prev_ind, /* I/O last index in previous frame */ - const opus_int conditional, /* I first gain is delta coded if 1 */ - const opus_int nb_subfr /* I number of subframes */ -) -{ - opus_int k, ind_tmp, double_step_size_threshold; - - for( k = 0; k < nb_subfr; k++ ) { - if( k == 0 && conditional == 0 ) { - /* Gain index is not allowed to go down more than 16 steps (~21.8 dB) */ - *prev_ind = silk_max_int( ind[ k ], *prev_ind - 16 ); - } else { - /* Delta index */ - ind_tmp = ind[ k ] + MIN_DELTA_GAIN_QUANT; - - /* Accumulate deltas */ - double_step_size_threshold = 2 * MAX_DELTA_GAIN_QUANT - N_LEVELS_QGAIN + *prev_ind; - if( ind_tmp > double_step_size_threshold ) { - *prev_ind += silk_LSHIFT( ind_tmp, 1 ) - double_step_size_threshold; - } else { - *prev_ind += ind_tmp; - } - } - *prev_ind = silk_LIMIT_int( *prev_ind, 0, N_LEVELS_QGAIN - 1 ); - - /* Scale and convert to linear scale */ - gain_Q16[ k ] = silk_log2lin( silk_min_32( silk_SMULWB( INV_SCALE_Q16, *prev_ind ) + OFFSET, 3967 ) ); /* 3967 = 31 in Q7 */ - } -} - -/* Compute unique identifier of gain indices vector */ -opus_int32 silk_gains_ID( /* O returns unique identifier of gains */ - const opus_int8 ind[ MAX_NB_SUBFR ], /* I gain indices */ - const opus_int nb_subfr /* I number of subframes */ -) -{ - opus_int k; - opus_int32 gainsID; - - gainsID = 0; - for( k = 0; k < nb_subfr; k++ ) { - gainsID = silk_ADD_LSHIFT32( ind[ k ], gainsID, 8 ); - } - - return gainsID; -} diff --git a/src/opus-1.0.2/silk/init_decoder.c b/src/opus-1.0.2/silk/init_decoder.c deleted file mode 100644 index 47834890..00000000 --- a/src/opus-1.0.2/silk/init_decoder.c +++ /dev/null @@ -1,56 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main.h" - -/************************/ -/* Init Decoder State */ -/************************/ -opus_int silk_init_decoder( - silk_decoder_state *psDec /* I/O Decoder state pointer */ -) -{ - /* Clear the entire encoder state, except anything copied */ - silk_memset( psDec, 0, sizeof( silk_decoder_state ) ); - - /* Used to deactivate LSF interpolation */ - psDec->first_frame_after_reset = 1; - psDec->prev_gain_Q16 = 65536; - - /* Reset CNG state */ - silk_CNG_Reset( psDec ); - - /* Reset PLC state */ - silk_PLC_Reset( psDec ); - - return(0); -} - diff --git a/src/opus-1.0.2/silk/init_encoder.c b/src/opus-1.0.2/silk/init_encoder.c deleted file mode 100644 index fe3fe968..00000000 --- a/src/opus-1.0.2/silk/init_encoder.c +++ /dev/null @@ -1,60 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#ifdef FIXED_POINT -#include "main_FIX.h" -#else -#include "main_FLP.h" -#endif -#include "tuning_parameters.h" - -/*********************************/ -/* Initialize Silk Encoder state */ -/*********************************/ -opus_int silk_init_encoder( - silk_encoder_state_Fxx *psEnc /* I/O Pointer to Silk FIX encoder state */ -) -{ - opus_int ret = 0; - - /* Clear the entire encoder state */ - silk_memset( psEnc, 0, sizeof( silk_encoder_state_Fxx ) ); - - psEnc->sCmn.variable_HP_smth1_Q15 = silk_LSHIFT( silk_lin2log( SILK_FIX_CONST( VARIABLE_HP_MIN_CUTOFF_HZ, 16 ) ) - ( 16 << 7 ), 8 ); - psEnc->sCmn.variable_HP_smth2_Q15 = psEnc->sCmn.variable_HP_smth1_Q15; - - /* Used to deactivate LSF interpolation, pitch prediction */ - psEnc->sCmn.first_frame_after_reset = 1; - - /* Initialize Silk VAD */ - ret += silk_VAD_Init( &psEnc->sCmn.sVAD ); - - return ret; -} diff --git a/src/opus-1.0.2/silk/inner_prod_aligned.c b/src/opus-1.0.2/silk/inner_prod_aligned.c deleted file mode 100644 index fe20a2b1..00000000 --- a/src/opus-1.0.2/silk/inner_prod_aligned.c +++ /dev/null @@ -1,47 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "SigProc_FIX.h" - -opus_int32 silk_inner_prod_aligned_scale( - const opus_int16 *const inVec1, /* I input vector 1 */ - const opus_int16 *const inVec2, /* I input vector 2 */ - const opus_int scale, /* I number of bits to shift */ - const opus_int len /* I vector lengths */ -) -{ - opus_int i; - opus_int32 sum = 0; - for( i = 0; i < len; i++ ) { - sum = silk_ADD_RSHIFT32( sum, silk_SMULBB( inVec1[ i ], inVec2[ i ] ), scale ); - } - return sum; -} diff --git a/src/opus-1.0.2/silk/interpolate.c b/src/opus-1.0.2/silk/interpolate.c deleted file mode 100644 index 226488b9..00000000 --- a/src/opus-1.0.2/silk/interpolate.c +++ /dev/null @@ -1,51 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main.h" - -/* Interpolate two vectors */ -void silk_interpolate( - opus_int16 xi[ MAX_LPC_ORDER ], /* O interpolated vector */ - const opus_int16 x0[ MAX_LPC_ORDER ], /* I first vector */ - const opus_int16 x1[ MAX_LPC_ORDER ], /* I second vector */ - const opus_int ifact_Q2, /* I interp. factor, weight on 2nd vector */ - const opus_int d /* I number of parameters */ -) -{ - opus_int i; - - silk_assert( ifact_Q2 >= 0 ); - silk_assert( ifact_Q2 <= 4 ); - - for( i = 0; i < d; i++ ) { - xi[ i ] = (opus_int16)silk_ADD_RSHIFT( x0[ i ], silk_SMULBB( x1[ i ] - x0[ i ], ifact_Q2 ), 2 ); - } -} diff --git a/src/opus-1.0.2/silk/lin2log.c b/src/opus-1.0.2/silk/lin2log.c deleted file mode 100644 index 212b670d..00000000 --- a/src/opus-1.0.2/silk/lin2log.c +++ /dev/null @@ -1,46 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "SigProc_FIX.h" -/* Approximation of 128 * log2() (very close inverse of silk_log2lin()) */ -/* Convert input to a log scale */ -opus_int32 silk_lin2log( - const opus_int32 inLin /* I input in linear scale */ -) -{ - opus_int32 lz, frac_Q7; - - silk_CLZ_FRAC( inLin, &lz, &frac_Q7 ); - - /* Piece-wise parabolic approximation */ - return silk_LSHIFT( 31 - lz, 7 ) + silk_SMLAWB( frac_Q7, silk_MUL( frac_Q7, 128 - frac_Q7 ), 179 ); -} - diff --git a/src/opus-1.0.2/silk/log2lin.c b/src/opus-1.0.2/silk/log2lin.c deleted file mode 100644 index 33a19ad1..00000000 --- a/src/opus-1.0.2/silk/log2lin.c +++ /dev/null @@ -1,56 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "SigProc_FIX.h" - -/* Approximation of 2^() (very close inverse of silk_lin2log()) */ -/* Convert input to a linear scale */ -opus_int32 silk_log2lin( - const opus_int32 inLog_Q7 /* I input on log scale */ -) -{ - opus_int32 out, frac_Q7; - - if( inLog_Q7 < 0 ) { - return 0; - } - - out = silk_LSHIFT( 1, silk_RSHIFT( inLog_Q7, 7 ) ); - frac_Q7 = inLog_Q7 & 0x7F; - if( inLog_Q7 < 2048 ) { - /* Piece-wise parabolic approximation */ - out = silk_ADD_RSHIFT32( out, silk_MUL( out, silk_SMLAWB( frac_Q7, silk_SMULBB( frac_Q7, 128 - frac_Q7 ), -174 ) ), 7 ); - } else { - /* Piece-wise parabolic approximation */ - out = silk_MLA( out, silk_RSHIFT( out, 7 ), silk_SMLAWB( frac_Q7, silk_SMULBB( frac_Q7, 128 - frac_Q7 ), -174 ) ); - } - return out; -} diff --git a/src/opus-1.0.2/silk/macros.h b/src/opus-1.0.2/silk/macros.h deleted file mode 100644 index 2612fc7a..00000000 --- a/src/opus-1.0.2/silk/macros.h +++ /dev/null @@ -1,135 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifndef SILK_MACROS_H -#define SILK_MACROS_H - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* This is an inline header file for general platform. */ - -/* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */ -#define silk_SMULWB(a32, b32) ((((a32) >> 16) * (opus_int32)((opus_int16)(b32))) + ((((a32) & 0x0000FFFF) * (opus_int32)((opus_int16)(b32))) >> 16)) - -/* a32 + (b32 * (opus_int32)((opus_int16)(c32))) >> 16 output have to be 32bit int */ -#define silk_SMLAWB(a32, b32, c32) ((a32) + ((((b32) >> 16) * (opus_int32)((opus_int16)(c32))) + ((((b32) & 0x0000FFFF) * (opus_int32)((opus_int16)(c32))) >> 16))) - -/* (a32 * (b32 >> 16)) >> 16 */ -#define silk_SMULWT(a32, b32) (((a32) >> 16) * ((b32) >> 16) + ((((a32) & 0x0000FFFF) * ((b32) >> 16)) >> 16)) - -/* a32 + (b32 * (c32 >> 16)) >> 16 */ -#define silk_SMLAWT(a32, b32, c32) ((a32) + (((b32) >> 16) * ((c32) >> 16)) + ((((b32) & 0x0000FFFF) * ((c32) >> 16)) >> 16)) - -/* (opus_int32)((opus_int16)(a3))) * (opus_int32)((opus_int16)(b32)) output have to be 32bit int */ -#define silk_SMULBB(a32, b32) ((opus_int32)((opus_int16)(a32)) * (opus_int32)((opus_int16)(b32))) - -/* a32 + (opus_int32)((opus_int16)(b32)) * (opus_int32)((opus_int16)(c32)) output have to be 32bit int */ -#define silk_SMLABB(a32, b32, c32) ((a32) + ((opus_int32)((opus_int16)(b32))) * (opus_int32)((opus_int16)(c32))) - -/* (opus_int32)((opus_int16)(a32)) * (b32 >> 16) */ -#define silk_SMULBT(a32, b32) ((opus_int32)((opus_int16)(a32)) * ((b32) >> 16)) - -/* a32 + (opus_int32)((opus_int16)(b32)) * (c32 >> 16) */ -#define silk_SMLABT(a32, b32, c32) ((a32) + ((opus_int32)((opus_int16)(b32))) * ((c32) >> 16)) - -/* a64 + (b32 * c32) */ -#define silk_SMLAL(a64, b32, c32) (silk_ADD64((a64), ((opus_int64)(b32) * (opus_int64)(c32)))) - -/* (a32 * b32) >> 16 */ -#define silk_SMULWW(a32, b32) silk_MLA(silk_SMULWB((a32), (b32)), (a32), silk_RSHIFT_ROUND((b32), 16)) - -/* a32 + ((b32 * c32) >> 16) */ -#define silk_SMLAWW(a32, b32, c32) silk_MLA(silk_SMLAWB((a32), (b32), (c32)), (b32), silk_RSHIFT_ROUND((c32), 16)) - -/* add/subtract with output saturated */ -#define silk_ADD_SAT32(a, b) ((((opus_uint32)(a) + (opus_uint32)(b)) & 0x80000000) == 0 ? \ - ((((a) & (b)) & 0x80000000) != 0 ? silk_int32_MIN : (a)+(b)) : \ - ((((a) | (b)) & 0x80000000) == 0 ? silk_int32_MAX : (a)+(b)) ) - -#define silk_SUB_SAT32(a, b) ((((opus_uint32)(a)-(opus_uint32)(b)) & 0x80000000) == 0 ? \ - (( (a) & ((b)^0x80000000) & 0x80000000) ? silk_int32_MIN : (a)-(b)) : \ - ((((a)^0x80000000) & (b) & 0x80000000) ? silk_int32_MAX : (a)-(b)) ) - -static inline opus_int32 silk_CLZ16(opus_int16 in16) -{ - opus_int32 out32 = 0; - if( in16 == 0 ) { - return 16; - } - /* test nibbles */ - if( in16 & 0xFF00 ) { - if( in16 & 0xF000 ) { - in16 >>= 12; - } else { - out32 += 4; - in16 >>= 8; - } - } else { - if( in16 & 0xFFF0 ) { - out32 += 8; - in16 >>= 4; - } else { - out32 += 12; - } - } - /* test bits and return */ - if( in16 & 0xC ) { - if( in16 & 0x8 ) - return out32 + 0; - else - return out32 + 1; - } else { - if( in16 & 0xE ) - return out32 + 2; - else - return out32 + 3; - } -} - -static inline opus_int32 silk_CLZ32(opus_int32 in32) -{ - /* test highest 16 bits and convert to opus_int16 */ - if( in32 & 0xFFFF0000 ) { - return silk_CLZ16((opus_int16)(in32 >> 16)); - } else { - return silk_CLZ16((opus_int16)in32) + 16; - } -} - -/* Row based */ -#define matrix_ptr(Matrix_base_adr, row, column, N) *(Matrix_base_adr + ((row)*(N)+(column))) -#define matrix_adr(Matrix_base_adr, row, column, N) (Matrix_base_adr + ((row)*(N)+(column))) - -/* Column based */ -#ifndef matrix_c_ptr -# define matrix_c_ptr(Matrix_base_adr, row, column, M) *(Matrix_base_adr + ((row)+(M)*(column))) -#endif - -#endif /* SILK_MACROS_H */ - diff --git a/src/opus-1.0.2/silk/main.h b/src/opus-1.0.2/silk/main.h deleted file mode 100644 index 32675f69..00000000 --- a/src/opus-1.0.2/silk/main.h +++ /dev/null @@ -1,434 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifndef SILK_MAIN_H -#define SILK_MAIN_H - -#include "SigProc_FIX.h" -#include "define.h" -#include "structs.h" -#include "tables.h" -#include "PLC.h" -#include "control.h" -#include "debug.h" -#include "entenc.h" -#include "entdec.h" - -/* Convert Left/Right stereo signal to adaptive Mid/Side representation */ -void silk_stereo_LR_to_MS( - stereo_enc_state *state, /* I/O State */ - opus_int16 x1[], /* I/O Left input signal, becomes mid signal */ - opus_int16 x2[], /* I/O Right input signal, becomes side signal */ - opus_int8 ix[ 2 ][ 3 ], /* O Quantization indices */ - opus_int8 *mid_only_flag, /* O Flag: only mid signal coded */ - opus_int32 mid_side_rates_bps[], /* O Bitrates for mid and side signals */ - opus_int32 total_rate_bps, /* I Total bitrate */ - opus_int prev_speech_act_Q8, /* I Speech activity level in previous frame */ - opus_int toMono, /* I Last frame before a stereo->mono transition */ - opus_int fs_kHz, /* I Sample rate (kHz) */ - opus_int frame_length /* I Number of samples */ -); - -/* Convert adaptive Mid/Side representation to Left/Right stereo signal */ -void silk_stereo_MS_to_LR( - stereo_dec_state *state, /* I/O State */ - opus_int16 x1[], /* I/O Left input signal, becomes mid signal */ - opus_int16 x2[], /* I/O Right input signal, becomes side signal */ - const opus_int32 pred_Q13[], /* I Predictors */ - opus_int fs_kHz, /* I Samples rate (kHz) */ - opus_int frame_length /* I Number of samples */ -); - -/* Find least-squares prediction gain for one signal based on another and quantize it */ -opus_int32 silk_stereo_find_predictor( /* O Returns predictor in Q13 */ - opus_int32 *ratio_Q14, /* O Ratio of residual and mid energies */ - const opus_int16 x[], /* I Basis signal */ - const opus_int16 y[], /* I Target signal */ - opus_int32 mid_res_amp_Q0[], /* I/O Smoothed mid, residual norms */ - opus_int length, /* I Number of samples */ - opus_int smooth_coef_Q16 /* I Smoothing coefficient */ -); - -/* Quantize mid/side predictors */ -void silk_stereo_quant_pred( - opus_int32 pred_Q13[], /* I/O Predictors (out: quantized) */ - opus_int8 ix[ 2 ][ 3 ] /* O Quantization indices */ -); - -/* Entropy code the mid/side quantization indices */ -void silk_stereo_encode_pred( - ec_enc *psRangeEnc, /* I/O Compressor data structure */ - opus_int8 ix[ 2 ][ 3 ] /* I Quantization indices */ -); - -/* Entropy code the mid-only flag */ -void silk_stereo_encode_mid_only( - ec_enc *psRangeEnc, /* I/O Compressor data structure */ - opus_int8 mid_only_flag -); - -/* Decode mid/side predictors */ -void silk_stereo_decode_pred( - ec_dec *psRangeDec, /* I/O Compressor data structure */ - opus_int32 pred_Q13[] /* O Predictors */ -); - -/* Decode mid-only flag */ -void silk_stereo_decode_mid_only( - ec_dec *psRangeDec, /* I/O Compressor data structure */ - opus_int *decode_only_mid /* O Flag that only mid channel has been coded */ -); - -/* Encodes signs of excitation */ -void silk_encode_signs( - ec_enc *psRangeEnc, /* I/O Compressor data structure */ - const opus_int8 pulses[], /* I pulse signal */ - opus_int length, /* I length of input */ - const opus_int signalType, /* I Signal type */ - const opus_int quantOffsetType, /* I Quantization offset type */ - const opus_int sum_pulses[ MAX_NB_SHELL_BLOCKS ] /* I Sum of absolute pulses per block */ -); - -/* Decodes signs of excitation */ -void silk_decode_signs( - ec_dec *psRangeDec, /* I/O Compressor data structure */ - opus_int pulses[], /* I/O pulse signal */ - opus_int length, /* I length of input */ - const opus_int signalType, /* I Signal type */ - const opus_int quantOffsetType, /* I Quantization offset type */ - const opus_int sum_pulses[ MAX_NB_SHELL_BLOCKS ] /* I Sum of absolute pulses per block */ -); - -/* Check encoder control struct */ -opus_int check_control_input( - silk_EncControlStruct *encControl /* I Control structure */ -); - -/* Control internal sampling rate */ -opus_int silk_control_audio_bandwidth( - silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */ - silk_EncControlStruct *encControl /* I Control structure */ -); - -/* Control SNR of redidual quantizer */ -opus_int silk_control_SNR( - silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */ - opus_int32 TargetRate_bps /* I Target max bitrate (bps) */ -); - -/***************/ -/* Shell coder */ -/***************/ - -/* Encode quantization indices of excitation */ -void silk_encode_pulses( - ec_enc *psRangeEnc, /* I/O compressor data structure */ - const opus_int signalType, /* I Signal type */ - const opus_int quantOffsetType, /* I quantOffsetType */ - opus_int8 pulses[], /* I quantization indices */ - const opus_int frame_length /* I Frame length */ -); - -/* Shell encoder, operates on one shell code frame of 16 pulses */ -void silk_shell_encoder( - ec_enc *psRangeEnc, /* I/O compressor data structure */ - const opus_int *pulses0 /* I data: nonnegative pulse amplitudes */ -); - -/* Shell decoder, operates on one shell code frame of 16 pulses */ -void silk_shell_decoder( - opus_int *pulses0, /* O data: nonnegative pulse amplitudes */ - ec_dec *psRangeDec, /* I/O Compressor data structure */ - const opus_int pulses4 /* I number of pulses per pulse-subframe */ -); - -/* Gain scalar quantization with hysteresis, uniform on log scale */ -void silk_gains_quant( - opus_int8 ind[ MAX_NB_SUBFR ], /* O gain indices */ - opus_int32 gain_Q16[ MAX_NB_SUBFR ], /* I/O gains (quantized out) */ - opus_int8 *prev_ind, /* I/O last index in previous frame */ - const opus_int conditional, /* I first gain is delta coded if 1 */ - const opus_int nb_subfr /* I number of subframes */ -); - -/* Gains scalar dequantization, uniform on log scale */ -void silk_gains_dequant( - opus_int32 gain_Q16[ MAX_NB_SUBFR ], /* O quantized gains */ - const opus_int8 ind[ MAX_NB_SUBFR ], /* I gain indices */ - opus_int8 *prev_ind, /* I/O last index in previous frame */ - const opus_int conditional, /* I first gain is delta coded if 1 */ - const opus_int nb_subfr /* I number of subframes */ -); - -/* Compute unique identifier of gain indices vector */ -opus_int32 silk_gains_ID( /* O returns unique identifier of gains */ - const opus_int8 ind[ MAX_NB_SUBFR ], /* I gain indices */ - const opus_int nb_subfr /* I number of subframes */ -); - -/* Interpolate two vectors */ -void silk_interpolate( - opus_int16 xi[ MAX_LPC_ORDER ], /* O interpolated vector */ - const opus_int16 x0[ MAX_LPC_ORDER ], /* I first vector */ - const opus_int16 x1[ MAX_LPC_ORDER ], /* I second vector */ - const opus_int ifact_Q2, /* I interp. factor, weight on 2nd vector */ - const opus_int d /* I number of parameters */ -); - -/* LTP tap quantizer */ -void silk_quant_LTP_gains( - opus_int16 B_Q14[ MAX_NB_SUBFR * LTP_ORDER ], /* I/O (un)quantized LTP gains */ - opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook Index */ - opus_int8 *periodicity_index, /* O Periodicity Index */ - const opus_int32 W_Q18[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ], /* I Error Weights in Q18 */ - opus_int mu_Q9, /* I Mu value (R/D tradeoff) */ - opus_int lowComplexity, /* I Flag for low complexity */ - const opus_int nb_subfr /* I number of subframes */ -); - -/* Entropy constrained matrix-weighted VQ, for a single input data vector */ -void silk_VQ_WMat_EC( - opus_int8 *ind, /* O index of best codebook vector */ - opus_int32 *rate_dist_Q14, /* O best weighted quant error + mu * rate */ - const opus_int16 *in_Q14, /* I input vector to be quantized */ - const opus_int32 *W_Q18, /* I weighting matrix */ - const opus_int8 *cb_Q7, /* I codebook */ - const opus_uint8 *cl_Q5, /* I code length for each codebook vector */ - const opus_int mu_Q9, /* I tradeoff betw. weighted error and rate */ - opus_int L /* I number of vectors in codebook */ -); - -/************************************/ -/* Noise shaping quantization (NSQ) */ -/************************************/ -void silk_NSQ( - const silk_encoder_state *psEncC, /* I/O Encoder State */ - silk_nsq_state *NSQ, /* I/O NSQ state */ - SideInfoIndices *psIndices, /* I/O Quantization Indices */ - const opus_int32 x_Q3[], /* I Prefiltered input signal */ - opus_int8 pulses[], /* O Quantized pulse signal */ - const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ - const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ - const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ - const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ - const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ - const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ - const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ - const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ - const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ - const opus_int LTP_scale_Q14 /* I LTP state scaling */ -); - -/* Noise shaping using delayed decision */ -void silk_NSQ_del_dec( - const silk_encoder_state *psEncC, /* I/O Encoder State */ - silk_nsq_state *NSQ, /* I/O NSQ state */ - SideInfoIndices *psIndices, /* I/O Quantization Indices */ - const opus_int32 x_Q3[], /* I Prefiltered input signal */ - opus_int8 pulses[], /* O Quantized pulse signal */ - const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ - const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ - const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ - const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ - const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ - const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ - const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ - const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ - const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ - const opus_int LTP_scale_Q14 /* I LTP state scaling */ -); - -/************/ -/* Silk VAD */ -/************/ -/* Initialize the Silk VAD */ -opus_int silk_VAD_Init( /* O Return value, 0 if success */ - silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */ -); - -/* Get speech activity level in Q8 */ -opus_int silk_VAD_GetSA_Q8( /* O Return value, 0 if success */ - silk_encoder_state *psEncC, /* I/O Encoder state */ - const opus_int16 pIn[] /* I PCM input */ -); - -/* Low-pass filter with variable cutoff frequency based on */ -/* piece-wise linear interpolation between elliptic filters */ -/* Start by setting transition_frame_no = 1; */ -void silk_LP_variable_cutoff( - silk_LP_state *psLP, /* I/O LP filter state */ - opus_int16 *frame, /* I/O Low-pass filtered output signal */ - const opus_int frame_length /* I Frame length */ -); - -/******************/ -/* NLSF Quantizer */ -/******************/ -/* Limit, stabilize, convert and quantize NLSFs */ -void silk_process_NLSFs( - silk_encoder_state *psEncC, /* I/O Encoder state */ - opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ], /* O Prediction coefficients */ - opus_int16 pNLSF_Q15[ MAX_LPC_ORDER ], /* I/O Normalized LSFs (quant out) (0 - (2^15-1)) */ - const opus_int16 prev_NLSFq_Q15[ MAX_LPC_ORDER ] /* I Previous Normalized LSFs (0 - (2^15-1)) */ -); - -opus_int32 silk_NLSF_encode( /* O Returns RD value in Q25 */ - opus_int8 *NLSFIndices, /* I Codebook path vector [ LPC_ORDER + 1 ] */ - opus_int16 *pNLSF_Q15, /* I/O Quantized NLSF vector [ LPC_ORDER ] */ - const silk_NLSF_CB_struct *psNLSF_CB, /* I Codebook object */ - const opus_int16 *pW_QW, /* I NLSF weight vector [ LPC_ORDER ] */ - const opus_int NLSF_mu_Q20, /* I Rate weight for the RD optimization */ - const opus_int nSurvivors, /* I Max survivors after first stage */ - const opus_int signalType /* I Signal type: 0/1/2 */ -); - -/* Compute quantization errors for an LPC_order element input vector for a VQ codebook */ -void silk_NLSF_VQ( - opus_int32 err_Q26[], /* O Quantization errors [K] */ - const opus_int16 in_Q15[], /* I Input vectors to be quantized [LPC_order] */ - const opus_uint8 pCB_Q8[], /* I Codebook vectors [K*LPC_order] */ - const opus_int K, /* I Number of codebook vectors */ - const opus_int LPC_order /* I Number of LPCs */ -); - -/* Delayed-decision quantizer for NLSF residuals */ -opus_int32 silk_NLSF_del_dec_quant( /* O Returns RD value in Q25 */ - opus_int8 indices[], /* O Quantization indices [ order ] */ - const opus_int16 x_Q10[], /* I Input [ order ] */ - const opus_int16 w_Q5[], /* I Weights [ order ] */ - const opus_uint8 pred_coef_Q8[], /* I Backward predictor coefs [ order ] */ - const opus_int16 ec_ix[], /* I Indices to entropy coding tables [ order ] */ - const opus_uint8 ec_rates_Q5[], /* I Rates [] */ - const opus_int quant_step_size_Q16, /* I Quantization step size */ - const opus_int16 inv_quant_step_size_Q6, /* I Inverse quantization step size */ - const opus_int32 mu_Q20, /* I R/D tradeoff */ - const opus_int16 order /* I Number of input values */ -); - -/* Unpack predictor values and indices for entropy coding tables */ -void silk_NLSF_unpack( - opus_int16 ec_ix[], /* O Indices to entropy tables [ LPC_ORDER ] */ - opus_uint8 pred_Q8[], /* O LSF predictor [ LPC_ORDER ] */ - const silk_NLSF_CB_struct *psNLSF_CB, /* I Codebook object */ - const opus_int CB1_index /* I Index of vector in first LSF codebook */ -); - -/***********************/ -/* NLSF vector decoder */ -/***********************/ -void silk_NLSF_decode( - opus_int16 *pNLSF_Q15, /* O Quantized NLSF vector [ LPC_ORDER ] */ - opus_int8 *NLSFIndices, /* I Codebook path vector [ LPC_ORDER + 1 ] */ - const silk_NLSF_CB_struct *psNLSF_CB /* I Codebook object */ -); - -/****************************************************/ -/* Decoder Functions */ -/****************************************************/ -opus_int silk_init_decoder( - silk_decoder_state *psDec /* I/O Decoder state pointer */ -); - -/* Set decoder sampling rate */ -opus_int silk_decoder_set_fs( - silk_decoder_state *psDec, /* I/O Decoder state pointer */ - opus_int fs_kHz, /* I Sampling frequency (kHz) */ - opus_int32 fs_API_Hz /* I API Sampling frequency (Hz) */ -); - -/****************/ -/* Decode frame */ -/****************/ -opus_int silk_decode_frame( - silk_decoder_state *psDec, /* I/O Pointer to Silk decoder state */ - ec_dec *psRangeDec, /* I/O Compressor data structure */ - opus_int16 pOut[], /* O Pointer to output speech frame */ - opus_int32 *pN, /* O Pointer to size of output frame */ - opus_int lostFlag, /* I 0: no loss, 1 loss, 2 decode fec */ - opus_int condCoding /* I The type of conditional coding to use */ -); - -/* Decode indices from bitstream */ -void silk_decode_indices( - silk_decoder_state *psDec, /* I/O State */ - ec_dec *psRangeDec, /* I/O Compressor data structure */ - opus_int FrameIndex, /* I Frame number */ - opus_int decode_LBRR, /* I Flag indicating LBRR data is being decoded */ - opus_int condCoding /* I The type of conditional coding to use */ -); - -/* Decode parameters from payload */ -void silk_decode_parameters( - silk_decoder_state *psDec, /* I/O State */ - silk_decoder_control *psDecCtrl, /* I/O Decoder control */ - opus_int condCoding /* I The type of conditional coding to use */ -); - -/* Core decoder. Performs inverse NSQ operation LTP + LPC */ -void silk_decode_core( - silk_decoder_state *psDec, /* I/O Decoder state */ - silk_decoder_control *psDecCtrl, /* I Decoder control */ - opus_int16 xq[], /* O Decoded speech */ - const opus_int pulses[ MAX_FRAME_LENGTH ] /* I Pulse signal */ -); - -/* Decode quantization indices of excitation (Shell coding) */ -void silk_decode_pulses( - ec_dec *psRangeDec, /* I/O Compressor data structure */ - opus_int pulses[], /* O Excitation signal */ - const opus_int signalType, /* I Sigtype */ - const opus_int quantOffsetType, /* I quantOffsetType */ - const opus_int frame_length /* I Frame length */ -); - -/******************/ -/* CNG */ -/******************/ - -/* Reset CNG */ -void silk_CNG_Reset( - silk_decoder_state *psDec /* I/O Decoder state */ -); - -/* Updates CNG estimate, and applies the CNG when packet was lost */ -void silk_CNG( - silk_decoder_state *psDec, /* I/O Decoder state */ - silk_decoder_control *psDecCtrl, /* I/O Decoder control */ - opus_int16 frame[], /* I/O Signal */ - opus_int length /* I Length of residual */ -); - -/* Encoding of various parameters */ -void silk_encode_indices( - silk_encoder_state *psEncC, /* I/O Encoder state */ - ec_enc *psRangeEnc, /* I/O Compressor data structure */ - opus_int FrameIndex, /* I Frame number */ - opus_int encode_LBRR, /* I Flag indicating LBRR data is being encoded */ - opus_int condCoding /* I The type of conditional coding to use */ -); - -#endif diff --git a/src/opus-1.0.2/silk/pitch_est_defines.h b/src/opus-1.0.2/silk/pitch_est_defines.h deleted file mode 100644 index 0b6770eb..00000000 --- a/src/opus-1.0.2/silk/pitch_est_defines.h +++ /dev/null @@ -1,88 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifndef SILK_PE_DEFINES_H -#define SILK_PE_DEFINES_H - -#include "SigProc_FIX.h" - -/********************************************************/ -/* Definitions for pitch estimator */ -/********************************************************/ - -#define PE_MAX_FS_KHZ 16 /* Maximum sampling frequency used */ - -#define PE_MAX_NB_SUBFR 4 -#define PE_SUBFR_LENGTH_MS 5 /* 5 ms */ - -#define PE_LTP_MEM_LENGTH_MS ( 4 * PE_SUBFR_LENGTH_MS ) - -#define PE_MAX_FRAME_LENGTH_MS ( PE_LTP_MEM_LENGTH_MS + PE_MAX_NB_SUBFR * PE_SUBFR_LENGTH_MS ) -#define PE_MAX_FRAME_LENGTH ( PE_MAX_FRAME_LENGTH_MS * PE_MAX_FS_KHZ ) -#define PE_MAX_FRAME_LENGTH_ST_1 ( PE_MAX_FRAME_LENGTH >> 2 ) -#define PE_MAX_FRAME_LENGTH_ST_2 ( PE_MAX_FRAME_LENGTH >> 1 ) - -#define PE_MAX_LAG_MS 18 /* 18 ms -> 56 Hz */ -#define PE_MIN_LAG_MS 2 /* 2 ms -> 500 Hz */ -#define PE_MAX_LAG ( PE_MAX_LAG_MS * PE_MAX_FS_KHZ ) -#define PE_MIN_LAG ( PE_MIN_LAG_MS * PE_MAX_FS_KHZ ) - -#define PE_D_SRCH_LENGTH 24 - -#define PE_NB_STAGE3_LAGS 5 - -#define PE_NB_CBKS_STAGE2 3 -#define PE_NB_CBKS_STAGE2_EXT 11 - -#define PE_NB_CBKS_STAGE3_MAX 34 -#define PE_NB_CBKS_STAGE3_MID 24 -#define PE_NB_CBKS_STAGE3_MIN 16 - -#define PE_NB_CBKS_STAGE3_10MS 12 -#define PE_NB_CBKS_STAGE2_10MS 3 - -#define PE_SHORTLAG_BIAS 0.2f /* for logarithmic weighting */ -#define PE_PREVLAG_BIAS 0.2f /* for logarithmic weighting */ -#define PE_FLATCONTOUR_BIAS 0.05f - -#define SILK_PE_MIN_COMPLEX 0 -#define SILK_PE_MID_COMPLEX 1 -#define SILK_PE_MAX_COMPLEX 2 - -/* Tables for 20 ms frames */ -extern const opus_int8 silk_CB_lags_stage2[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE2_EXT ]; -extern const opus_int8 silk_CB_lags_stage3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ]; -extern const opus_int8 silk_Lag_range_stage3[ SILK_PE_MAX_COMPLEX + 1 ] [ PE_MAX_NB_SUBFR ][ 2 ]; -extern const opus_int8 silk_nb_cbk_searchs_stage3[ SILK_PE_MAX_COMPLEX + 1 ]; - -/* Tables for 10 ms frames */ -extern const opus_int8 silk_CB_lags_stage2_10_ms[ PE_MAX_NB_SUBFR >> 1][ 3 ]; -extern const opus_int8 silk_CB_lags_stage3_10_ms[ PE_MAX_NB_SUBFR >> 1 ][ 12 ]; -extern const opus_int8 silk_Lag_range_stage3_10_ms[ PE_MAX_NB_SUBFR >> 1 ][ 2 ]; - -#endif - diff --git a/src/opus-1.0.2/silk/pitch_est_tables.c b/src/opus-1.0.2/silk/pitch_est_tables.c deleted file mode 100644 index 7b139ed2..00000000 --- a/src/opus-1.0.2/silk/pitch_est_tables.c +++ /dev/null @@ -1,99 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "typedef.h" -#include "pitch_est_defines.h" - -const opus_int8 silk_CB_lags_stage2_10_ms[ PE_MAX_NB_SUBFR >> 1][ PE_NB_CBKS_STAGE2_10MS ] = -{ - {0, 1, 0}, - {0, 0, 1} -}; - -const opus_int8 silk_CB_lags_stage3_10_ms[ PE_MAX_NB_SUBFR >> 1 ][ PE_NB_CBKS_STAGE3_10MS ] = -{ - { 0, 0, 1,-1, 1,-1, 2,-2, 2,-2, 3,-3}, - { 0, 1, 0, 1,-1, 2,-1, 2,-2, 3,-2, 3} -}; - -const opus_int8 silk_Lag_range_stage3_10_ms[ PE_MAX_NB_SUBFR >> 1 ][ 2 ] = -{ - {-3, 7}, - {-2, 7} -}; - -const opus_int8 silk_CB_lags_stage2[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE2_EXT ] = -{ - {0, 2,-1,-1,-1, 0, 0, 1, 1, 0, 1}, - {0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0}, - {0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0}, - {0,-1, 2, 1, 0, 1, 1, 0, 0,-1,-1} -}; - -const opus_int8 silk_CB_lags_stage3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ] = -{ - {0, 0, 1,-1, 0, 1,-1, 0,-1, 1,-2, 2,-2,-2, 2,-3, 2, 3,-3,-4, 3,-4, 4, 4,-5, 5,-6,-5, 6,-7, 6, 5, 8,-9}, - {0, 0, 1, 0, 0, 0, 0, 0, 0, 0,-1, 1, 0, 0, 1,-1, 0, 1,-1,-1, 1,-1, 2, 1,-1, 2,-2,-2, 2,-2, 2, 2, 3,-3}, - {0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1,-1, 1, 0, 0, 2, 1,-1, 2,-1,-1, 2,-1, 2, 2,-1, 3,-2,-2,-2, 3}, - {0, 1, 0, 0, 1, 0, 1,-1, 2,-1, 2,-1, 2, 3,-2, 3,-2,-2, 4, 4,-3, 5,-3,-4, 6,-4, 6, 5,-5, 8,-6,-5,-7, 9} -}; - -const opus_int8 silk_Lag_range_stage3[ SILK_PE_MAX_COMPLEX + 1 ] [ PE_MAX_NB_SUBFR ][ 2 ] = -{ - /* Lags to search for low number of stage3 cbks */ - { - {-5,8}, - {-1,6}, - {-1,6}, - {-4,10} - }, - /* Lags to search for middle number of stage3 cbks */ - { - {-6,10}, - {-2,6}, - {-1,6}, - {-5,10} - }, - /* Lags to search for max number of stage3 cbks */ - { - {-9,12}, - {-3,7}, - {-2,7}, - {-7,13} - } -}; - -const opus_int8 silk_nb_cbk_searchs_stage3[ SILK_PE_MAX_COMPLEX + 1 ] = -{ - PE_NB_CBKS_STAGE3_MIN, - PE_NB_CBKS_STAGE3_MID, - PE_NB_CBKS_STAGE3_MAX -}; diff --git a/src/opus-1.0.2/silk/process_NLSFs.c b/src/opus-1.0.2/silk/process_NLSFs.c deleted file mode 100644 index 34ce7914..00000000 --- a/src/opus-1.0.2/silk/process_NLSFs.c +++ /dev/null @@ -1,105 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main.h" - -/* Limit, stabilize, convert and quantize NLSFs */ -void silk_process_NLSFs( - silk_encoder_state *psEncC, /* I/O Encoder state */ - opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ], /* O Prediction coefficients */ - opus_int16 pNLSF_Q15[ MAX_LPC_ORDER ], /* I/O Normalized LSFs (quant out) (0 - (2^15-1)) */ - const opus_int16 prev_NLSFq_Q15[ MAX_LPC_ORDER ] /* I Previous Normalized LSFs (0 - (2^15-1)) */ -) -{ - opus_int i, doInterpolate; - opus_int NLSF_mu_Q20; - opus_int32 i_sqr_Q15; - opus_int16 pNLSF0_temp_Q15[ MAX_LPC_ORDER ]; - opus_int16 pNLSFW_QW[ MAX_LPC_ORDER ]; - opus_int16 pNLSFW0_temp_QW[ MAX_LPC_ORDER ]; - - silk_assert( psEncC->speech_activity_Q8 >= 0 ); - silk_assert( psEncC->speech_activity_Q8 <= SILK_FIX_CONST( 1.0, 8 ) ); - silk_assert( psEncC->useInterpolatedNLSFs == 1 || psEncC->indices.NLSFInterpCoef_Q2 == ( 1 << 2 ) ); - - /***********************/ - /* Calculate mu values */ - /***********************/ - /* NLSF_mu = 0.003 - 0.0015 * psEnc->speech_activity; */ - NLSF_mu_Q20 = silk_SMLAWB( SILK_FIX_CONST( 0.003, 20 ), SILK_FIX_CONST( -0.001, 28 ), psEncC->speech_activity_Q8 ); - if( psEncC->nb_subfr == 2 ) { - /* Multiply by 1.5 for 10 ms packets */ - NLSF_mu_Q20 = silk_ADD_RSHIFT( NLSF_mu_Q20, NLSF_mu_Q20, 1 ); - } - - silk_assert( NLSF_mu_Q20 > 0 ); - silk_assert( NLSF_mu_Q20 <= SILK_FIX_CONST( 0.005, 20 ) ); - - /* Calculate NLSF weights */ - silk_NLSF_VQ_weights_laroia( pNLSFW_QW, pNLSF_Q15, psEncC->predictLPCOrder ); - - /* Update NLSF weights for interpolated NLSFs */ - doInterpolate = ( psEncC->useInterpolatedNLSFs == 1 ) && ( psEncC->indices.NLSFInterpCoef_Q2 < 4 ); - if( doInterpolate ) { - /* Calculate the interpolated NLSF vector for the first half */ - silk_interpolate( pNLSF0_temp_Q15, prev_NLSFq_Q15, pNLSF_Q15, - psEncC->indices.NLSFInterpCoef_Q2, psEncC->predictLPCOrder ); - - /* Calculate first half NLSF weights for the interpolated NLSFs */ - silk_NLSF_VQ_weights_laroia( pNLSFW0_temp_QW, pNLSF0_temp_Q15, psEncC->predictLPCOrder ); - - /* Update NLSF weights with contribution from first half */ - i_sqr_Q15 = silk_LSHIFT( silk_SMULBB( psEncC->indices.NLSFInterpCoef_Q2, psEncC->indices.NLSFInterpCoef_Q2 ), 11 ); - for( i = 0; i < psEncC->predictLPCOrder; i++ ) { - pNLSFW_QW[ i ] = silk_SMLAWB( silk_RSHIFT( pNLSFW_QW[ i ], 1 ), (opus_int32)pNLSFW0_temp_QW[ i ], i_sqr_Q15 ); - silk_assert( pNLSFW_QW[ i ] >= 1 ); - } - } - - silk_NLSF_encode( psEncC->indices.NLSFIndices, pNLSF_Q15, psEncC->psNLSF_CB, pNLSFW_QW, - NLSF_mu_Q20, psEncC->NLSF_MSVQ_Survivors, psEncC->indices.signalType ); - - /* Convert quantized NLSFs back to LPC coefficients */ - silk_NLSF2A( PredCoef_Q12[ 1 ], pNLSF_Q15, psEncC->predictLPCOrder ); - - if( doInterpolate ) { - /* Calculate the interpolated, quantized LSF vector for the first half */ - silk_interpolate( pNLSF0_temp_Q15, prev_NLSFq_Q15, pNLSF_Q15, - psEncC->indices.NLSFInterpCoef_Q2, psEncC->predictLPCOrder ); - - /* Convert back to LPC coefficients */ - silk_NLSF2A( PredCoef_Q12[ 0 ], pNLSF0_temp_Q15, psEncC->predictLPCOrder ); - - } else { - /* Copy LPC coefficients for first half from second half */ - silk_memcpy( PredCoef_Q12[ 0 ], PredCoef_Q12[ 1 ], psEncC->predictLPCOrder * sizeof( opus_int16 ) ); - } -} diff --git a/src/opus-1.0.2/silk/quant_LTP_gains.c b/src/opus-1.0.2/silk/quant_LTP_gains.c deleted file mode 100644 index f73c0f50..00000000 --- a/src/opus-1.0.2/silk/quant_LTP_gains.c +++ /dev/null @@ -1,107 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main.h" - -void silk_quant_LTP_gains( - opus_int16 B_Q14[ MAX_NB_SUBFR * LTP_ORDER ], /* I/O (un)quantized LTP gains */ - opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook Index */ - opus_int8 *periodicity_index, /* O Periodicity Index */ - const opus_int32 W_Q18[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ], /* I Error Weights in Q18 */ - opus_int mu_Q9, /* I Mu value (R/D tradeoff) */ - opus_int lowComplexity, /* I Flag for low complexity */ - const opus_int nb_subfr /* I number of subframes */ -) -{ - opus_int j, k, cbk_size; - opus_int8 temp_idx[ MAX_NB_SUBFR ]; - const opus_uint8 *cl_ptr_Q5; - const opus_int8 *cbk_ptr_Q7; - const opus_int16 *b_Q14_ptr; - const opus_int32 *W_Q18_ptr; - opus_int32 rate_dist_Q14_subfr, rate_dist_Q14, min_rate_dist_Q14; - - /***************************************************/ - /* iterate over different codebooks with different */ - /* rates/distortions, and choose best */ - /***************************************************/ - min_rate_dist_Q14 = silk_int32_MAX; - for( k = 0; k < 3; k++ ) { - cl_ptr_Q5 = silk_LTP_gain_BITS_Q5_ptrs[ k ]; - cbk_ptr_Q7 = silk_LTP_vq_ptrs_Q7[ k ]; - cbk_size = silk_LTP_vq_sizes[ k ]; - - /* Set up pointer to first subframe */ - W_Q18_ptr = W_Q18; - b_Q14_ptr = B_Q14; - - rate_dist_Q14 = 0; - for( j = 0; j < nb_subfr; j++ ) { - silk_VQ_WMat_EC( - &temp_idx[ j ], /* O index of best codebook vector */ - &rate_dist_Q14_subfr, /* O best weighted quantization error + mu * rate */ - b_Q14_ptr, /* I input vector to be quantized */ - W_Q18_ptr, /* I weighting matrix */ - cbk_ptr_Q7, /* I codebook */ - cl_ptr_Q5, /* I code length for each codebook vector */ - mu_Q9, /* I tradeoff between weighted error and rate */ - cbk_size /* I number of vectors in codebook */ - ); - - rate_dist_Q14 = silk_ADD_POS_SAT32( rate_dist_Q14, rate_dist_Q14_subfr ); - - b_Q14_ptr += LTP_ORDER; - W_Q18_ptr += LTP_ORDER * LTP_ORDER; - } - - /* Avoid never finding a codebook */ - rate_dist_Q14 = silk_min( silk_int32_MAX - 1, rate_dist_Q14 ); - - if( rate_dist_Q14 < min_rate_dist_Q14 ) { - min_rate_dist_Q14 = rate_dist_Q14; - *periodicity_index = (opus_int8)k; - silk_memcpy( cbk_index, temp_idx, nb_subfr * sizeof( opus_int8 ) ); - } - - /* Break early in low-complexity mode if rate distortion is below threshold */ - if( lowComplexity && ( rate_dist_Q14 < silk_LTP_gain_middle_avg_RD_Q14 ) ) { - break; - } - } - - cbk_ptr_Q7 = silk_LTP_vq_ptrs_Q7[ *periodicity_index ]; - for( j = 0; j < nb_subfr; j++ ) { - for( k = 0; k < LTP_ORDER; k++ ) { - B_Q14[ j * LTP_ORDER + k ] = silk_LSHIFT( cbk_ptr_Q7[ cbk_index[ j ] * LTP_ORDER + k ], 7 ); - } - } -} - diff --git a/src/opus-1.0.2/silk/resampler.c b/src/opus-1.0.2/silk/resampler.c deleted file mode 100644 index 7e58332f..00000000 --- a/src/opus-1.0.2/silk/resampler.c +++ /dev/null @@ -1,215 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* - * Matrix of resampling methods used: - * Fs_out (kHz) - * 8 12 16 24 48 - * - * 8 C UF U UF UF - * 12 AF C UF U UF - * Fs_in (kHz) 16 D AF C UF UF - * 24 AF D AF C U - * 48 AF AF AF D C - * - * C -> Copy (no resampling) - * D -> Allpass-based 2x downsampling - * U -> Allpass-based 2x upsampling - * UF -> Allpass-based 2x upsampling followed by FIR interpolation - * AF -> AR2 filter followed by FIR interpolation - */ - -#include "resampler_private.h" - -/* Tables with delay compensation values to equalize total delay for different modes */ -static const opus_int8 delay_matrix_enc[ 5 ][ 3 ] = { -/* in \ out 8 12 16 */ -/* 8 */ { 6, 0, 3 }, -/* 12 */ { 0, 7, 3 }, -/* 16 */ { 0, 1, 10 }, -/* 24 */ { 0, 2, 6 }, -/* 48 */ { 18, 10, 12 } -}; - -static const opus_int8 delay_matrix_dec[ 3 ][ 5 ] = { -/* in \ out 8 12 16 24 48 */ -/* 8 */ { 4, 0, 2, 0, 0 }, -/* 12 */ { 0, 9, 4, 7, 4 }, -/* 16 */ { 0, 3, 12, 7, 7 } -}; - -/* Simple way to make [8000, 12000, 16000, 24000, 48000] to [0, 1, 2, 3, 4] */ -#define rateID(R) ( ( ( ((R)>>12) - ((R)>16000) ) >> ((R)>24000) ) - 1 ) - -#define USE_silk_resampler_copy (0) -#define USE_silk_resampler_private_up2_HQ_wrapper (1) -#define USE_silk_resampler_private_IIR_FIR (2) -#define USE_silk_resampler_private_down_FIR (3) - -/* Initialize/reset the resampler state for a given pair of input/output sampling rates */ -opus_int silk_resampler_init( - silk_resampler_state_struct *S, /* I/O Resampler state */ - opus_int32 Fs_Hz_in, /* I Input sampling rate (Hz) */ - opus_int32 Fs_Hz_out, /* I Output sampling rate (Hz) */ - opus_int forEnc /* I If 1: encoder; if 0: decoder */ -) -{ - opus_int up2x; - - /* Clear state */ - silk_memset( S, 0, sizeof( silk_resampler_state_struct ) ); - - /* Input checking */ - if( forEnc ) { - if( ( Fs_Hz_in != 8000 && Fs_Hz_in != 12000 && Fs_Hz_in != 16000 && Fs_Hz_in != 24000 && Fs_Hz_in != 48000 ) || - ( Fs_Hz_out != 8000 && Fs_Hz_out != 12000 && Fs_Hz_out != 16000 ) ) { - silk_assert( 0 ); - return -1; - } - S->inputDelay = delay_matrix_enc[ rateID( Fs_Hz_in ) ][ rateID( Fs_Hz_out ) ]; - } else { - if( ( Fs_Hz_in != 8000 && Fs_Hz_in != 12000 && Fs_Hz_in != 16000 ) || - ( Fs_Hz_out != 8000 && Fs_Hz_out != 12000 && Fs_Hz_out != 16000 && Fs_Hz_out != 24000 && Fs_Hz_out != 48000 ) ) { - silk_assert( 0 ); - return -1; - } - S->inputDelay = delay_matrix_dec[ rateID( Fs_Hz_in ) ][ rateID( Fs_Hz_out ) ]; - } - - S->Fs_in_kHz = silk_DIV32_16( Fs_Hz_in, 1000 ); - S->Fs_out_kHz = silk_DIV32_16( Fs_Hz_out, 1000 ); - - /* Number of samples processed per batch */ - S->batchSize = S->Fs_in_kHz * RESAMPLER_MAX_BATCH_SIZE_MS; - - /* Find resampler with the right sampling ratio */ - up2x = 0; - if( Fs_Hz_out > Fs_Hz_in ) { - /* Upsample */ - if( Fs_Hz_out == silk_MUL( Fs_Hz_in, 2 ) ) { /* Fs_out : Fs_in = 2 : 1 */ - /* Special case: directly use 2x upsampler */ - S->resampler_function = USE_silk_resampler_private_up2_HQ_wrapper; - } else { - /* Default resampler */ - S->resampler_function = USE_silk_resampler_private_IIR_FIR; - up2x = 1; - } - } else if ( Fs_Hz_out < Fs_Hz_in ) { - /* Downsample */ - S->resampler_function = USE_silk_resampler_private_down_FIR; - if( silk_MUL( Fs_Hz_out, 4 ) == silk_MUL( Fs_Hz_in, 3 ) ) { /* Fs_out : Fs_in = 3 : 4 */ - S->FIR_Fracs = 3; - S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR0; - S->Coefs = silk_Resampler_3_4_COEFS; - } else if( silk_MUL( Fs_Hz_out, 3 ) == silk_MUL( Fs_Hz_in, 2 ) ) { /* Fs_out : Fs_in = 2 : 3 */ - S->FIR_Fracs = 2; - S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR0; - S->Coefs = silk_Resampler_2_3_COEFS; - } else if( silk_MUL( Fs_Hz_out, 2 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 2 */ - S->FIR_Fracs = 1; - S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR1; - S->Coefs = silk_Resampler_1_2_COEFS; - } else if( silk_MUL( Fs_Hz_out, 3 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 3 */ - S->FIR_Fracs = 1; - S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR2; - S->Coefs = silk_Resampler_1_3_COEFS; - } else if( silk_MUL( Fs_Hz_out, 4 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 4 */ - S->FIR_Fracs = 1; - S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR2; - S->Coefs = silk_Resampler_1_4_COEFS; - } else if( silk_MUL( Fs_Hz_out, 6 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 6 */ - S->FIR_Fracs = 1; - S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR2; - S->Coefs = silk_Resampler_1_6_COEFS; - } else { - /* None available */ - silk_assert( 0 ); - return -1; - } - } else { - /* Input and output sampling rates are equal: copy */ - S->resampler_function = USE_silk_resampler_copy; - } - - /* Ratio of input/output samples */ - S->invRatio_Q16 = silk_LSHIFT32( silk_DIV32( silk_LSHIFT32( Fs_Hz_in, 14 + up2x ), Fs_Hz_out ), 2 ); - /* Make sure the ratio is rounded up */ - while( silk_SMULWW( S->invRatio_Q16, Fs_Hz_out ) < silk_LSHIFT32( Fs_Hz_in, up2x ) ) { - S->invRatio_Q16++; - } - - return 0; -} - -/* Resampler: convert from one sampling rate to another */ -/* Input and output sampling rate are at most 48000 Hz */ -opus_int silk_resampler( - silk_resampler_state_struct *S, /* I/O Resampler state */ - opus_int16 out[], /* O Output signal */ - const opus_int16 in[], /* I Input signal */ - opus_int32 inLen /* I Number of input samples */ -) -{ - opus_int nSamples; - - /* Need at least 1 ms of input data */ - silk_assert( inLen >= S->Fs_in_kHz ); - /* Delay can't exceed the 1 ms of buffering */ - silk_assert( S->inputDelay <= S->Fs_in_kHz ); - - nSamples = S->Fs_in_kHz - S->inputDelay; - - /* Copy to delay buffer */ - silk_memcpy( &S->delayBuf[ S->inputDelay ], in, nSamples * sizeof( opus_int16 ) ); - - switch( S->resampler_function ) { - case USE_silk_resampler_private_up2_HQ_wrapper: - silk_resampler_private_up2_HQ_wrapper( S, out, S->delayBuf, S->Fs_in_kHz ); - silk_resampler_private_up2_HQ_wrapper( S, &out[ S->Fs_out_kHz ], &in[ nSamples ], inLen - S->Fs_in_kHz ); - break; - case USE_silk_resampler_private_IIR_FIR: - silk_resampler_private_IIR_FIR( S, out, S->delayBuf, S->Fs_in_kHz ); - silk_resampler_private_IIR_FIR( S, &out[ S->Fs_out_kHz ], &in[ nSamples ], inLen - S->Fs_in_kHz ); - break; - case USE_silk_resampler_private_down_FIR: - silk_resampler_private_down_FIR( S, out, S->delayBuf, S->Fs_in_kHz ); - silk_resampler_private_down_FIR( S, &out[ S->Fs_out_kHz ], &in[ nSamples ], inLen - S->Fs_in_kHz ); - break; - default: - silk_memcpy( out, S->delayBuf, S->Fs_in_kHz * sizeof( opus_int16 ) ); - silk_memcpy( &out[ S->Fs_out_kHz ], &in[ nSamples ], ( inLen - S->Fs_in_kHz ) * sizeof( opus_int16 ) ); - } - - /* Copy to delay buffer */ - silk_memcpy( S->delayBuf, &in[ inLen - S->inputDelay ], S->inputDelay * sizeof( opus_int16 ) ); - - return 0; -} diff --git a/src/opus-1.0.2/silk/resampler_down2.c b/src/opus-1.0.2/silk/resampler_down2.c deleted file mode 100644 index 21d11992..00000000 --- a/src/opus-1.0.2/silk/resampler_down2.c +++ /dev/null @@ -1,74 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "SigProc_FIX.h" -#include "resampler_rom.h" - -/* Downsample by a factor 2 */ -void silk_resampler_down2( - opus_int32 *S, /* I/O State vector [ 2 ] */ - opus_int16 *out, /* O Output signal [ len ] */ - const opus_int16 *in, /* I Input signal [ floor(len/2) ] */ - opus_int32 inLen /* I Number of input samples */ -) -{ - opus_int32 k, len2 = silk_RSHIFT32( inLen, 1 ); - opus_int32 in32, out32, Y, X; - - silk_assert( silk_resampler_down2_0 > 0 ); - silk_assert( silk_resampler_down2_1 < 0 ); - - /* Internal variables and state are in Q10 format */ - for( k = 0; k < len2; k++ ) { - /* Convert to Q10 */ - in32 = silk_LSHIFT( (opus_int32)in[ 2 * k ], 10 ); - - /* All-pass section for even input sample */ - Y = silk_SUB32( in32, S[ 0 ] ); - X = silk_SMLAWB( Y, Y, silk_resampler_down2_1 ); - out32 = silk_ADD32( S[ 0 ], X ); - S[ 0 ] = silk_ADD32( in32, X ); - - /* Convert to Q10 */ - in32 = silk_LSHIFT( (opus_int32)in[ 2 * k + 1 ], 10 ); - - /* All-pass section for odd input sample, and add to output of previous section */ - Y = silk_SUB32( in32, S[ 1 ] ); - X = silk_SMULWB( Y, silk_resampler_down2_0 ); - out32 = silk_ADD32( out32, S[ 1 ] ); - out32 = silk_ADD32( out32, X ); - S[ 1 ] = silk_ADD32( in32, X ); - - /* Add, convert back to int16 and store to output */ - out[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( out32, 11 ) ); - } -} - diff --git a/src/opus-1.0.2/silk/resampler_down2_3.c b/src/opus-1.0.2/silk/resampler_down2_3.c deleted file mode 100644 index fe5b671d..00000000 --- a/src/opus-1.0.2/silk/resampler_down2_3.c +++ /dev/null @@ -1,98 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "SigProc_FIX.h" -#include "resampler_private.h" - -#define ORDER_FIR 4 - -/* Downsample by a factor 2/3, low quality */ -void silk_resampler_down2_3( - opus_int32 *S, /* I/O State vector [ 6 ] */ - opus_int16 *out, /* O Output signal [ floor(2*inLen/3) ] */ - const opus_int16 *in, /* I Input signal [ inLen ] */ - opus_int32 inLen /* I Number of input samples */ -) -{ - opus_int32 nSamplesIn, counter, res_Q6; - opus_int32 buf[ RESAMPLER_MAX_BATCH_SIZE_IN + ORDER_FIR ]; - opus_int32 *buf_ptr; - - /* Copy buffered samples to start of buffer */ - silk_memcpy( buf, S, ORDER_FIR * sizeof( opus_int32 ) ); - - /* Iterate over blocks of frameSizeIn input samples */ - while( 1 ) { - nSamplesIn = silk_min( inLen, RESAMPLER_MAX_BATCH_SIZE_IN ); - - /* Second-order AR filter (output in Q8) */ - silk_resampler_private_AR2( &S[ ORDER_FIR ], &buf[ ORDER_FIR ], in, - silk_Resampler_2_3_COEFS_LQ, nSamplesIn ); - - /* Interpolate filtered signal */ - buf_ptr = buf; - counter = nSamplesIn; - while( counter > 2 ) { - /* Inner product */ - res_Q6 = silk_SMULWB( buf_ptr[ 0 ], silk_Resampler_2_3_COEFS_LQ[ 2 ] ); - res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 1 ], silk_Resampler_2_3_COEFS_LQ[ 3 ] ); - res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 2 ], silk_Resampler_2_3_COEFS_LQ[ 5 ] ); - res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 3 ], silk_Resampler_2_3_COEFS_LQ[ 4 ] ); - - /* Scale down, saturate and store in output array */ - *out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q6, 6 ) ); - - res_Q6 = silk_SMULWB( buf_ptr[ 1 ], silk_Resampler_2_3_COEFS_LQ[ 4 ] ); - res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 2 ], silk_Resampler_2_3_COEFS_LQ[ 5 ] ); - res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 3 ], silk_Resampler_2_3_COEFS_LQ[ 3 ] ); - res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 4 ], silk_Resampler_2_3_COEFS_LQ[ 2 ] ); - - /* Scale down, saturate and store in output array */ - *out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q6, 6 ) ); - - buf_ptr += 3; - counter -= 3; - } - - in += nSamplesIn; - inLen -= nSamplesIn; - - if( inLen > 0 ) { - /* More iterations to do; copy last part of filtered signal to beginning of buffer */ - silk_memcpy( buf, &buf[ nSamplesIn ], ORDER_FIR * sizeof( opus_int32 ) ); - } else { - break; - } - } - - /* Copy last part of filtered signal to the state for the next call */ - silk_memcpy( S, &buf[ nSamplesIn ], ORDER_FIR * sizeof( opus_int32 ) ); -} diff --git a/src/opus-1.0.2/silk/resampler_private.h b/src/opus-1.0.2/silk/resampler_private.h deleted file mode 100644 index 45d342c7..00000000 --- a/src/opus-1.0.2/silk/resampler_private.h +++ /dev/null @@ -1,88 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifndef SILK_RESAMPLER_PRIVATE_H -#define SILK_RESAMPLER_PRIVATE_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include "SigProc_FIX.h" -#include "resampler_structs.h" -#include "resampler_rom.h" - -/* Number of input samples to process in the inner loop */ -#define RESAMPLER_MAX_BATCH_SIZE_MS 10 -#define RESAMPLER_MAX_FS_KHZ 48 -#define RESAMPLER_MAX_BATCH_SIZE_IN ( RESAMPLER_MAX_BATCH_SIZE_MS * RESAMPLER_MAX_FS_KHZ ) - -/* Description: Hybrid IIR/FIR polyphase implementation of resampling */ -void silk_resampler_private_IIR_FIR( - void *SS, /* I/O Resampler state */ - opus_int16 out[], /* O Output signal */ - const opus_int16 in[], /* I Input signal */ - opus_int32 inLen /* I Number of input samples */ -); - -/* Description: Hybrid IIR/FIR polyphase implementation of resampling */ -void silk_resampler_private_down_FIR( - void *SS, /* I/O Resampler state */ - opus_int16 out[], /* O Output signal */ - const opus_int16 in[], /* I Input signal */ - opus_int32 inLen /* I Number of input samples */ -); - -/* Upsample by a factor 2, high quality */ -void silk_resampler_private_up2_HQ_wrapper( - void *SS, /* I/O Resampler state (unused) */ - opus_int16 *out, /* O Output signal [ 2 * len ] */ - const opus_int16 *in, /* I Input signal [ len ] */ - opus_int32 len /* I Number of input samples */ -); - -/* Upsample by a factor 2, high quality */ -void silk_resampler_private_up2_HQ( - opus_int32 *S, /* I/O Resampler state [ 6 ] */ - opus_int16 *out, /* O Output signal [ 2 * len ] */ - const opus_int16 *in, /* I Input signal [ len ] */ - opus_int32 len /* I Number of input samples */ -); - -/* Second order AR filter */ -void silk_resampler_private_AR2( - opus_int32 S[], /* I/O State vector [ 2 ] */ - opus_int32 out_Q8[], /* O Output signal */ - const opus_int16 in[], /* I Input signal */ - const opus_int16 A_Q14[], /* I AR coefficients, Q14 */ - opus_int32 len /* I Signal length */ -); - -#ifdef __cplusplus -} -#endif -#endif /* SILK_RESAMPLER_PRIVATE_H */ diff --git a/src/opus-1.0.2/silk/resampler_private_AR2.c b/src/opus-1.0.2/silk/resampler_private_AR2.c deleted file mode 100644 index d069f2d8..00000000 --- a/src/opus-1.0.2/silk/resampler_private_AR2.c +++ /dev/null @@ -1,55 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "SigProc_FIX.h" -#include "resampler_private.h" - -/* Second order AR filter with single delay elements */ -void silk_resampler_private_AR2( - opus_int32 S[], /* I/O State vector [ 2 ] */ - opus_int32 out_Q8[], /* O Output signal */ - const opus_int16 in[], /* I Input signal */ - const opus_int16 A_Q14[], /* I AR coefficients, Q14 */ - opus_int32 len /* I Signal length */ -) -{ - opus_int32 k; - opus_int32 out32; - - for( k = 0; k < len; k++ ) { - out32 = silk_ADD_LSHIFT32( S[ 0 ], (opus_int32)in[ k ], 8 ); - out_Q8[ k ] = out32; - out32 = silk_LSHIFT( out32, 2 ); - S[ 0 ] = silk_SMLAWB( S[ 1 ], out32, A_Q14[ 0 ] ); - S[ 1 ] = silk_SMULWB( out32, A_Q14[ 1 ] ); - } -} - diff --git a/src/opus-1.0.2/silk/resampler_private_IIR_FIR.c b/src/opus-1.0.2/silk/resampler_private_IIR_FIR.c deleted file mode 100644 index d9e42ca0..00000000 --- a/src/opus-1.0.2/silk/resampler_private_IIR_FIR.c +++ /dev/null @@ -1,103 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "SigProc_FIX.h" -#include "resampler_private.h" - -static inline opus_int16 *silk_resampler_private_IIR_FIR_INTERPOL( - opus_int16 *out, - opus_int16 *buf, - opus_int32 max_index_Q16, - opus_int32 index_increment_Q16 -) -{ - opus_int32 index_Q16, res_Q15; - opus_int16 *buf_ptr; - opus_int32 table_index; - - /* Interpolate upsampled signal and store in output array */ - for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) { - table_index = silk_SMULWB( index_Q16 & 0xFFFF, 12 ); - buf_ptr = &buf[ index_Q16 >> 16 ]; - - res_Q15 = silk_SMULBB( buf_ptr[ 0 ], silk_resampler_frac_FIR_12[ table_index ][ 0 ] ); - res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 1 ], silk_resampler_frac_FIR_12[ table_index ][ 1 ] ); - res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 2 ], silk_resampler_frac_FIR_12[ table_index ][ 2 ] ); - res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 3 ], silk_resampler_frac_FIR_12[ table_index ][ 3 ] ); - res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 4 ], silk_resampler_frac_FIR_12[ 11 - table_index ][ 3 ] ); - res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 5 ], silk_resampler_frac_FIR_12[ 11 - table_index ][ 2 ] ); - res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 6 ], silk_resampler_frac_FIR_12[ 11 - table_index ][ 1 ] ); - res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 7 ], silk_resampler_frac_FIR_12[ 11 - table_index ][ 0 ] ); - *out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q15, 15 ) ); - } - return out; -} -/* Upsample using a combination of allpass-based 2x upsampling and FIR interpolation */ -void silk_resampler_private_IIR_FIR( - void *SS, /* I/O Resampler state */ - opus_int16 out[], /* O Output signal */ - const opus_int16 in[], /* I Input signal */ - opus_int32 inLen /* I Number of input samples */ -) -{ - silk_resampler_state_struct *S = (silk_resampler_state_struct *)SS; - opus_int32 nSamplesIn; - opus_int32 max_index_Q16, index_increment_Q16; - opus_int16 buf[ RESAMPLER_MAX_BATCH_SIZE_IN + RESAMPLER_ORDER_FIR_12 ]; - - /* Copy buffered samples to start of buffer */ - silk_memcpy( buf, S->sFIR, RESAMPLER_ORDER_FIR_12 * sizeof( opus_int32 ) ); - - /* Iterate over blocks of frameSizeIn input samples */ - index_increment_Q16 = S->invRatio_Q16; - while( 1 ) { - nSamplesIn = silk_min( inLen, S->batchSize ); - - /* Upsample 2x */ - silk_resampler_private_up2_HQ( S->sIIR, &buf[ RESAMPLER_ORDER_FIR_12 ], in, nSamplesIn ); - - max_index_Q16 = silk_LSHIFT32( nSamplesIn, 16 + 1 ); /* + 1 because 2x upsampling */ - out = silk_resampler_private_IIR_FIR_INTERPOL( out, buf, max_index_Q16, index_increment_Q16 ); - in += nSamplesIn; - inLen -= nSamplesIn; - - if( inLen > 0 ) { - /* More iterations to do; copy last part of filtered signal to beginning of buffer */ - silk_memcpy( buf, &buf[ nSamplesIn << 1 ], RESAMPLER_ORDER_FIR_12 * sizeof( opus_int32 ) ); - } else { - break; - } - } - - /* Copy last part of filtered signal to the state for the next call */ - silk_memcpy( S->sFIR, &buf[ nSamplesIn << 1 ], RESAMPLER_ORDER_FIR_12 * sizeof( opus_int32 ) ); -} - diff --git a/src/opus-1.0.2/silk/resampler_private_down_FIR.c b/src/opus-1.0.2/silk/resampler_private_down_FIR.c deleted file mode 100644 index 5d24564c..00000000 --- a/src/opus-1.0.2/silk/resampler_private_down_FIR.c +++ /dev/null @@ -1,189 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "SigProc_FIX.h" -#include "resampler_private.h" - -static inline opus_int16 *silk_resampler_private_down_FIR_INTERPOL( - opus_int16 *out, - opus_int32 *buf, - const opus_int16 *FIR_Coefs, - opus_int FIR_Order, - opus_int FIR_Fracs, - opus_int32 max_index_Q16, - opus_int32 index_increment_Q16 -) -{ - opus_int32 index_Q16, res_Q6; - opus_int32 *buf_ptr; - opus_int32 interpol_ind; - const opus_int16 *interpol_ptr; - - switch( FIR_Order ) { - case RESAMPLER_DOWN_ORDER_FIR0: - for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) { - /* Integer part gives pointer to buffered input */ - buf_ptr = buf + silk_RSHIFT( index_Q16, 16 ); - - /* Fractional part gives interpolation coefficients */ - interpol_ind = silk_SMULWB( index_Q16 & 0xFFFF, FIR_Fracs ); - - /* Inner product */ - interpol_ptr = &FIR_Coefs[ RESAMPLER_DOWN_ORDER_FIR0 / 2 * interpol_ind ]; - res_Q6 = silk_SMULWB( buf_ptr[ 0 ], interpol_ptr[ 0 ] ); - res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 1 ], interpol_ptr[ 1 ] ); - res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 2 ], interpol_ptr[ 2 ] ); - res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 3 ], interpol_ptr[ 3 ] ); - res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 4 ], interpol_ptr[ 4 ] ); - res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 5 ], interpol_ptr[ 5 ] ); - res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 6 ], interpol_ptr[ 6 ] ); - res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 7 ], interpol_ptr[ 7 ] ); - res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 8 ], interpol_ptr[ 8 ] ); - interpol_ptr = &FIR_Coefs[ RESAMPLER_DOWN_ORDER_FIR0 / 2 * ( FIR_Fracs - 1 - interpol_ind ) ]; - res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 17 ], interpol_ptr[ 0 ] ); - res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 16 ], interpol_ptr[ 1 ] ); - res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 15 ], interpol_ptr[ 2 ] ); - res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 14 ], interpol_ptr[ 3 ] ); - res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 13 ], interpol_ptr[ 4 ] ); - res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 12 ], interpol_ptr[ 5 ] ); - res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 11 ], interpol_ptr[ 6 ] ); - res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 10 ], interpol_ptr[ 7 ] ); - res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 9 ], interpol_ptr[ 8 ] ); - - /* Scale down, saturate and store in output array */ - *out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q6, 6 ) ); - } - break; - case RESAMPLER_DOWN_ORDER_FIR1: - for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) { - /* Integer part gives pointer to buffered input */ - buf_ptr = buf + silk_RSHIFT( index_Q16, 16 ); - - /* Inner product */ - res_Q6 = silk_SMULWB( silk_ADD32( buf_ptr[ 0 ], buf_ptr[ 23 ] ), FIR_Coefs[ 0 ] ); - res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 1 ], buf_ptr[ 22 ] ), FIR_Coefs[ 1 ] ); - res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 2 ], buf_ptr[ 21 ] ), FIR_Coefs[ 2 ] ); - res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 3 ], buf_ptr[ 20 ] ), FIR_Coefs[ 3 ] ); - res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 4 ], buf_ptr[ 19 ] ), FIR_Coefs[ 4 ] ); - res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 5 ], buf_ptr[ 18 ] ), FIR_Coefs[ 5 ] ); - res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 6 ], buf_ptr[ 17 ] ), FIR_Coefs[ 6 ] ); - res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 7 ], buf_ptr[ 16 ] ), FIR_Coefs[ 7 ] ); - res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 8 ], buf_ptr[ 15 ] ), FIR_Coefs[ 8 ] ); - res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 9 ], buf_ptr[ 14 ] ), FIR_Coefs[ 9 ] ); - res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 10 ], buf_ptr[ 13 ] ), FIR_Coefs[ 10 ] ); - res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 11 ], buf_ptr[ 12 ] ), FIR_Coefs[ 11 ] ); - - /* Scale down, saturate and store in output array */ - *out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q6, 6 ) ); - } - break; - case RESAMPLER_DOWN_ORDER_FIR2: - for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) { - /* Integer part gives pointer to buffered input */ - buf_ptr = buf + silk_RSHIFT( index_Q16, 16 ); - - /* Inner product */ - res_Q6 = silk_SMULWB( silk_ADD32( buf_ptr[ 0 ], buf_ptr[ 35 ] ), FIR_Coefs[ 0 ] ); - res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 1 ], buf_ptr[ 34 ] ), FIR_Coefs[ 1 ] ); - res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 2 ], buf_ptr[ 33 ] ), FIR_Coefs[ 2 ] ); - res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 3 ], buf_ptr[ 32 ] ), FIR_Coefs[ 3 ] ); - res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 4 ], buf_ptr[ 31 ] ), FIR_Coefs[ 4 ] ); - res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 5 ], buf_ptr[ 30 ] ), FIR_Coefs[ 5 ] ); - res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 6 ], buf_ptr[ 29 ] ), FIR_Coefs[ 6 ] ); - res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 7 ], buf_ptr[ 28 ] ), FIR_Coefs[ 7 ] ); - res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 8 ], buf_ptr[ 27 ] ), FIR_Coefs[ 8 ] ); - res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 9 ], buf_ptr[ 26 ] ), FIR_Coefs[ 9 ] ); - res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 10 ], buf_ptr[ 25 ] ), FIR_Coefs[ 10 ] ); - res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 11 ], buf_ptr[ 24 ] ), FIR_Coefs[ 11 ] ); - res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 12 ], buf_ptr[ 23 ] ), FIR_Coefs[ 12 ] ); - res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 13 ], buf_ptr[ 22 ] ), FIR_Coefs[ 13 ] ); - res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 14 ], buf_ptr[ 21 ] ), FIR_Coefs[ 14 ] ); - res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 15 ], buf_ptr[ 20 ] ), FIR_Coefs[ 15 ] ); - res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 16 ], buf_ptr[ 19 ] ), FIR_Coefs[ 16 ] ); - res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 17 ], buf_ptr[ 18 ] ), FIR_Coefs[ 17 ] ); - - /* Scale down, saturate and store in output array */ - *out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q6, 6 ) ); - } - break; - default: - silk_assert( 0 ); - } - return out; -} - -/* Resample with a 2nd order AR filter followed by FIR interpolation */ -void silk_resampler_private_down_FIR( - void *SS, /* I/O Resampler state */ - opus_int16 out[], /* O Output signal */ - const opus_int16 in[], /* I Input signal */ - opus_int32 inLen /* I Number of input samples */ -) -{ - silk_resampler_state_struct *S = (silk_resampler_state_struct *)SS; - opus_int32 nSamplesIn; - opus_int32 max_index_Q16, index_increment_Q16; - opus_int32 buf[ RESAMPLER_MAX_BATCH_SIZE_IN + SILK_RESAMPLER_MAX_FIR_ORDER ]; - const opus_int16 *FIR_Coefs; - - /* Copy buffered samples to start of buffer */ - silk_memcpy( buf, S->sFIR, S->FIR_Order * sizeof( opus_int32 ) ); - - FIR_Coefs = &S->Coefs[ 2 ]; - - /* Iterate over blocks of frameSizeIn input samples */ - index_increment_Q16 = S->invRatio_Q16; - while( 1 ) { - nSamplesIn = silk_min( inLen, S->batchSize ); - - /* Second-order AR filter (output in Q8) */ - silk_resampler_private_AR2( S->sIIR, &buf[ S->FIR_Order ], in, S->Coefs, nSamplesIn ); - - max_index_Q16 = silk_LSHIFT32( nSamplesIn, 16 ); - - /* Interpolate filtered signal */ - out = silk_resampler_private_down_FIR_INTERPOL( out, buf, FIR_Coefs, S->FIR_Order, - S->FIR_Fracs, max_index_Q16, index_increment_Q16 ); - - in += nSamplesIn; - inLen -= nSamplesIn; - - if( inLen > 1 ) { - /* More iterations to do; copy last part of filtered signal to beginning of buffer */ - silk_memcpy( buf, &buf[ nSamplesIn ], S->FIR_Order * sizeof( opus_int32 ) ); - } else { - break; - } - } - - /* Copy last part of filtered signal to the state for the next call */ - silk_memcpy( S->sFIR, &buf[ nSamplesIn ], S->FIR_Order * sizeof( opus_int32 ) ); -} diff --git a/src/opus-1.0.2/silk/resampler_private_up2_HQ.c b/src/opus-1.0.2/silk/resampler_private_up2_HQ.c deleted file mode 100644 index 9e6dfc9e..00000000 --- a/src/opus-1.0.2/silk/resampler_private_up2_HQ.c +++ /dev/null @@ -1,113 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "SigProc_FIX.h" -#include "resampler_private.h" - -/* Upsample by a factor 2, high quality */ -/* Uses 2nd order allpass filters for the 2x upsampling, followed by a */ -/* notch filter just above Nyquist. */ -void silk_resampler_private_up2_HQ( - opus_int32 *S, /* I/O Resampler state [ 6 ] */ - opus_int16 *out, /* O Output signal [ 2 * len ] */ - const opus_int16 *in, /* I Input signal [ len ] */ - opus_int32 len /* I Number of input samples */ -) -{ - opus_int32 k; - opus_int32 in32, out32_1, out32_2, Y, X; - - silk_assert( silk_resampler_up2_hq_0[ 0 ] > 0 ); - silk_assert( silk_resampler_up2_hq_0[ 1 ] > 0 ); - silk_assert( silk_resampler_up2_hq_0[ 2 ] < 0 ); - silk_assert( silk_resampler_up2_hq_1[ 0 ] > 0 ); - silk_assert( silk_resampler_up2_hq_1[ 1 ] > 0 ); - silk_assert( silk_resampler_up2_hq_1[ 2 ] < 0 ); - - /* Internal variables and state are in Q10 format */ - for( k = 0; k < len; k++ ) { - /* Convert to Q10 */ - in32 = silk_LSHIFT( (opus_int32)in[ k ], 10 ); - - /* First all-pass section for even output sample */ - Y = silk_SUB32( in32, S[ 0 ] ); - X = silk_SMULWB( Y, silk_resampler_up2_hq_0[ 0 ] ); - out32_1 = silk_ADD32( S[ 0 ], X ); - S[ 0 ] = silk_ADD32( in32, X ); - - /* Second all-pass section for even output sample */ - Y = silk_SUB32( out32_1, S[ 1 ] ); - X = silk_SMULWB( Y, silk_resampler_up2_hq_0[ 1 ] ); - out32_2 = silk_ADD32( S[ 1 ], X ); - S[ 1 ] = silk_ADD32( out32_1, X ); - - /* Third all-pass section for even output sample */ - Y = silk_SUB32( out32_2, S[ 2 ] ); - X = silk_SMLAWB( Y, Y, silk_resampler_up2_hq_0[ 2 ] ); - out32_1 = silk_ADD32( S[ 2 ], X ); - S[ 2 ] = silk_ADD32( out32_2, X ); - - /* Apply gain in Q15, convert back to int16 and store to output */ - out[ 2 * k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( out32_1, 10 ) ); - - /* First all-pass section for odd output sample */ - Y = silk_SUB32( in32, S[ 3 ] ); - X = silk_SMULWB( Y, silk_resampler_up2_hq_1[ 0 ] ); - out32_1 = silk_ADD32( S[ 3 ], X ); - S[ 3 ] = silk_ADD32( in32, X ); - - /* Second all-pass section for odd output sample */ - Y = silk_SUB32( out32_1, S[ 4 ] ); - X = silk_SMULWB( Y, silk_resampler_up2_hq_1[ 1 ] ); - out32_2 = silk_ADD32( S[ 4 ], X ); - S[ 4 ] = silk_ADD32( out32_1, X ); - - /* Third all-pass section for odd output sample */ - Y = silk_SUB32( out32_2, S[ 5 ] ); - X = silk_SMLAWB( Y, Y, silk_resampler_up2_hq_1[ 2 ] ); - out32_1 = silk_ADD32( S[ 5 ], X ); - S[ 5 ] = silk_ADD32( out32_2, X ); - - /* Apply gain in Q15, convert back to int16 and store to output */ - out[ 2 * k + 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( out32_1, 10 ) ); - } -} - -void silk_resampler_private_up2_HQ_wrapper( - void *SS, /* I/O Resampler state (unused) */ - opus_int16 *out, /* O Output signal [ 2 * len ] */ - const opus_int16 *in, /* I Input signal [ len ] */ - opus_int32 len /* I Number of input samples */ -) -{ - silk_resampler_state_struct *S = (silk_resampler_state_struct *)SS; - silk_resampler_private_up2_HQ( S->sIIR, out, in, len ); -} diff --git a/src/opus-1.0.2/silk/resampler_rom.c b/src/opus-1.0.2/silk/resampler_rom.c deleted file mode 100644 index b50af2e2..00000000 --- a/src/opus-1.0.2/silk/resampler_rom.c +++ /dev/null @@ -1,96 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* Filter coefficients for IIR/FIR polyphase resampling * - * Total size: 179 Words (358 Bytes) */ - -#include "resampler_private.h" - -/* Matlab code for the notch filter coefficients: */ -/* B = [1, 0.147, 1]; A = [1, 0.107, 0.89]; G = 0.93; freqz(G * B, A, 2^14, 16e3); axis([0, 8000, -10, 1]) */ -/* fprintf('\t%6d, %6d, %6d, %6d\n', round(B(2)*2^16), round(-A(2)*2^16), round((1-A(3))*2^16), round(G*2^15)) */ -/* const opus_int16 silk_resampler_up2_hq_notch[ 4 ] = { 9634, -7012, 7209, 30474 }; */ - -/* Tables with IIR and FIR coefficients for fractional downsamplers (123 Words) */ -silk_DWORD_ALIGN const opus_int16 silk_Resampler_3_4_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ] = { - -20694, -13867, - -49, 64, 17, -157, 353, -496, 163, 11047, 22205, - -39, 6, 91, -170, 186, 23, -896, 6336, 19928, - -19, -36, 102, -89, -24, 328, -951, 2568, 15909, -}; - -silk_DWORD_ALIGN const opus_int16 silk_Resampler_2_3_COEFS[ 2 + 2 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ] = { - -14457, -14019, - 64, 128, -122, 36, 310, -768, 584, 9267, 17733, - 12, 128, 18, -142, 288, -117, -865, 4123, 14459, -}; - -silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_2_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR1 / 2 ] = { - 616, -14323, - -10, 39, 58, -46, -84, 120, 184, -315, -541, 1284, 5380, 9024, -}; - -silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_3_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ] = { - 16102, -15162, - -13, 0, 20, 26, 5, -31, -43, -4, 65, 90, 7, -157, -248, -44, 593, 1583, 2612, 3271, -}; - -silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_4_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ] = { - 22500, -15099, - 3, -14, -20, -15, 2, 25, 37, 25, -16, -71, -107, -79, 50, 292, 623, 982, 1288, 1464, -}; - -silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_6_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ] = { - 27540, -15257, - 17, 12, 8, 1, -10, -22, -30, -32, -22, 3, 44, 100, 168, 243, 317, 381, 429, 455, -}; - -silk_DWORD_ALIGN const opus_int16 silk_Resampler_2_3_COEFS_LQ[ 2 + 2 * 2 ] = { - -2797, -6507, - 4697, 10739, - 1567, 8276, -}; - -/* Table with interplation fractions of 1/24, 3/24, 5/24, ... , 23/24 : 23/24 (46 Words) */ -silk_DWORD_ALIGN const opus_int16 silk_resampler_frac_FIR_12[ 12 ][ RESAMPLER_ORDER_FIR_12 / 2 ] = { - { 189, -600, 617, 30567 }, - { 117, -159, -1070, 29704 }, - { 52, 221, -2392, 28276 }, - { -4, 529, -3350, 26341 }, - { -48, 758, -3956, 23973 }, - { -80, 905, -4235, 21254 }, - { -99, 972, -4222, 18278 }, - { -107, 967, -3957, 15143 }, - { -103, 896, -3487, 11950 }, - { -91, 773, -2865, 8798 }, - { -71, 611, -2143, 5784 }, - { -46, 425, -1375, 2996 }, -}; diff --git a/src/opus-1.0.2/silk/resampler_rom.h b/src/opus-1.0.2/silk/resampler_rom.h deleted file mode 100644 index 473b24a2..00000000 --- a/src/opus-1.0.2/silk/resampler_rom.h +++ /dev/null @@ -1,68 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifndef SILK_FIX_RESAMPLER_ROM_H -#define SILK_FIX_RESAMPLER_ROM_H - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include "typedef.h" -#include "resampler_structs.h" - -#define RESAMPLER_DOWN_ORDER_FIR0 18 -#define RESAMPLER_DOWN_ORDER_FIR1 24 -#define RESAMPLER_DOWN_ORDER_FIR2 36 -#define RESAMPLER_ORDER_FIR_12 8 - -/* Tables for 2x downsampler */ -static const opus_int16 silk_resampler_down2_0 = 9872; -static const opus_int16 silk_resampler_down2_1 = 39809 - 65536; - -/* Tables for 2x upsampler, high quality */ -static const opus_int16 silk_resampler_up2_hq_0[ 3 ] = { 1746, 14986, 39083 - 65536 }; -static const opus_int16 silk_resampler_up2_hq_1[ 3 ] = { 6854, 25769, 55542 - 65536 }; - -/* Tables with IIR and FIR coefficients for fractional downsamplers */ -extern const opus_int16 silk_Resampler_3_4_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ]; -extern const opus_int16 silk_Resampler_2_3_COEFS[ 2 + 2 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ]; -extern const opus_int16 silk_Resampler_1_2_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR1 / 2 ]; -extern const opus_int16 silk_Resampler_1_3_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ]; -extern const opus_int16 silk_Resampler_1_4_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ]; -extern const opus_int16 silk_Resampler_1_6_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ]; -extern const opus_int16 silk_Resampler_2_3_COEFS_LQ[ 2 + 2 * 2 ]; - -/* Table with interplation fractions of 1/24, 3/24, ..., 23/24 */ -extern const opus_int16 silk_resampler_frac_FIR_12[ 12 ][ RESAMPLER_ORDER_FIR_12 / 2 ]; - -#ifdef __cplusplus -} -#endif - -#endif /* SILK_FIX_RESAMPLER_ROM_H */ diff --git a/src/opus-1.0.2/silk/resampler_structs.h b/src/opus-1.0.2/silk/resampler_structs.h deleted file mode 100644 index 4c28bd0a..00000000 --- a/src/opus-1.0.2/silk/resampler_structs.h +++ /dev/null @@ -1,57 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifndef SILK_RESAMPLER_STRUCTS_H -#define SILK_RESAMPLER_STRUCTS_H - -#ifdef __cplusplus -extern "C" { -#endif - -#define SILK_RESAMPLER_MAX_FIR_ORDER 36 -#define SILK_RESAMPLER_MAX_IIR_ORDER 6 - -typedef struct _silk_resampler_state_struct{ - opus_int32 sIIR[ SILK_RESAMPLER_MAX_IIR_ORDER ]; /* this must be the first element of this struct */ - opus_int32 sFIR[ SILK_RESAMPLER_MAX_FIR_ORDER ]; - opus_int16 delayBuf[ 48 ]; - opus_int resampler_function; - opus_int batchSize; - opus_int32 invRatio_Q16; - opus_int FIR_Order; - opus_int FIR_Fracs; - opus_int Fs_in_kHz; - opus_int Fs_out_kHz; - opus_int inputDelay; - const opus_int16 *Coefs; -} silk_resampler_state_struct; - -#ifdef __cplusplus -} -#endif -#endif /* SILK_RESAMPLER_STRUCTS_H */ - diff --git a/src/opus-1.0.2/silk/shell_coder.c b/src/opus-1.0.2/silk/shell_coder.c deleted file mode 100644 index 32d00129..00000000 --- a/src/opus-1.0.2/silk/shell_coder.c +++ /dev/null @@ -1,151 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main.h" - -/* shell coder; pulse-subframe length is hardcoded */ - -static inline void combine_pulses( - opus_int *out, /* O combined pulses vector [len] */ - const opus_int *in, /* I input vector [2 * len] */ - const opus_int len /* I number of OUTPUT samples */ -) -{ - opus_int k; - for( k = 0; k < len; k++ ) { - out[ k ] = in[ 2 * k ] + in[ 2 * k + 1 ]; - } -} - -static inline void encode_split( - ec_enc *psRangeEnc, /* I/O compressor data structure */ - const opus_int p_child1, /* I pulse amplitude of first child subframe */ - const opus_int p, /* I pulse amplitude of current subframe */ - const opus_uint8 *shell_table /* I table of shell cdfs */ -) -{ - if( p > 0 ) { - ec_enc_icdf( psRangeEnc, p_child1, &shell_table[ silk_shell_code_table_offsets[ p ] ], 8 ); - } -} - -static inline void decode_split( - opus_int *p_child1, /* O pulse amplitude of first child subframe */ - opus_int *p_child2, /* O pulse amplitude of second child subframe */ - ec_dec *psRangeDec, /* I/O Compressor data structure */ - const opus_int p, /* I pulse amplitude of current subframe */ - const opus_uint8 *shell_table /* I table of shell cdfs */ -) -{ - if( p > 0 ) { - p_child1[ 0 ] = ec_dec_icdf( psRangeDec, &shell_table[ silk_shell_code_table_offsets[ p ] ], 8 ); - p_child2[ 0 ] = p - p_child1[ 0 ]; - } else { - p_child1[ 0 ] = 0; - p_child2[ 0 ] = 0; - } -} - -/* Shell encoder, operates on one shell code frame of 16 pulses */ -void silk_shell_encoder( - ec_enc *psRangeEnc, /* I/O compressor data structure */ - const opus_int *pulses0 /* I data: nonnegative pulse amplitudes */ -) -{ - opus_int pulses1[ 8 ], pulses2[ 4 ], pulses3[ 2 ], pulses4[ 1 ]; - - /* this function operates on one shell code frame of 16 pulses */ - silk_assert( SHELL_CODEC_FRAME_LENGTH == 16 ); - - /* tree representation per pulse-subframe */ - combine_pulses( pulses1, pulses0, 8 ); - combine_pulses( pulses2, pulses1, 4 ); - combine_pulses( pulses3, pulses2, 2 ); - combine_pulses( pulses4, pulses3, 1 ); - - encode_split( psRangeEnc, pulses3[ 0 ], pulses4[ 0 ], silk_shell_code_table3 ); - - encode_split( psRangeEnc, pulses2[ 0 ], pulses3[ 0 ], silk_shell_code_table2 ); - - encode_split( psRangeEnc, pulses1[ 0 ], pulses2[ 0 ], silk_shell_code_table1 ); - encode_split( psRangeEnc, pulses0[ 0 ], pulses1[ 0 ], silk_shell_code_table0 ); - encode_split( psRangeEnc, pulses0[ 2 ], pulses1[ 1 ], silk_shell_code_table0 ); - - encode_split( psRangeEnc, pulses1[ 2 ], pulses2[ 1 ], silk_shell_code_table1 ); - encode_split( psRangeEnc, pulses0[ 4 ], pulses1[ 2 ], silk_shell_code_table0 ); - encode_split( psRangeEnc, pulses0[ 6 ], pulses1[ 3 ], silk_shell_code_table0 ); - - encode_split( psRangeEnc, pulses2[ 2 ], pulses3[ 1 ], silk_shell_code_table2 ); - - encode_split( psRangeEnc, pulses1[ 4 ], pulses2[ 2 ], silk_shell_code_table1 ); - encode_split( psRangeEnc, pulses0[ 8 ], pulses1[ 4 ], silk_shell_code_table0 ); - encode_split( psRangeEnc, pulses0[ 10 ], pulses1[ 5 ], silk_shell_code_table0 ); - - encode_split( psRangeEnc, pulses1[ 6 ], pulses2[ 3 ], silk_shell_code_table1 ); - encode_split( psRangeEnc, pulses0[ 12 ], pulses1[ 6 ], silk_shell_code_table0 ); - encode_split( psRangeEnc, pulses0[ 14 ], pulses1[ 7 ], silk_shell_code_table0 ); -} - - -/* Shell decoder, operates on one shell code frame of 16 pulses */ -void silk_shell_decoder( - opus_int *pulses0, /* O data: nonnegative pulse amplitudes */ - ec_dec *psRangeDec, /* I/O Compressor data structure */ - const opus_int pulses4 /* I number of pulses per pulse-subframe */ -) -{ - opus_int pulses3[ 2 ], pulses2[ 4 ], pulses1[ 8 ]; - - /* this function operates on one shell code frame of 16 pulses */ - silk_assert( SHELL_CODEC_FRAME_LENGTH == 16 ); - - decode_split( &pulses3[ 0 ], &pulses3[ 1 ], psRangeDec, pulses4, silk_shell_code_table3 ); - - decode_split( &pulses2[ 0 ], &pulses2[ 1 ], psRangeDec, pulses3[ 0 ], silk_shell_code_table2 ); - - decode_split( &pulses1[ 0 ], &pulses1[ 1 ], psRangeDec, pulses2[ 0 ], silk_shell_code_table1 ); - decode_split( &pulses0[ 0 ], &pulses0[ 1 ], psRangeDec, pulses1[ 0 ], silk_shell_code_table0 ); - decode_split( &pulses0[ 2 ], &pulses0[ 3 ], psRangeDec, pulses1[ 1 ], silk_shell_code_table0 ); - - decode_split( &pulses1[ 2 ], &pulses1[ 3 ], psRangeDec, pulses2[ 1 ], silk_shell_code_table1 ); - decode_split( &pulses0[ 4 ], &pulses0[ 5 ], psRangeDec, pulses1[ 2 ], silk_shell_code_table0 ); - decode_split( &pulses0[ 6 ], &pulses0[ 7 ], psRangeDec, pulses1[ 3 ], silk_shell_code_table0 ); - - decode_split( &pulses2[ 2 ], &pulses2[ 3 ], psRangeDec, pulses3[ 1 ], silk_shell_code_table2 ); - - decode_split( &pulses1[ 4 ], &pulses1[ 5 ], psRangeDec, pulses2[ 2 ], silk_shell_code_table1 ); - decode_split( &pulses0[ 8 ], &pulses0[ 9 ], psRangeDec, pulses1[ 4 ], silk_shell_code_table0 ); - decode_split( &pulses0[ 10 ], &pulses0[ 11 ], psRangeDec, pulses1[ 5 ], silk_shell_code_table0 ); - - decode_split( &pulses1[ 6 ], &pulses1[ 7 ], psRangeDec, pulses2[ 3 ], silk_shell_code_table1 ); - decode_split( &pulses0[ 12 ], &pulses0[ 13 ], psRangeDec, pulses1[ 6 ], silk_shell_code_table0 ); - decode_split( &pulses0[ 14 ], &pulses0[ 15 ], psRangeDec, pulses1[ 7 ], silk_shell_code_table0 ); -} diff --git a/src/opus-1.0.2/silk/sigm_Q15.c b/src/opus-1.0.2/silk/sigm_Q15.c deleted file mode 100644 index cf5af6bc..00000000 --- a/src/opus-1.0.2/silk/sigm_Q15.c +++ /dev/null @@ -1,76 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* Approximate sigmoid function */ - -#include "SigProc_FIX.h" - -/* fprintf(1, '%d, ', round(1024 * ([1 ./ (1 + exp(-(1:5))), 1] - 1 ./ (1 + exp(-(0:5)))))); */ -static const opus_int32 sigm_LUT_slope_Q10[ 6 ] = { - 237, 153, 73, 30, 12, 7 -}; -/* fprintf(1, '%d, ', round(32767 * 1 ./ (1 + exp(-(0:5))))); */ -static const opus_int32 sigm_LUT_pos_Q15[ 6 ] = { - 16384, 23955, 28861, 31213, 32178, 32548 -}; -/* fprintf(1, '%d, ', round(32767 * 1 ./ (1 + exp((0:5))))); */ -static const opus_int32 sigm_LUT_neg_Q15[ 6 ] = { - 16384, 8812, 3906, 1554, 589, 219 -}; - -opus_int silk_sigm_Q15( - opus_int in_Q5 /* I */ -) -{ - opus_int ind; - - if( in_Q5 < 0 ) { - /* Negative input */ - in_Q5 = -in_Q5; - if( in_Q5 >= 6 * 32 ) { - return 0; /* Clip */ - } else { - /* Linear interpolation of look up table */ - ind = silk_RSHIFT( in_Q5, 5 ); - return( sigm_LUT_neg_Q15[ ind ] - silk_SMULBB( sigm_LUT_slope_Q10[ ind ], in_Q5 & 0x1F ) ); - } - } else { - /* Positive input */ - if( in_Q5 >= 6 * 32 ) { - return 32767; /* clip */ - } else { - /* Linear interpolation of look up table */ - ind = silk_RSHIFT( in_Q5, 5 ); - return( sigm_LUT_pos_Q15[ ind ] + silk_SMULBB( sigm_LUT_slope_Q10[ ind ], in_Q5 & 0x1F ) ); - } - } -} - diff --git a/src/opus-1.0.2/silk/sort.c b/src/opus-1.0.2/silk/sort.c deleted file mode 100644 index a4072ec4..00000000 --- a/src/opus-1.0.2/silk/sort.c +++ /dev/null @@ -1,154 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -/* Insertion sort (fast for already almost sorted arrays): */ -/* Best case: O(n) for an already sorted array */ -/* Worst case: O(n^2) for an inversely sorted array */ -/* */ -/* Shell short: http://en.wikipedia.org/wiki/Shell_sort */ - -#include "SigProc_FIX.h" - -void silk_insertion_sort_increasing( - opus_int32 *a, /* I/O Unsorted / Sorted vector */ - opus_int *idx, /* O Index vector for the sorted elements */ - const opus_int L, /* I Vector length */ - const opus_int K /* I Number of correctly sorted positions */ -) -{ - opus_int32 value; - opus_int i, j; - - /* Safety checks */ - silk_assert( K > 0 ); - silk_assert( L > 0 ); - silk_assert( L >= K ); - - /* Write start indices in index vector */ - for( i = 0; i < K; i++ ) { - idx[ i ] = i; - } - - /* Sort vector elements by value, increasing order */ - for( i = 1; i < K; i++ ) { - value = a[ i ]; - for( j = i - 1; ( j >= 0 ) && ( value < a[ j ] ); j-- ) { - a[ j + 1 ] = a[ j ]; /* Shift value */ - idx[ j + 1 ] = idx[ j ]; /* Shift index */ - } - a[ j + 1 ] = value; /* Write value */ - idx[ j + 1 ] = i; /* Write index */ - } - - /* If less than L values are asked for, check the remaining values, */ - /* but only spend CPU to ensure that the K first values are correct */ - for( i = K; i < L; i++ ) { - value = a[ i ]; - if( value < a[ K - 1 ] ) { - for( j = K - 2; ( j >= 0 ) && ( value < a[ j ] ); j-- ) { - a[ j + 1 ] = a[ j ]; /* Shift value */ - idx[ j + 1 ] = idx[ j ]; /* Shift index */ - } - a[ j + 1 ] = value; /* Write value */ - idx[ j + 1 ] = i; /* Write index */ - } - } -} - -#ifdef FIXED_POINT -/* This function is only used by the fixed-point build */ -void silk_insertion_sort_decreasing_int16( - opus_int16 *a, /* I/O Unsorted / Sorted vector */ - opus_int *idx, /* O Index vector for the sorted elements */ - const opus_int L, /* I Vector length */ - const opus_int K /* I Number of correctly sorted positions */ -) -{ - opus_int i, j; - opus_int value; - - /* Safety checks */ - silk_assert( K > 0 ); - silk_assert( L > 0 ); - silk_assert( L >= K ); - - /* Write start indices in index vector */ - for( i = 0; i < K; i++ ) { - idx[ i ] = i; - } - - /* Sort vector elements by value, decreasing order */ - for( i = 1; i < K; i++ ) { - value = a[ i ]; - for( j = i - 1; ( j >= 0 ) && ( value > a[ j ] ); j-- ) { - a[ j + 1 ] = a[ j ]; /* Shift value */ - idx[ j + 1 ] = idx[ j ]; /* Shift index */ - } - a[ j + 1 ] = value; /* Write value */ - idx[ j + 1 ] = i; /* Write index */ - } - - /* If less than L values are asked for, check the remaining values, */ - /* but only spend CPU to ensure that the K first values are correct */ - for( i = K; i < L; i++ ) { - value = a[ i ]; - if( value > a[ K - 1 ] ) { - for( j = K - 2; ( j >= 0 ) && ( value > a[ j ] ); j-- ) { - a[ j + 1 ] = a[ j ]; /* Shift value */ - idx[ j + 1 ] = idx[ j ]; /* Shift index */ - } - a[ j + 1 ] = value; /* Write value */ - idx[ j + 1 ] = i; /* Write index */ - } - } -} -#endif - -void silk_insertion_sort_increasing_all_values_int16( - opus_int16 *a, /* I/O Unsorted / Sorted vector */ - const opus_int L /* I Vector length */ -) -{ - opus_int value; - opus_int i, j; - - /* Safety checks */ - silk_assert( L > 0 ); - - /* Sort vector elements by value, increasing order */ - for( i = 1; i < L; i++ ) { - value = a[ i ]; - for( j = i - 1; ( j >= 0 ) && ( value < a[ j ] ); j-- ) { - a[ j + 1 ] = a[ j ]; /* Shift value */ - } - a[ j + 1 ] = value; /* Write value */ - } -} diff --git a/src/opus-1.0.2/silk/stereo_LR_to_MS.c b/src/opus-1.0.2/silk/stereo_LR_to_MS.c deleted file mode 100644 index 6a680e09..00000000 --- a/src/opus-1.0.2/silk/stereo_LR_to_MS.c +++ /dev/null @@ -1,219 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main.h" - -/* Convert Left/Right stereo signal to adaptive Mid/Side representation */ -void silk_stereo_LR_to_MS( - stereo_enc_state *state, /* I/O State */ - opus_int16 x1[], /* I/O Left input signal, becomes mid signal */ - opus_int16 x2[], /* I/O Right input signal, becomes side signal */ - opus_int8 ix[ 2 ][ 3 ], /* O Quantization indices */ - opus_int8 *mid_only_flag, /* O Flag: only mid signal coded */ - opus_int32 mid_side_rates_bps[], /* O Bitrates for mid and side signals */ - opus_int32 total_rate_bps, /* I Total bitrate */ - opus_int prev_speech_act_Q8, /* I Speech activity level in previous frame */ - opus_int toMono, /* I Last frame before a stereo->mono transition */ - opus_int fs_kHz, /* I Sample rate (kHz) */ - opus_int frame_length /* I Number of samples */ -) -{ - opus_int n, is10msFrame, denom_Q16, delta0_Q13, delta1_Q13; - opus_int32 sum, diff, smooth_coef_Q16, pred_Q13[ 2 ], pred0_Q13, pred1_Q13; - opus_int32 LP_ratio_Q14, HP_ratio_Q14, frac_Q16, frac_3_Q16, min_mid_rate_bps, width_Q14, w_Q24, deltaw_Q24; - opus_int16 side[ MAX_FRAME_LENGTH + 2 ]; - opus_int16 LP_mid[ MAX_FRAME_LENGTH ], HP_mid[ MAX_FRAME_LENGTH ]; - opus_int16 LP_side[ MAX_FRAME_LENGTH ], HP_side[ MAX_FRAME_LENGTH ]; - opus_int16 *mid = &x1[ -2 ]; - - /* Convert to basic mid/side signals */ - for( n = 0; n < frame_length + 2; n++ ) { - sum = x1[ n - 2 ] + (opus_int32)x2[ n - 2 ]; - diff = x1[ n - 2 ] - (opus_int32)x2[ n - 2 ]; - mid[ n ] = (opus_int16)silk_RSHIFT_ROUND( sum, 1 ); - side[ n ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( diff, 1 ) ); - } - - /* Buffering */ - silk_memcpy( mid, state->sMid, 2 * sizeof( opus_int16 ) ); - silk_memcpy( side, state->sSide, 2 * sizeof( opus_int16 ) ); - silk_memcpy( state->sMid, &mid[ frame_length ], 2 * sizeof( opus_int16 ) ); - silk_memcpy( state->sSide, &side[ frame_length ], 2 * sizeof( opus_int16 ) ); - - /* LP and HP filter mid signal */ - for( n = 0; n < frame_length; n++ ) { - sum = silk_RSHIFT_ROUND( silk_ADD_LSHIFT( mid[ n ] + mid[ n + 2 ], mid[ n + 1 ], 1 ), 2 ); - LP_mid[ n ] = sum; - HP_mid[ n ] = mid[ n + 1 ] - sum; - } - - /* LP and HP filter side signal */ - for( n = 0; n < frame_length; n++ ) { - sum = silk_RSHIFT_ROUND( silk_ADD_LSHIFT( side[ n ] + side[ n + 2 ], side[ n + 1 ], 1 ), 2 ); - LP_side[ n ] = sum; - HP_side[ n ] = side[ n + 1 ] - sum; - } - - /* Find energies and predictors */ - is10msFrame = frame_length == 10 * fs_kHz; - smooth_coef_Q16 = is10msFrame ? - SILK_FIX_CONST( STEREO_RATIO_SMOOTH_COEF / 2, 16 ) : - SILK_FIX_CONST( STEREO_RATIO_SMOOTH_COEF, 16 ); - smooth_coef_Q16 = silk_SMULWB( silk_SMULBB( prev_speech_act_Q8, prev_speech_act_Q8 ), smooth_coef_Q16 ); - - pred_Q13[ 0 ] = silk_stereo_find_predictor( &LP_ratio_Q14, LP_mid, LP_side, &state->mid_side_amp_Q0[ 0 ], frame_length, smooth_coef_Q16 ); - pred_Q13[ 1 ] = silk_stereo_find_predictor( &HP_ratio_Q14, HP_mid, HP_side, &state->mid_side_amp_Q0[ 2 ], frame_length, smooth_coef_Q16 ); - /* Ratio of the norms of residual and mid signals */ - frac_Q16 = silk_SMLABB( HP_ratio_Q14, LP_ratio_Q14, 3 ); - frac_Q16 = silk_min( frac_Q16, SILK_FIX_CONST( 1, 16 ) ); - - /* Determine bitrate distribution between mid and side, and possibly reduce stereo width */ - total_rate_bps -= is10msFrame ? 1200 : 600; /* Subtract approximate bitrate for coding stereo parameters */ - if( total_rate_bps < 1 ) { - total_rate_bps = 1; - } - min_mid_rate_bps = silk_SMLABB( 2000, fs_kHz, 900 ); - silk_assert( min_mid_rate_bps < 32767 ); - /* Default bitrate distribution: 8 parts for Mid and (5+3*frac) parts for Side. so: mid_rate = ( 8 / ( 13 + 3 * frac ) ) * total_ rate */ - frac_3_Q16 = silk_MUL( 3, frac_Q16 ); - mid_side_rates_bps[ 0 ] = silk_DIV32_varQ( total_rate_bps, SILK_FIX_CONST( 8 + 5, 16 ) + frac_3_Q16, 16+3 ); - /* If Mid bitrate below minimum, reduce stereo width */ - if( mid_side_rates_bps[ 0 ] < min_mid_rate_bps ) { - mid_side_rates_bps[ 0 ] = min_mid_rate_bps; - mid_side_rates_bps[ 1 ] = total_rate_bps - mid_side_rates_bps[ 0 ]; - /* width = 4 * ( 2 * side_rate - min_rate ) / ( ( 1 + 3 * frac ) * min_rate ) */ - width_Q14 = silk_DIV32_varQ( silk_LSHIFT( mid_side_rates_bps[ 1 ], 1 ) - min_mid_rate_bps, - silk_SMULWB( SILK_FIX_CONST( 1, 16 ) + frac_3_Q16, min_mid_rate_bps ), 14+2 ); - width_Q14 = silk_LIMIT( width_Q14, 0, SILK_FIX_CONST( 1, 14 ) ); - } else { - mid_side_rates_bps[ 1 ] = total_rate_bps - mid_side_rates_bps[ 0 ]; - width_Q14 = SILK_FIX_CONST( 1, 14 ); - } - - /* Smoother */ - state->smth_width_Q14 = (opus_int16)silk_SMLAWB( state->smth_width_Q14, width_Q14 - state->smth_width_Q14, smooth_coef_Q16 ); - - /* At very low bitrates or for inputs that are nearly amplitude panned, switch to panned-mono coding */ - *mid_only_flag = 0; - if( toMono ) { - /* Last frame before stereo->mono transition; collapse stereo width */ - width_Q14 = 0; - pred_Q13[ 0 ] = 0; - pred_Q13[ 1 ] = 0; - silk_stereo_quant_pred( pred_Q13, ix ); - } else if( state->width_prev_Q14 == 0 && - ( 8 * total_rate_bps < 13 * min_mid_rate_bps || silk_SMULWB( frac_Q16, state->smth_width_Q14 ) < SILK_FIX_CONST( 0.05, 14 ) ) ) - { - /* Code as panned-mono; previous frame already had zero width */ - /* Scale down and quantize predictors */ - pred_Q13[ 0 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 0 ] ), 14 ); - pred_Q13[ 1 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 1 ] ), 14 ); - silk_stereo_quant_pred( pred_Q13, ix ); - /* Collapse stereo width */ - width_Q14 = 0; - pred_Q13[ 0 ] = 0; - pred_Q13[ 1 ] = 0; - mid_side_rates_bps[ 0 ] = total_rate_bps; - mid_side_rates_bps[ 1 ] = 0; - *mid_only_flag = 1; - } else if( state->width_prev_Q14 != 0 && - ( 8 * total_rate_bps < 11 * min_mid_rate_bps || silk_SMULWB( frac_Q16, state->smth_width_Q14 ) < SILK_FIX_CONST( 0.02, 14 ) ) ) - { - /* Transition to zero-width stereo */ - /* Scale down and quantize predictors */ - pred_Q13[ 0 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 0 ] ), 14 ); - pred_Q13[ 1 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 1 ] ), 14 ); - silk_stereo_quant_pred( pred_Q13, ix ); - /* Collapse stereo width */ - width_Q14 = 0; - pred_Q13[ 0 ] = 0; - pred_Q13[ 1 ] = 0; - } else if( state->smth_width_Q14 > SILK_FIX_CONST( 0.95, 14 ) ) { - /* Full-width stereo coding */ - silk_stereo_quant_pred( pred_Q13, ix ); - width_Q14 = SILK_FIX_CONST( 1, 14 ); - } else { - /* Reduced-width stereo coding; scale down and quantize predictors */ - pred_Q13[ 0 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 0 ] ), 14 ); - pred_Q13[ 1 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 1 ] ), 14 ); - silk_stereo_quant_pred( pred_Q13, ix ); - width_Q14 = state->smth_width_Q14; - } - - /* Make sure to keep on encoding until the tapered output has been transmitted */ - if( *mid_only_flag == 1 ) { - state->silent_side_len += frame_length - STEREO_INTERP_LEN_MS * fs_kHz; - if( state->silent_side_len < LA_SHAPE_MS * fs_kHz ) { - *mid_only_flag = 0; - } else { - /* Limit to avoid wrapping around */ - state->silent_side_len = 10000; - } - } else { - state->silent_side_len = 0; - } - - if( *mid_only_flag == 0 && mid_side_rates_bps[ 1 ] < 1 ) { - mid_side_rates_bps[ 1 ] = 1; - mid_side_rates_bps[ 0 ] = silk_max_int( 1, total_rate_bps - mid_side_rates_bps[ 1 ]); - } - - /* Interpolate predictors and subtract prediction from side channel */ - pred0_Q13 = -state->pred_prev_Q13[ 0 ]; - pred1_Q13 = -state->pred_prev_Q13[ 1 ]; - w_Q24 = silk_LSHIFT( state->width_prev_Q14, 10 ); - denom_Q16 = silk_DIV32_16( (opus_int32)1 << 16, STEREO_INTERP_LEN_MS * fs_kHz ); - delta0_Q13 = -silk_RSHIFT_ROUND( silk_SMULBB( pred_Q13[ 0 ] - state->pred_prev_Q13[ 0 ], denom_Q16 ), 16 ); - delta1_Q13 = -silk_RSHIFT_ROUND( silk_SMULBB( pred_Q13[ 1 ] - state->pred_prev_Q13[ 1 ], denom_Q16 ), 16 ); - deltaw_Q24 = silk_LSHIFT( silk_SMULWB( width_Q14 - state->width_prev_Q14, denom_Q16 ), 10 ); - for( n = 0; n < STEREO_INTERP_LEN_MS * fs_kHz; n++ ) { - pred0_Q13 += delta0_Q13; - pred1_Q13 += delta1_Q13; - w_Q24 += deltaw_Q24; - sum = silk_LSHIFT( silk_ADD_LSHIFT( mid[ n ] + mid[ n + 2 ], mid[ n + 1 ], 1 ), 9 ); /* Q11 */ - sum = silk_SMLAWB( silk_SMULWB( w_Q24, side[ n + 1 ] ), sum, pred0_Q13 ); /* Q8 */ - sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)mid[ n + 1 ], 11 ), pred1_Q13 ); /* Q8 */ - x2[ n - 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) ); - } - - pred0_Q13 = -pred_Q13[ 0 ]; - pred1_Q13 = -pred_Q13[ 1 ]; - w_Q24 = silk_LSHIFT( width_Q14, 10 ); - for( n = STEREO_INTERP_LEN_MS * fs_kHz; n < frame_length; n++ ) { - sum = silk_LSHIFT( silk_ADD_LSHIFT( mid[ n ] + mid[ n + 2 ], mid[ n + 1 ], 1 ), 9 ); /* Q11 */ - sum = silk_SMLAWB( silk_SMULWB( w_Q24, side[ n + 1 ] ), sum, pred0_Q13 ); /* Q8 */ - sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)mid[ n + 1 ], 11 ), pred1_Q13 ); /* Q8 */ - x2[ n - 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) ); - } - state->pred_prev_Q13[ 0 ] = (opus_int16)pred_Q13[ 0 ]; - state->pred_prev_Q13[ 1 ] = (opus_int16)pred_Q13[ 1 ]; - state->width_prev_Q14 = (opus_int16)width_Q14; -} diff --git a/src/opus-1.0.2/silk/stereo_MS_to_LR.c b/src/opus-1.0.2/silk/stereo_MS_to_LR.c deleted file mode 100644 index 23515870..00000000 --- a/src/opus-1.0.2/silk/stereo_MS_to_LR.c +++ /dev/null @@ -1,85 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main.h" - -/* Convert adaptive Mid/Side representation to Left/Right stereo signal */ -void silk_stereo_MS_to_LR( - stereo_dec_state *state, /* I/O State */ - opus_int16 x1[], /* I/O Left input signal, becomes mid signal */ - opus_int16 x2[], /* I/O Right input signal, becomes side signal */ - const opus_int32 pred_Q13[], /* I Predictors */ - opus_int fs_kHz, /* I Samples rate (kHz) */ - opus_int frame_length /* I Number of samples */ -) -{ - opus_int n, denom_Q16, delta0_Q13, delta1_Q13; - opus_int32 sum, diff, pred0_Q13, pred1_Q13; - - /* Buffering */ - silk_memcpy( x1, state->sMid, 2 * sizeof( opus_int16 ) ); - silk_memcpy( x2, state->sSide, 2 * sizeof( opus_int16 ) ); - silk_memcpy( state->sMid, &x1[ frame_length ], 2 * sizeof( opus_int16 ) ); - silk_memcpy( state->sSide, &x2[ frame_length ], 2 * sizeof( opus_int16 ) ); - - /* Interpolate predictors and add prediction to side channel */ - pred0_Q13 = state->pred_prev_Q13[ 0 ]; - pred1_Q13 = state->pred_prev_Q13[ 1 ]; - denom_Q16 = silk_DIV32_16( (opus_int32)1 << 16, STEREO_INTERP_LEN_MS * fs_kHz ); - delta0_Q13 = silk_RSHIFT_ROUND( silk_SMULBB( pred_Q13[ 0 ] - state->pred_prev_Q13[ 0 ], denom_Q16 ), 16 ); - delta1_Q13 = silk_RSHIFT_ROUND( silk_SMULBB( pred_Q13[ 1 ] - state->pred_prev_Q13[ 1 ], denom_Q16 ), 16 ); - for( n = 0; n < STEREO_INTERP_LEN_MS * fs_kHz; n++ ) { - pred0_Q13 += delta0_Q13; - pred1_Q13 += delta1_Q13; - sum = silk_LSHIFT( silk_ADD_LSHIFT( x1[ n ] + x1[ n + 2 ], x1[ n + 1 ], 1 ), 9 ); /* Q11 */ - sum = silk_SMLAWB( silk_LSHIFT( (opus_int32)x2[ n + 1 ], 8 ), sum, pred0_Q13 ); /* Q8 */ - sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)x1[ n + 1 ], 11 ), pred1_Q13 ); /* Q8 */ - x2[ n + 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) ); - } - pred0_Q13 = pred_Q13[ 0 ]; - pred1_Q13 = pred_Q13[ 1 ]; - for( n = STEREO_INTERP_LEN_MS * fs_kHz; n < frame_length; n++ ) { - sum = silk_LSHIFT( silk_ADD_LSHIFT( x1[ n ] + x1[ n + 2 ], x1[ n + 1 ], 1 ), 9 ); /* Q11 */ - sum = silk_SMLAWB( silk_LSHIFT( (opus_int32)x2[ n + 1 ], 8 ), sum, pred0_Q13 ); /* Q8 */ - sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)x1[ n + 1 ], 11 ), pred1_Q13 ); /* Q8 */ - x2[ n + 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) ); - } - state->pred_prev_Q13[ 0 ] = pred_Q13[ 0 ]; - state->pred_prev_Q13[ 1 ] = pred_Q13[ 1 ]; - - /* Convert to left/right signals */ - for( n = 0; n < frame_length; n++ ) { - sum = x1[ n + 1 ] + (opus_int32)x2[ n + 1 ]; - diff = x1[ n + 1 ] - (opus_int32)x2[ n + 1 ]; - x1[ n + 1 ] = (opus_int16)silk_SAT16( sum ); - x2[ n + 1 ] = (opus_int16)silk_SAT16( diff ); - } -} diff --git a/src/opus-1.0.2/silk/stereo_decode_pred.c b/src/opus-1.0.2/silk/stereo_decode_pred.c deleted file mode 100644 index 026aa7a0..00000000 --- a/src/opus-1.0.2/silk/stereo_decode_pred.c +++ /dev/null @@ -1,73 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main.h" - -/* Decode mid/side predictors */ -void silk_stereo_decode_pred( - ec_dec *psRangeDec, /* I/O Compressor data structure */ - opus_int32 pred_Q13[] /* O Predictors */ -) -{ - opus_int n, ix[ 2 ][ 3 ]; - opus_int32 low_Q13, step_Q13; - - /* Entropy decoding */ - n = ec_dec_icdf( psRangeDec, silk_stereo_pred_joint_iCDF, 8 ); - ix[ 0 ][ 2 ] = silk_DIV32_16( n, 5 ); - ix[ 1 ][ 2 ] = n - 5 * ix[ 0 ][ 2 ]; - for( n = 0; n < 2; n++ ) { - ix[ n ][ 0 ] = ec_dec_icdf( psRangeDec, silk_uniform3_iCDF, 8 ); - ix[ n ][ 1 ] = ec_dec_icdf( psRangeDec, silk_uniform5_iCDF, 8 ); - } - - /* Dequantize */ - for( n = 0; n < 2; n++ ) { - ix[ n ][ 0 ] += 3 * ix[ n ][ 2 ]; - low_Q13 = silk_stereo_pred_quant_Q13[ ix[ n ][ 0 ] ]; - step_Q13 = silk_SMULWB( silk_stereo_pred_quant_Q13[ ix[ n ][ 0 ] + 1 ] - low_Q13, - SILK_FIX_CONST( 0.5 / STEREO_QUANT_SUB_STEPS, 16 ) ); - pred_Q13[ n ] = silk_SMLABB( low_Q13, step_Q13, 2 * ix[ n ][ 1 ] + 1 ); - } - - /* Subtract second from first predictor (helps when actually applying these) */ - pred_Q13[ 0 ] -= pred_Q13[ 1 ]; -} - -/* Decode mid-only flag */ -void silk_stereo_decode_mid_only( - ec_dec *psRangeDec, /* I/O Compressor data structure */ - opus_int *decode_only_mid /* O Flag that only mid channel has been coded */ -) -{ - /* Decode flag that only mid channel is coded */ - *decode_only_mid = ec_dec_icdf( psRangeDec, silk_stereo_only_code_mid_iCDF, 8 ); -} diff --git a/src/opus-1.0.2/silk/stereo_encode_pred.c b/src/opus-1.0.2/silk/stereo_encode_pred.c deleted file mode 100644 index 3cffd367..00000000 --- a/src/opus-1.0.2/silk/stereo_encode_pred.c +++ /dev/null @@ -1,62 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main.h" - -/* Entropy code the mid/side quantization indices */ -void silk_stereo_encode_pred( - ec_enc *psRangeEnc, /* I/O Compressor data structure */ - opus_int8 ix[ 2 ][ 3 ] /* I Quantization indices */ -) -{ - opus_int n; - - /* Entropy coding */ - n = 5 * ix[ 0 ][ 2 ] + ix[ 1 ][ 2 ]; - silk_assert( n < 25 ); - ec_enc_icdf( psRangeEnc, n, silk_stereo_pred_joint_iCDF, 8 ); - for( n = 0; n < 2; n++ ) { - silk_assert( ix[ n ][ 0 ] < 3 ); - silk_assert( ix[ n ][ 1 ] < STEREO_QUANT_SUB_STEPS ); - ec_enc_icdf( psRangeEnc, ix[ n ][ 0 ], silk_uniform3_iCDF, 8 ); - ec_enc_icdf( psRangeEnc, ix[ n ][ 1 ], silk_uniform5_iCDF, 8 ); - } -} - -/* Entropy code the mid-only flag */ -void silk_stereo_encode_mid_only( - ec_enc *psRangeEnc, /* I/O Compressor data structure */ - opus_int8 mid_only_flag -) -{ - /* Encode flag that only mid channel is coded */ - ec_enc_icdf( psRangeEnc, mid_only_flag, silk_stereo_only_code_mid_iCDF, 8 ); -} diff --git a/src/opus-1.0.2/silk/stereo_find_predictor.c b/src/opus-1.0.2/silk/stereo_find_predictor.c deleted file mode 100644 index aec58dab..00000000 --- a/src/opus-1.0.2/silk/stereo_find_predictor.c +++ /dev/null @@ -1,79 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main.h" - -/* Find least-squares prediction gain for one signal based on another and quantize it */ -opus_int32 silk_stereo_find_predictor( /* O Returns predictor in Q13 */ - opus_int32 *ratio_Q14, /* O Ratio of residual and mid energies */ - const opus_int16 x[], /* I Basis signal */ - const opus_int16 y[], /* I Target signal */ - opus_int32 mid_res_amp_Q0[], /* I/O Smoothed mid, residual norms */ - opus_int length, /* I Number of samples */ - opus_int smooth_coef_Q16 /* I Smoothing coefficient */ -) -{ - opus_int scale, scale1, scale2; - opus_int32 nrgx, nrgy, corr, pred_Q13, pred2_Q10; - - /* Find predictor */ - silk_sum_sqr_shift( &nrgx, &scale1, x, length ); - silk_sum_sqr_shift( &nrgy, &scale2, y, length ); - scale = silk_max_int( scale1, scale2 ); - scale = scale + ( scale & 1 ); /* make even */ - nrgy = silk_RSHIFT32( nrgy, scale - scale2 ); - nrgx = silk_RSHIFT32( nrgx, scale - scale1 ); - nrgx = silk_max_int( nrgx, 1 ); - corr = silk_inner_prod_aligned_scale( x, y, scale, length ); - pred_Q13 = silk_DIV32_varQ( corr, nrgx, 13 ); - pred_Q13 = silk_LIMIT( pred_Q13, -(1 << 14), 1 << 14 ); - pred2_Q10 = silk_SMULWB( pred_Q13, pred_Q13 ); - - /* Faster update for signals with large prediction parameters */ - smooth_coef_Q16 = (opus_int)silk_max_int( smooth_coef_Q16, silk_abs( pred2_Q10 ) ); - - /* Smoothed mid and residual norms */ - silk_assert( smooth_coef_Q16 < 32768 ); - scale = silk_RSHIFT( scale, 1 ); - mid_res_amp_Q0[ 0 ] = silk_SMLAWB( mid_res_amp_Q0[ 0 ], silk_LSHIFT( silk_SQRT_APPROX( nrgx ), scale ) - mid_res_amp_Q0[ 0 ], - smooth_coef_Q16 ); - /* Residual energy = nrgy - 2 * pred * corr + pred^2 * nrgx */ - nrgy = silk_SUB_LSHIFT32( nrgy, silk_SMULWB( corr, pred_Q13 ), 3 + 1 ); - nrgy = silk_ADD_LSHIFT32( nrgy, silk_SMULWB( nrgx, pred2_Q10 ), 6 ); - mid_res_amp_Q0[ 1 ] = silk_SMLAWB( mid_res_amp_Q0[ 1 ], silk_LSHIFT( silk_SQRT_APPROX( nrgy ), scale ) - mid_res_amp_Q0[ 1 ], - smooth_coef_Q16 ); - - /* Ratio of smoothed residual and mid norms */ - *ratio_Q14 = silk_DIV32_varQ( mid_res_amp_Q0[ 1 ], silk_max( mid_res_amp_Q0[ 0 ], 1 ), 14 ); - *ratio_Q14 = silk_LIMIT( *ratio_Q14, 0, 32767 ); - - return pred_Q13; -} diff --git a/src/opus-1.0.2/silk/stereo_quant_pred.c b/src/opus-1.0.2/silk/stereo_quant_pred.c deleted file mode 100644 index df97c9f6..00000000 --- a/src/opus-1.0.2/silk/stereo_quant_pred.c +++ /dev/null @@ -1,73 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "main.h" - -/* Quantize mid/side predictors */ -void silk_stereo_quant_pred( - opus_int32 pred_Q13[], /* I/O Predictors (out: quantized) */ - opus_int8 ix[ 2 ][ 3 ] /* O Quantization indices */ -) -{ - opus_int i, j, n; - opus_int32 low_Q13, step_Q13, lvl_Q13, err_min_Q13, err_Q13, quant_pred_Q13 = 0; - - /* Quantize */ - for( n = 0; n < 2; n++ ) { - /* Brute-force search over quantization levels */ - err_min_Q13 = silk_int32_MAX; - for( i = 0; i < STEREO_QUANT_TAB_SIZE - 1; i++ ) { - low_Q13 = silk_stereo_pred_quant_Q13[ i ]; - step_Q13 = silk_SMULWB( silk_stereo_pred_quant_Q13[ i + 1 ] - low_Q13, - SILK_FIX_CONST( 0.5 / STEREO_QUANT_SUB_STEPS, 16 ) ); - for( j = 0; j < STEREO_QUANT_SUB_STEPS; j++ ) { - lvl_Q13 = silk_SMLABB( low_Q13, step_Q13, 2 * j + 1 ); - err_Q13 = silk_abs( pred_Q13[ n ] - lvl_Q13 ); - if( err_Q13 < err_min_Q13 ) { - err_min_Q13 = err_Q13; - quant_pred_Q13 = lvl_Q13; - ix[ n ][ 0 ] = i; - ix[ n ][ 1 ] = j; - } else { - /* Error increasing, so we're past the optimum */ - goto done; - } - } - } - done: - ix[ n ][ 2 ] = silk_DIV32_16( ix[ n ][ 0 ], 3 ); - ix[ n ][ 0 ] -= ix[ n ][ 2 ] * 3; - pred_Q13[ n ] = quant_pred_Q13; - } - - /* Subtract second from first predictor (helps when actually applying these) */ - pred_Q13[ 0 ] -= pred_Q13[ 1 ]; -} diff --git a/src/opus-1.0.2/silk/structs.h b/src/opus-1.0.2/silk/structs.h deleted file mode 100644 index 5d37f660..00000000 --- a/src/opus-1.0.2/silk/structs.h +++ /dev/null @@ -1,324 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifndef SILK_STRUCTS_H -#define SILK_STRUCTS_H - -#include "typedef.h" -#include "SigProc_FIX.h" -#include "define.h" -#include "entenc.h" -#include "entdec.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -/************************************/ -/* Noise shaping quantization state */ -/************************************/ -typedef struct { - opus_int16 xq[ 2 * MAX_FRAME_LENGTH ]; /* Buffer for quantized output signal */ - opus_int32 sLTP_shp_Q14[ 2 * MAX_FRAME_LENGTH ]; - opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ]; - opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ]; - opus_int32 sLF_AR_shp_Q14; - opus_int lagPrev; - opus_int sLTP_buf_idx; - opus_int sLTP_shp_buf_idx; - opus_int32 rand_seed; - opus_int32 prev_gain_Q16; - opus_int rewhite_flag; -} silk_nsq_state; - -/********************************/ -/* VAD state */ -/********************************/ -typedef struct { - opus_int32 AnaState[ 2 ]; /* Analysis filterbank state: 0-8 kHz */ - opus_int32 AnaState1[ 2 ]; /* Analysis filterbank state: 0-4 kHz */ - opus_int32 AnaState2[ 2 ]; /* Analysis filterbank state: 0-2 kHz */ - opus_int32 XnrgSubfr[ VAD_N_BANDS ]; /* Subframe energies */ - opus_int32 NrgRatioSmth_Q8[ VAD_N_BANDS ]; /* Smoothed energy level in each band */ - opus_int16 HPstate; /* State of differentiator in the lowest band */ - opus_int32 NL[ VAD_N_BANDS ]; /* Noise energy level in each band */ - opus_int32 inv_NL[ VAD_N_BANDS ]; /* Inverse noise energy level in each band */ - opus_int32 NoiseLevelBias[ VAD_N_BANDS ]; /* Noise level estimator bias/offset */ - opus_int32 counter; /* Frame counter used in the initial phase */ -} silk_VAD_state; - -/* Variable cut-off low-pass filter state */ -typedef struct { - opus_int32 In_LP_State[ 2 ]; /* Low pass filter state */ - opus_int32 transition_frame_no; /* Counter which is mapped to a cut-off frequency */ - opus_int mode; /* Operating mode, <0: switch down, >0: switch up; 0: do nothing */ -} silk_LP_state; - -/* Structure containing NLSF codebook */ -typedef struct { - const opus_int16 nVectors; - const opus_int16 order; - const opus_int16 quantStepSize_Q16; - const opus_int16 invQuantStepSize_Q6; - const opus_uint8 *CB1_NLSF_Q8; - const opus_uint8 *CB1_iCDF; - const opus_uint8 *pred_Q8; - const opus_uint8 *ec_sel; - const opus_uint8 *ec_iCDF; - const opus_uint8 *ec_Rates_Q5; - const opus_int16 *deltaMin_Q15; -} silk_NLSF_CB_struct; - -typedef struct { - opus_int16 pred_prev_Q13[ 2 ]; - opus_int16 sMid[ 2 ]; - opus_int16 sSide[ 2 ]; - opus_int32 mid_side_amp_Q0[ 4 ]; - opus_int16 smth_width_Q14; - opus_int16 width_prev_Q14; - opus_int16 silent_side_len; - opus_int8 predIx[ MAX_FRAMES_PER_PACKET ][ 2 ][ 3 ]; - opus_int8 mid_only_flags[ MAX_FRAMES_PER_PACKET ]; -} stereo_enc_state; - -typedef struct { - opus_int16 pred_prev_Q13[ 2 ]; - opus_int16 sMid[ 2 ]; - opus_int16 sSide[ 2 ]; -} stereo_dec_state; - -typedef struct { - opus_int8 GainsIndices[ MAX_NB_SUBFR ]; - opus_int8 LTPIndex[ MAX_NB_SUBFR ]; - opus_int8 NLSFIndices[ MAX_LPC_ORDER + 1 ]; - opus_int16 lagIndex; - opus_int8 contourIndex; - opus_int8 signalType; - opus_int8 quantOffsetType; - opus_int8 NLSFInterpCoef_Q2; - opus_int8 PERIndex; - opus_int8 LTP_scaleIndex; - opus_int8 Seed; -} SideInfoIndices; - -/********************************/ -/* Encoder state */ -/********************************/ -typedef struct { - opus_int32 In_HP_State[ 2 ]; /* High pass filter state */ - opus_int32 variable_HP_smth1_Q15; /* State of first smoother */ - opus_int32 variable_HP_smth2_Q15; /* State of second smoother */ - silk_LP_state sLP; /* Low pass filter state */ - silk_VAD_state sVAD; /* Voice activity detector state */ - silk_nsq_state sNSQ; /* Noise Shape Quantizer State */ - opus_int16 prev_NLSFq_Q15[ MAX_LPC_ORDER ]; /* Previously quantized NLSF vector */ - opus_int speech_activity_Q8; /* Speech activity */ - opus_int allow_bandwidth_switch; /* Flag indicating that switching of internal bandwidth is allowed */ - opus_int8 LBRRprevLastGainIndex; - opus_int8 prevSignalType; - opus_int prevLag; - opus_int pitch_LPC_win_length; - opus_int max_pitch_lag; /* Highest possible pitch lag (samples) */ - opus_int32 API_fs_Hz; /* API sampling frequency (Hz) */ - opus_int32 prev_API_fs_Hz; /* Previous API sampling frequency (Hz) */ - opus_int maxInternal_fs_Hz; /* Maximum internal sampling frequency (Hz) */ - opus_int minInternal_fs_Hz; /* Minimum internal sampling frequency (Hz) */ - opus_int desiredInternal_fs_Hz; /* Soft request for internal sampling frequency (Hz) */ - opus_int fs_kHz; /* Internal sampling frequency (kHz) */ - opus_int nb_subfr; /* Number of 5 ms subframes in a frame */ - opus_int frame_length; /* Frame length (samples) */ - opus_int subfr_length; /* Subframe length (samples) */ - opus_int ltp_mem_length; /* Length of LTP memory */ - opus_int la_pitch; /* Look-ahead for pitch analysis (samples) */ - opus_int la_shape; /* Look-ahead for noise shape analysis (samples) */ - opus_int shapeWinLength; /* Window length for noise shape analysis (samples) */ - opus_int32 TargetRate_bps; /* Target bitrate (bps) */ - opus_int PacketSize_ms; /* Number of milliseconds to put in each packet */ - opus_int PacketLoss_perc; /* Packet loss rate measured by farend */ - opus_int32 frameCounter; - opus_int Complexity; /* Complexity setting */ - opus_int nStatesDelayedDecision; /* Number of states in delayed decision quantization */ - opus_int useInterpolatedNLSFs; /* Flag for using NLSF interpolation */ - opus_int shapingLPCOrder; /* Filter order for noise shaping filters */ - opus_int predictLPCOrder; /* Filter order for prediction filters */ - opus_int pitchEstimationComplexity; /* Complexity level for pitch estimator */ - opus_int pitchEstimationLPCOrder; /* Whitening filter order for pitch estimator */ - opus_int32 pitchEstimationThreshold_Q16; /* Threshold for pitch estimator */ - opus_int LTPQuantLowComplexity; /* Flag for low complexity LTP quantization */ - opus_int mu_LTP_Q9; /* Rate-distortion tradeoff in LTP quantization */ - opus_int NLSF_MSVQ_Survivors; /* Number of survivors in NLSF MSVQ */ - opus_int first_frame_after_reset; /* Flag for deactivating NLSF interpolation, pitch prediction */ - opus_int controlled_since_last_payload; /* Flag for ensuring codec_control only runs once per packet */ - opus_int warping_Q16; /* Warping parameter for warped noise shaping */ - opus_int useCBR; /* Flag to enable constant bitrate */ - opus_int prefillFlag; /* Flag to indicate that only buffers are prefilled, no coding */ - const opus_uint8 *pitch_lag_low_bits_iCDF; /* Pointer to iCDF table for low bits of pitch lag index */ - const opus_uint8 *pitch_contour_iCDF; /* Pointer to iCDF table for pitch contour index */ - const silk_NLSF_CB_struct *psNLSF_CB; /* Pointer to NLSF codebook */ - opus_int input_quality_bands_Q15[ VAD_N_BANDS ]; - opus_int input_tilt_Q15; - opus_int SNR_dB_Q7; /* Quality setting */ - - opus_int8 VAD_flags[ MAX_FRAMES_PER_PACKET ]; - opus_int8 LBRR_flag; - opus_int LBRR_flags[ MAX_FRAMES_PER_PACKET ]; - - SideInfoIndices indices; - opus_int8 pulses[ MAX_FRAME_LENGTH ]; - - /* Input/output buffering */ - opus_int16 inputBuf[ MAX_FRAME_LENGTH + 2 ]; /* Buffer containing input signal */ - opus_int inputBufIx; - opus_int nFramesPerPacket; - opus_int nFramesEncoded; /* Number of frames analyzed in current packet */ - - opus_int nChannelsAPI; - opus_int nChannelsInternal; - opus_int channelNb; - - /* Parameters For LTP scaling Control */ - opus_int frames_since_onset; - - /* Specifically for entropy coding */ - opus_int ec_prevSignalType; - opus_int16 ec_prevLagIndex; - - silk_resampler_state_struct resampler_state; - - /* DTX */ - opus_int useDTX; /* Flag to enable DTX */ - opus_int inDTX; /* Flag to signal DTX period */ - opus_int noSpeechCounter; /* Counts concecutive nonactive frames, used by DTX */ - - /* Inband Low Bitrate Redundancy (LBRR) data */ - opus_int useInBandFEC; /* Saves the API setting for query */ - opus_int LBRR_enabled; /* Depends on useInBandFRC, bitrate and packet loss rate */ - opus_int LBRR_GainIncreases; /* Gains increment for coding LBRR frames */ - SideInfoIndices indices_LBRR[ MAX_FRAMES_PER_PACKET ]; - opus_int8 pulses_LBRR[ MAX_FRAMES_PER_PACKET ][ MAX_FRAME_LENGTH ]; -} silk_encoder_state; - - -/* Struct for Packet Loss Concealment */ -typedef struct { - opus_int32 pitchL_Q8; /* Pitch lag to use for voiced concealment */ - opus_int16 LTPCoef_Q14[ LTP_ORDER ]; /* LTP coeficients to use for voiced concealment */ - opus_int16 prevLPC_Q12[ MAX_LPC_ORDER ]; - opus_int last_frame_lost; /* Was previous frame lost */ - opus_int32 rand_seed; /* Seed for unvoiced signal generation */ - opus_int16 randScale_Q14; /* Scaling of unvoiced random signal */ - opus_int32 conc_energy; - opus_int conc_energy_shift; - opus_int16 prevLTP_scale_Q14; - opus_int32 prevGain_Q16[ 2 ]; - opus_int fs_kHz; - opus_int nb_subfr; - opus_int subfr_length; -} silk_PLC_struct; - -/* Struct for CNG */ -typedef struct { - opus_int32 CNG_exc_buf_Q14[ MAX_FRAME_LENGTH ]; - opus_int16 CNG_smth_NLSF_Q15[ MAX_LPC_ORDER ]; - opus_int32 CNG_synth_state[ MAX_LPC_ORDER ]; - opus_int32 CNG_smth_Gain_Q16; - opus_int32 rand_seed; - opus_int fs_kHz; -} silk_CNG_struct; - -/********************************/ -/* Decoder state */ -/********************************/ -typedef struct { - opus_int32 prev_gain_Q16; - opus_int32 exc_Q14[ MAX_FRAME_LENGTH ]; - opus_int32 sLPC_Q14_buf[ MAX_LPC_ORDER ]; - opus_int16 outBuf[ MAX_FRAME_LENGTH + 2 * MAX_SUB_FRAME_LENGTH ]; /* Buffer for output signal */ - opus_int lagPrev; /* Previous Lag */ - opus_int8 LastGainIndex; /* Previous gain index */ - opus_int fs_kHz; /* Sampling frequency in kHz */ - opus_int32 fs_API_hz; /* API sample frequency (Hz) */ - opus_int nb_subfr; /* Number of 5 ms subframes in a frame */ - opus_int frame_length; /* Frame length (samples) */ - opus_int subfr_length; /* Subframe length (samples) */ - opus_int ltp_mem_length; /* Length of LTP memory */ - opus_int LPC_order; /* LPC order */ - opus_int16 prevNLSF_Q15[ MAX_LPC_ORDER ]; /* Used to interpolate LSFs */ - opus_int first_frame_after_reset; /* Flag for deactivating NLSF interpolation */ - const opus_uint8 *pitch_lag_low_bits_iCDF; /* Pointer to iCDF table for low bits of pitch lag index */ - const opus_uint8 *pitch_contour_iCDF; /* Pointer to iCDF table for pitch contour index */ - - /* For buffering payload in case of more frames per packet */ - opus_int nFramesDecoded; - opus_int nFramesPerPacket; - - /* Specifically for entropy coding */ - opus_int ec_prevSignalType; - opus_int16 ec_prevLagIndex; - - opus_int VAD_flags[ MAX_FRAMES_PER_PACKET ]; - opus_int LBRR_flag; - opus_int LBRR_flags[ MAX_FRAMES_PER_PACKET ]; - - silk_resampler_state_struct resampler_state; - - const silk_NLSF_CB_struct *psNLSF_CB; /* Pointer to NLSF codebook */ - - /* Quantization indices */ - SideInfoIndices indices; - - /* CNG state */ - silk_CNG_struct sCNG; - - /* Stuff used for PLC */ - opus_int lossCnt; - opus_int prevSignalType; - - silk_PLC_struct sPLC; - -} silk_decoder_state; - -/************************/ -/* Decoder control */ -/************************/ -typedef struct { - /* Prediction and coding parameters */ - opus_int pitchL[ MAX_NB_SUBFR ]; - opus_int32 Gains_Q16[ MAX_NB_SUBFR ]; - /* Holds interpolated and final coefficients, 4-byte aligned */ - silk_DWORD_ALIGN opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ]; - opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ]; - opus_int LTP_scale_Q14; -} silk_decoder_control; - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/opus-1.0.2/silk/sum_sqr_shift.c b/src/opus-1.0.2/silk/sum_sqr_shift.c deleted file mode 100644 index 2eaf77b6..00000000 --- a/src/opus-1.0.2/silk/sum_sqr_shift.c +++ /dev/null @@ -1,85 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "SigProc_FIX.h" - -/* Compute number of bits to right shift the sum of squares of a vector */ -/* of int16s to make it fit in an int32 */ -void silk_sum_sqr_shift( - opus_int32 *energy, /* O Energy of x, after shifting to the right */ - opus_int *shift, /* O Number of bits right shift applied to energy */ - const opus_int16 *x, /* I Input vector */ - opus_int len /* I Length of input vector */ -) -{ - opus_int i, shft; - opus_int32 nrg_tmp, nrg; - - nrg = 0; - shft = 0; - len--; - for( i = 0; i < len; i += 2 ) { - nrg = silk_SMLABB_ovflw( nrg, x[ i ], x[ i ] ); - nrg = silk_SMLABB_ovflw( nrg, x[ i + 1 ], x[ i + 1 ] ); - if( nrg < 0 ) { - /* Scale down */ - nrg = (opus_int32)silk_RSHIFT_uint( (opus_uint32)nrg, 2 ); - shft = 2; - break; - } - } - for( ; i < len; i += 2 ) { - nrg_tmp = silk_SMULBB( x[ i ], x[ i ] ); - nrg_tmp = silk_SMLABB_ovflw( nrg_tmp, x[ i + 1 ], x[ i + 1 ] ); - nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, (opus_uint32)nrg_tmp, shft ); - if( nrg < 0 ) { - /* Scale down */ - nrg = (opus_int32)silk_RSHIFT_uint( (opus_uint32)nrg, 2 ); - shft += 2; - } - } - if( i == len ) { - /* One sample left to process */ - nrg_tmp = silk_SMULBB( x[ i ], x[ i ] ); - nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft ); - } - - /* Make sure to have at least one extra leading zero (two leading zeros in total) */ - if( nrg & 0xC0000000 ) { - nrg = silk_RSHIFT_uint( (opus_uint32)nrg, 2 ); - shft += 2; - } - - /* Output arguments */ - *shift = shft; - *energy = nrg; -} - diff --git a/src/opus-1.0.2/silk/table_LSF_cos.c b/src/opus-1.0.2/silk/table_LSF_cos.c deleted file mode 100644 index 710537fb..00000000 --- a/src/opus-1.0.2/silk/table_LSF_cos.c +++ /dev/null @@ -1,70 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "tables.h" - -/* Cosine approximation table for LSF conversion */ -/* Q12 values (even) */ -const opus_int16 silk_LSFCosTab_FIX_Q12[ LSF_COS_TAB_SZ_FIX + 1 ] = { - 8192, 8190, 8182, 8170, - 8152, 8130, 8104, 8072, - 8034, 7994, 7946, 7896, - 7840, 7778, 7714, 7644, - 7568, 7490, 7406, 7318, - 7226, 7128, 7026, 6922, - 6812, 6698, 6580, 6458, - 6332, 6204, 6070, 5934, - 5792, 5648, 5502, 5352, - 5198, 5040, 4880, 4718, - 4552, 4382, 4212, 4038, - 3862, 3684, 3502, 3320, - 3136, 2948, 2760, 2570, - 2378, 2186, 1990, 1794, - 1598, 1400, 1202, 1002, - 802, 602, 402, 202, - 0, -202, -402, -602, - -802, -1002, -1202, -1400, - -1598, -1794, -1990, -2186, - -2378, -2570, -2760, -2948, - -3136, -3320, -3502, -3684, - -3862, -4038, -4212, -4382, - -4552, -4718, -4880, -5040, - -5198, -5352, -5502, -5648, - -5792, -5934, -6070, -6204, - -6332, -6458, -6580, -6698, - -6812, -6922, -7026, -7128, - -7226, -7318, -7406, -7490, - -7568, -7644, -7714, -7778, - -7840, -7896, -7946, -7994, - -8034, -8072, -8104, -8130, - -8152, -8170, -8182, -8190, - -8192 -}; diff --git a/src/opus-1.0.2/silk/tables.h b/src/opus-1.0.2/silk/tables.h deleted file mode 100644 index 072b7929..00000000 --- a/src/opus-1.0.2/silk/tables.h +++ /dev/null @@ -1,120 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifndef SILK_TABLES_H -#define SILK_TABLES_H - -#include "define.h" -#include "structs.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -/* Entropy coding tables (with size in bytes indicated) */ -extern const opus_uint8 silk_gain_iCDF[ 3 ][ N_LEVELS_QGAIN / 8 ]; /* 24 */ -extern const opus_uint8 silk_delta_gain_iCDF[ MAX_DELTA_GAIN_QUANT - MIN_DELTA_GAIN_QUANT + 1 ]; /* 41 */ - -extern const opus_uint8 silk_pitch_lag_iCDF[ 2 * ( PITCH_EST_MAX_LAG_MS - PITCH_EST_MIN_LAG_MS ) ];/* 32 */ -extern const opus_uint8 silk_pitch_delta_iCDF[ 21 ]; /* 21 */ -extern const opus_uint8 silk_pitch_contour_iCDF[ 34 ]; /* 34 */ -extern const opus_uint8 silk_pitch_contour_NB_iCDF[ 11 ]; /* 11 */ -extern const opus_uint8 silk_pitch_contour_10_ms_iCDF[ 12 ]; /* 12 */ -extern const opus_uint8 silk_pitch_contour_10_ms_NB_iCDF[ 3 ]; /* 3 */ - -extern const opus_uint8 silk_pulses_per_block_iCDF[ N_RATE_LEVELS ][ MAX_PULSES + 2 ]; /* 180 */ -extern const opus_uint8 silk_pulses_per_block_BITS_Q5[ N_RATE_LEVELS - 1 ][ MAX_PULSES + 2 ]; /* 162 */ - -extern const opus_uint8 silk_rate_levels_iCDF[ 2 ][ N_RATE_LEVELS - 1 ]; /* 18 */ -extern const opus_uint8 silk_rate_levels_BITS_Q5[ 2 ][ N_RATE_LEVELS - 1 ]; /* 18 */ - -extern const opus_uint8 silk_max_pulses_table[ 4 ]; /* 4 */ - -extern const opus_uint8 silk_shell_code_table0[ 152 ]; /* 152 */ -extern const opus_uint8 silk_shell_code_table1[ 152 ]; /* 152 */ -extern const opus_uint8 silk_shell_code_table2[ 152 ]; /* 152 */ -extern const opus_uint8 silk_shell_code_table3[ 152 ]; /* 152 */ -extern const opus_uint8 silk_shell_code_table_offsets[ MAX_PULSES + 1 ]; /* 17 */ - -extern const opus_uint8 silk_lsb_iCDF[ 2 ]; /* 2 */ - -extern const opus_uint8 silk_sign_iCDF[ 42 ]; /* 42 */ - -extern const opus_uint8 silk_uniform3_iCDF[ 3 ]; /* 3 */ -extern const opus_uint8 silk_uniform4_iCDF[ 4 ]; /* 4 */ -extern const opus_uint8 silk_uniform5_iCDF[ 5 ]; /* 5 */ -extern const opus_uint8 silk_uniform6_iCDF[ 6 ]; /* 6 */ -extern const opus_uint8 silk_uniform8_iCDF[ 8 ]; /* 8 */ - -extern const opus_uint8 silk_NLSF_EXT_iCDF[ 7 ]; /* 7 */ - -extern const opus_uint8 silk_LTP_per_index_iCDF[ 3 ]; /* 3 */ -extern const opus_uint8 * const silk_LTP_gain_iCDF_ptrs[ NB_LTP_CBKS ]; /* 3 */ -extern const opus_uint8 * const silk_LTP_gain_BITS_Q5_ptrs[ NB_LTP_CBKS ]; /* 3 */ -extern const opus_int16 silk_LTP_gain_middle_avg_RD_Q14; -extern const opus_int8 * const silk_LTP_vq_ptrs_Q7[ NB_LTP_CBKS ]; /* 168 */ -extern const opus_int8 silk_LTP_vq_sizes[ NB_LTP_CBKS ]; /* 3 */ - -extern const opus_uint8 silk_LTPscale_iCDF[ 3 ]; /* 4 */ -extern const opus_int16 silk_LTPScales_table_Q14[ 3 ]; /* 6 */ - -extern const opus_uint8 silk_type_offset_VAD_iCDF[ 4 ]; /* 4 */ -extern const opus_uint8 silk_type_offset_no_VAD_iCDF[ 2 ]; /* 2 */ - -extern const opus_int16 silk_stereo_pred_quant_Q13[ STEREO_QUANT_TAB_SIZE ]; /* 32 */ -extern const opus_uint8 silk_stereo_pred_joint_iCDF[ 25 ]; /* 25 */ -extern const opus_uint8 silk_stereo_only_code_mid_iCDF[ 2 ]; /* 2 */ - -extern const opus_uint8 * const silk_LBRR_flags_iCDF_ptr[ 2 ]; /* 10 */ - -extern const opus_uint8 silk_NLSF_interpolation_factor_iCDF[ 5 ]; /* 5 */ - -extern const silk_NLSF_CB_struct silk_NLSF_CB_WB; /* 1040 */ -extern const silk_NLSF_CB_struct silk_NLSF_CB_NB_MB; /* 728 */ - -/* Piece-wise linear mapping from bitrate in kbps to coding quality in dB SNR */ -extern const opus_int32 silk_TargetRate_table_NB[ TARGET_RATE_TAB_SZ ]; /* 32 */ -extern const opus_int32 silk_TargetRate_table_MB[ TARGET_RATE_TAB_SZ ]; /* 32 */ -extern const opus_int32 silk_TargetRate_table_WB[ TARGET_RATE_TAB_SZ ]; /* 32 */ -extern const opus_int16 silk_SNR_table_Q1[ TARGET_RATE_TAB_SZ ]; /* 32 */ - -/* Quantization offsets */ -extern const opus_int16 silk_Quantization_Offsets_Q10[ 2 ][ 2 ]; /* 8 */ - -/* Interpolation points for filter coefficients used in the bandwidth transition smoother */ -extern const opus_int32 silk_Transition_LP_B_Q28[ TRANSITION_INT_NUM ][ TRANSITION_NB ]; /* 60 */ -extern const opus_int32 silk_Transition_LP_A_Q28[ TRANSITION_INT_NUM ][ TRANSITION_NA ]; /* 60 */ - -/* Rom table with cosine values */ -extern const opus_int16 silk_LSFCosTab_FIX_Q12[ LSF_COS_TAB_SZ_FIX + 1 ]; /* 258 */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/opus-1.0.2/silk/tables_LTP.c b/src/opus-1.0.2/silk/tables_LTP.c deleted file mode 100644 index dd1fb556..00000000 --- a/src/opus-1.0.2/silk/tables_LTP.c +++ /dev/null @@ -1,272 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "tables.h" - -const opus_uint8 silk_LTP_per_index_iCDF[3] = { - 179, 99, 0 -}; - -static const opus_uint8 silk_LTP_gain_iCDF_0[8] = { - 71, 56, 43, 30, 21, 12, 6, 0 -}; - -static const opus_uint8 silk_LTP_gain_iCDF_1[16] = { - 199, 165, 144, 124, 109, 96, 84, 71, - 61, 51, 42, 32, 23, 15, 8, 0 -}; - -static const opus_uint8 silk_LTP_gain_iCDF_2[32] = { - 241, 225, 211, 199, 187, 175, 164, 153, - 142, 132, 123, 114, 105, 96, 88, 80, - 72, 64, 57, 50, 44, 38, 33, 29, - 24, 20, 16, 12, 9, 5, 2, 0 -}; - -const opus_int16 silk_LTP_gain_middle_avg_RD_Q14 = 12304; - -static const opus_uint8 silk_LTP_gain_BITS_Q5_0[8] = { - 15, 131, 138, 138, 155, 155, 173, 173 -}; - -static const opus_uint8 silk_LTP_gain_BITS_Q5_1[16] = { - 69, 93, 115, 118, 131, 138, 141, 138, - 150, 150, 155, 150, 155, 160, 166, 160 -}; - -static const opus_uint8 silk_LTP_gain_BITS_Q5_2[32] = { - 131, 128, 134, 141, 141, 141, 145, 145, - 145, 150, 155, 155, 155, 155, 160, 160, - 160, 160, 166, 166, 173, 173, 182, 192, - 182, 192, 192, 192, 205, 192, 205, 224 -}; - -const opus_uint8 * const silk_LTP_gain_iCDF_ptrs[NB_LTP_CBKS] = { - silk_LTP_gain_iCDF_0, - silk_LTP_gain_iCDF_1, - silk_LTP_gain_iCDF_2 -}; - -const opus_uint8 * const silk_LTP_gain_BITS_Q5_ptrs[NB_LTP_CBKS] = { - silk_LTP_gain_BITS_Q5_0, - silk_LTP_gain_BITS_Q5_1, - silk_LTP_gain_BITS_Q5_2 -}; - -static const opus_int8 silk_LTP_gain_vq_0[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 opus_int8 silk_LTP_gain_vq_1[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 opus_int8 silk_LTP_gain_vq_2[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 -} -}; - -const opus_int8 * const silk_LTP_vq_ptrs_Q7[NB_LTP_CBKS] = { - (opus_int8 *)&silk_LTP_gain_vq_0[0][0], - (opus_int8 *)&silk_LTP_gain_vq_1[0][0], - (opus_int8 *)&silk_LTP_gain_vq_2[0][0] -}; - -const opus_int8 silk_LTP_vq_sizes[NB_LTP_CBKS] = { - 8, 16, 32 -}; diff --git a/src/opus-1.0.2/silk/tables_NLSF_CB_NB_MB.c b/src/opus-1.0.2/silk/tables_NLSF_CB_NB_MB.c deleted file mode 100644 index 75480526..00000000 --- a/src/opus-1.0.2/silk/tables_NLSF_CB_NB_MB.c +++ /dev/null @@ -1,159 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "tables.h" - -static const opus_uint8 silk_NLSF_CB1_NB_MB_Q8[ 320 ] = { - 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 opus_uint8 silk_NLSF_CB1_iCDF_NB_MB[ 64 ] = { - 212, 178, 148, 129, 108, 96, 85, 82, - 79, 77, 61, 59, 57, 56, 51, 49, - 48, 45, 42, 41, 40, 38, 36, 34, - 31, 30, 21, 12, 10, 3, 1, 0, - 255, 245, 244, 236, 233, 225, 217, 203, - 190, 176, 175, 161, 149, 136, 125, 114, - 102, 91, 81, 71, 60, 52, 43, 35, - 28, 20, 19, 18, 12, 11, 5, 0 -}; - -static const opus_uint8 silk_NLSF_CB2_SELECT_NB_MB[ 160 ] = { - 16, 0, 0, 0, 0, 99, 66, 36, - 36, 34, 36, 34, 34, 34, 34, 83, - 69, 36, 52, 34, 116, 102, 70, 68, - 68, 176, 102, 68, 68, 34, 65, 85, - 68, 84, 36, 116, 141, 152, 139, 170, - 132, 187, 184, 216, 137, 132, 249, 168, - 185, 139, 104, 102, 100, 68, 68, 178, - 218, 185, 185, 170, 244, 216, 187, 187, - 170, 244, 187, 187, 219, 138, 103, 155, - 184, 185, 137, 116, 183, 155, 152, 136, - 132, 217, 184, 184, 170, 164, 217, 171, - 155, 139, 244, 169, 184, 185, 170, 164, - 216, 223, 218, 138, 214, 143, 188, 218, - 168, 244, 141, 136, 155, 170, 168, 138, - 220, 219, 139, 164, 219, 202, 216, 137, - 168, 186, 246, 185, 139, 116, 185, 219, - 185, 138, 100, 100, 134, 100, 102, 34, - 68, 68, 100, 68, 168, 203, 221, 218, - 168, 167, 154, 136, 104, 70, 164, 246, - 171, 137, 139, 137, 155, 218, 219, 139 -}; - -static const opus_uint8 silk_NLSF_CB2_iCDF_NB_MB[ 72 ] = { - 255, 254, 253, 238, 14, 3, 2, 1, - 0, 255, 254, 252, 218, 35, 3, 2, - 1, 0, 255, 254, 250, 208, 59, 4, - 2, 1, 0, 255, 254, 246, 194, 71, - 10, 2, 1, 0, 255, 252, 236, 183, - 82, 8, 2, 1, 0, 255, 252, 235, - 180, 90, 17, 2, 1, 0, 255, 248, - 224, 171, 97, 30, 4, 1, 0, 255, - 254, 236, 173, 95, 37, 7, 1, 0 -}; - -static const opus_uint8 silk_NLSF_CB2_BITS_NB_MB_Q5[ 72 ] = { - 255, 255, 255, 131, 6, 145, 255, 255, - 255, 255, 255, 236, 93, 15, 96, 255, - 255, 255, 255, 255, 194, 83, 25, 71, - 221, 255, 255, 255, 255, 162, 73, 34, - 66, 162, 255, 255, 255, 210, 126, 73, - 43, 57, 173, 255, 255, 255, 201, 125, - 71, 48, 58, 130, 255, 255, 255, 166, - 110, 73, 57, 62, 104, 210, 255, 255, - 251, 123, 65, 55, 68, 100, 171, 255 -}; - -static const opus_uint8 silk_NLSF_PRED_NB_MB_Q8[ 18 ] = { - 179, 138, 140, 148, 151, 149, 153, 151, - 163, 116, 67, 82, 59, 92, 72, 100, - 89, 92 -}; - -static const opus_int16 silk_NLSF_DELTA_MIN_NB_MB_Q15[ 11 ] = { - 250, 3, 6, 3, 3, 3, 4, 3, - 3, 3, 461 -}; - -const silk_NLSF_CB_struct silk_NLSF_CB_NB_MB = -{ - 32, - 10, - SILK_FIX_CONST( 0.18, 16 ), - SILK_FIX_CONST( 1.0 / 0.18, 6 ), - silk_NLSF_CB1_NB_MB_Q8, - silk_NLSF_CB1_iCDF_NB_MB, - silk_NLSF_PRED_NB_MB_Q8, - silk_NLSF_CB2_SELECT_NB_MB, - silk_NLSF_CB2_iCDF_NB_MB, - silk_NLSF_CB2_BITS_NB_MB_Q5, - silk_NLSF_DELTA_MIN_NB_MB_Q15, -}; diff --git a/src/opus-1.0.2/silk/tables_NLSF_CB_WB.c b/src/opus-1.0.2/silk/tables_NLSF_CB_WB.c deleted file mode 100644 index 3d6052e4..00000000 --- a/src/opus-1.0.2/silk/tables_NLSF_CB_WB.c +++ /dev/null @@ -1,198 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "tables.h" - -static const opus_uint8 silk_NLSF_CB1_WB_Q8[ 512 ] = { - 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 opus_uint8 silk_NLSF_CB1_iCDF_WB[ 64 ] = { - 225, 204, 201, 184, 183, 175, 158, 154, - 153, 135, 119, 115, 113, 110, 109, 99, - 98, 95, 79, 68, 52, 50, 48, 45, - 43, 32, 31, 27, 18, 10, 3, 0, - 255, 251, 235, 230, 212, 201, 196, 182, - 167, 166, 163, 151, 138, 124, 110, 104, - 90, 78, 76, 70, 69, 57, 45, 34, - 24, 21, 11, 6, 5, 4, 3, 0 -}; - -static const opus_uint8 silk_NLSF_CB2_SELECT_WB[ 256 ] = { - 0, 0, 0, 0, 0, 0, 0, 1, - 100, 102, 102, 68, 68, 36, 34, 96, - 164, 107, 158, 185, 180, 185, 139, 102, - 64, 66, 36, 34, 34, 0, 1, 32, - 208, 139, 141, 191, 152, 185, 155, 104, - 96, 171, 104, 166, 102, 102, 102, 132, - 1, 0, 0, 0, 0, 16, 16, 0, - 80, 109, 78, 107, 185, 139, 103, 101, - 208, 212, 141, 139, 173, 153, 123, 103, - 36, 0, 0, 0, 0, 0, 0, 1, - 48, 0, 0, 0, 0, 0, 0, 32, - 68, 135, 123, 119, 119, 103, 69, 98, - 68, 103, 120, 118, 118, 102, 71, 98, - 134, 136, 157, 184, 182, 153, 139, 134, - 208, 168, 248, 75, 189, 143, 121, 107, - 32, 49, 34, 34, 34, 0, 17, 2, - 210, 235, 139, 123, 185, 137, 105, 134, - 98, 135, 104, 182, 100, 183, 171, 134, - 100, 70, 68, 70, 66, 66, 34, 131, - 64, 166, 102, 68, 36, 2, 1, 0, - 134, 166, 102, 68, 34, 34, 66, 132, - 212, 246, 158, 139, 107, 107, 87, 102, - 100, 219, 125, 122, 137, 118, 103, 132, - 114, 135, 137, 105, 171, 106, 50, 34, - 164, 214, 141, 143, 185, 151, 121, 103, - 192, 34, 0, 0, 0, 0, 0, 1, - 208, 109, 74, 187, 134, 249, 159, 137, - 102, 110, 154, 118, 87, 101, 119, 101, - 0, 2, 0, 36, 36, 66, 68, 35, - 96, 164, 102, 100, 36, 0, 2, 33, - 167, 138, 174, 102, 100, 84, 2, 2, - 100, 107, 120, 119, 36, 197, 24, 0 -}; - -static const opus_uint8 silk_NLSF_CB2_iCDF_WB[ 72 ] = { - 255, 254, 253, 244, 12, 3, 2, 1, - 0, 255, 254, 252, 224, 38, 3, 2, - 1, 0, 255, 254, 251, 209, 57, 4, - 2, 1, 0, 255, 254, 244, 195, 69, - 4, 2, 1, 0, 255, 251, 232, 184, - 84, 7, 2, 1, 0, 255, 254, 240, - 186, 86, 14, 2, 1, 0, 255, 254, - 239, 178, 91, 30, 5, 1, 0, 255, - 248, 227, 177, 100, 19, 2, 1, 0 -}; - -static const opus_uint8 silk_NLSF_CB2_BITS_WB_Q5[ 72 ] = { - 255, 255, 255, 156, 4, 154, 255, 255, - 255, 255, 255, 227, 102, 15, 92, 255, - 255, 255, 255, 255, 213, 83, 24, 72, - 236, 255, 255, 255, 255, 150, 76, 33, - 63, 214, 255, 255, 255, 190, 121, 77, - 43, 55, 185, 255, 255, 255, 245, 137, - 71, 43, 59, 139, 255, 255, 255, 255, - 131, 66, 50, 66, 107, 194, 255, 255, - 166, 116, 76, 55, 53, 125, 255, 255 -}; - -static const opus_uint8 silk_NLSF_PRED_WB_Q8[ 30 ] = { - 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 opus_int16 silk_NLSF_DELTA_MIN_WB_Q15[ 17 ] = { - 100, 3, 40, 3, 3, 3, 5, 14, - 14, 10, 11, 3, 8, 9, 7, 3, - 347 -}; - -const silk_NLSF_CB_struct silk_NLSF_CB_WB = -{ - 32, - 16, - SILK_FIX_CONST( 0.15, 16 ), - SILK_FIX_CONST( 1.0 / 0.15, 6 ), - silk_NLSF_CB1_WB_Q8, - silk_NLSF_CB1_iCDF_WB, - silk_NLSF_PRED_WB_Q8, - silk_NLSF_CB2_SELECT_WB, - silk_NLSF_CB2_iCDF_WB, - silk_NLSF_CB2_BITS_WB_Q5, - silk_NLSF_DELTA_MIN_WB_Q15, -}; - diff --git a/src/opus-1.0.2/silk/tables_gain.c b/src/opus-1.0.2/silk/tables_gain.c deleted file mode 100644 index fccef821..00000000 --- a/src/opus-1.0.2/silk/tables_gain.c +++ /dev/null @@ -1,63 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "tables.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -const opus_uint8 silk_gain_iCDF[ 3 ][ N_LEVELS_QGAIN / 8 ] = -{ -{ - 224, 112, 44, 15, 3, 2, 1, 0 -}, -{ - 254, 237, 192, 132, 70, 23, 4, 0 -}, -{ - 255, 252, 226, 155, 61, 11, 2, 0 -} -}; - -const opus_uint8 silk_delta_gain_iCDF[ MAX_DELTA_GAIN_QUANT - MIN_DELTA_GAIN_QUANT + 1 ] = { - 250, 245, 234, 203, 71, 50, 42, 38, - 35, 33, 31, 29, 28, 27, 26, 25, - 24, 23, 22, 21, 20, 19, 18, 17, - 16, 15, 14, 13, 12, 11, 10, 9, - 8, 7, 6, 5, 4, 3, 2, 1, - 0 -}; - -#ifdef __cplusplus -} -#endif diff --git a/src/opus-1.0.2/silk/tables_other.c b/src/opus-1.0.2/silk/tables_other.c deleted file mode 100644 index 3dc68d47..00000000 --- a/src/opus-1.0.2/silk/tables_other.c +++ /dev/null @@ -1,138 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "structs.h" -#include "define.h" -#include "tables.h" - -#ifdef __cplusplus -extern "C" -{ -#endif - -/* Piece-wise linear mapping from bitrate in kbps to coding quality in dB SNR */ -const opus_int32 silk_TargetRate_table_NB[ TARGET_RATE_TAB_SZ ] = { - 0, 8000, 9400, 11500, 13500, 17500, 25000, MAX_TARGET_RATE_BPS -}; -const opus_int32 silk_TargetRate_table_MB[ TARGET_RATE_TAB_SZ ] = { - 0, 9000, 12000, 14500, 18500, 24500, 35500, MAX_TARGET_RATE_BPS -}; -const opus_int32 silk_TargetRate_table_WB[ TARGET_RATE_TAB_SZ ] = { - 0, 10500, 14000, 17000, 21500, 28500, 42000, MAX_TARGET_RATE_BPS -}; -const opus_int16 silk_SNR_table_Q1[ TARGET_RATE_TAB_SZ ] = { - 18, 29, 38, 40, 46, 52, 62, 84 -}; - -/* Tables for stereo predictor coding */ -const opus_int16 silk_stereo_pred_quant_Q13[ STEREO_QUANT_TAB_SIZE ] = { - -13732, -10050, -8266, -7526, -6500, -5000, -2950, -820, - 820, 2950, 5000, 6500, 7526, 8266, 10050, 13732 -}; -const opus_uint8 silk_stereo_pred_joint_iCDF[ 25 ] = { - 249, 247, 246, 245, 244, - 234, 210, 202, 201, 200, - 197, 174, 82, 59, 56, - 55, 54, 46, 22, 12, - 11, 10, 9, 7, 0 -}; -const opus_uint8 silk_stereo_only_code_mid_iCDF[ 2 ] = { 64, 0 }; - -/* Tables for LBRR flags */ -static const opus_uint8 silk_LBRR_flags_2_iCDF[ 3 ] = { 203, 150, 0 }; -static const opus_uint8 silk_LBRR_flags_3_iCDF[ 7 ] = { 215, 195, 166, 125, 110, 82, 0 }; -const opus_uint8 * const silk_LBRR_flags_iCDF_ptr[ 2 ] = { - silk_LBRR_flags_2_iCDF, - silk_LBRR_flags_3_iCDF -}; - -/* Table for LSB coding */ -const opus_uint8 silk_lsb_iCDF[ 2 ] = { 120, 0 }; - -/* Tables for LTPScale */ -const opus_uint8 silk_LTPscale_iCDF[ 3 ] = { 128, 64, 0 }; - -/* Tables for signal type and offset coding */ -const opus_uint8 silk_type_offset_VAD_iCDF[ 4 ] = { - 232, 158, 10, 0 -}; -const opus_uint8 silk_type_offset_no_VAD_iCDF[ 2 ] = { - 230, 0 -}; - -/* Tables for NLSF interpolation factor */ -const opus_uint8 silk_NLSF_interpolation_factor_iCDF[ 5 ] = { 243, 221, 192, 181, 0 }; - -/* Quantization offsets */ -const opus_int16 silk_Quantization_Offsets_Q10[ 2 ][ 2 ] = { - { OFFSET_UVL_Q10, OFFSET_UVH_Q10 }, { OFFSET_VL_Q10, OFFSET_VH_Q10 } -}; - -/* Table for LTPScale */ -const opus_int16 silk_LTPScales_table_Q14[ 3 ] = { 15565, 12288, 8192 }; - -/* Uniform entropy tables */ -const opus_uint8 silk_uniform3_iCDF[ 3 ] = { 171, 85, 0 }; -const opus_uint8 silk_uniform4_iCDF[ 4 ] = { 192, 128, 64, 0 }; -const opus_uint8 silk_uniform5_iCDF[ 5 ] = { 205, 154, 102, 51, 0 }; -const opus_uint8 silk_uniform6_iCDF[ 6 ] = { 213, 171, 128, 85, 43, 0 }; -const opus_uint8 silk_uniform8_iCDF[ 8 ] = { 224, 192, 160, 128, 96, 64, 32, 0 }; - -const opus_uint8 silk_NLSF_EXT_iCDF[ 7 ] = { 100, 40, 16, 7, 3, 1, 0 }; - -/* Elliptic/Cauer filters designed with 0.1 dB passband ripple, - 80 dB minimum stopband attenuation, and - [0.95 : 0.15 : 0.35] normalized cut off frequencies. */ - -/* Interpolation points for filter coefficients used in the bandwidth transition smoother */ -const opus_int32 silk_Transition_LP_B_Q28[ TRANSITION_INT_NUM ][ TRANSITION_NB ] = -{ -{ 250767114, 501534038, 250767114 }, -{ 209867381, 419732057, 209867381 }, -{ 170987846, 341967853, 170987846 }, -{ 131531482, 263046905, 131531482 }, -{ 89306658, 178584282, 89306658 } -}; - -/* Interpolation points for filter coefficients used in the bandwidth transition smoother */ -const opus_int32 silk_Transition_LP_A_Q28[ TRANSITION_INT_NUM ][ TRANSITION_NA ] = -{ -{ 506393414, 239854379 }, -{ 411067935, 169683996 }, -{ 306733530, 116694253 }, -{ 185807084, 77959395 }, -{ 35497197, 57401098 } -}; - -#ifdef __cplusplus -} -#endif - diff --git a/src/opus-1.0.2/silk/tables_pitch_lag.c b/src/opus-1.0.2/silk/tables_pitch_lag.c deleted file mode 100644 index 819b0ab3..00000000 --- a/src/opus-1.0.2/silk/tables_pitch_lag.c +++ /dev/null @@ -1,69 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "tables.h" - -const opus_uint8 silk_pitch_lag_iCDF[ 2 * ( PITCH_EST_MAX_LAG_MS - PITCH_EST_MIN_LAG_MS ) ] = { - 253, 250, 244, 233, 212, 182, 150, 131, - 120, 110, 98, 85, 72, 60, 49, 40, - 32, 25, 19, 15, 13, 11, 9, 8, - 7, 6, 5, 4, 3, 2, 1, 0 -}; - -const opus_uint8 silk_pitch_delta_iCDF[21] = { - 210, 208, 206, 203, 199, 193, 183, 168, - 142, 104, 74, 52, 37, 27, 20, 14, - 10, 6, 4, 2, 0 -}; - -const opus_uint8 silk_pitch_contour_iCDF[34] = { - 223, 201, 183, 167, 152, 138, 124, 111, - 98, 88, 79, 70, 62, 56, 50, 44, - 39, 35, 31, 27, 24, 21, 18, 16, - 14, 12, 10, 8, 6, 4, 3, 2, - 1, 0 -}; - -const opus_uint8 silk_pitch_contour_NB_iCDF[11] = { - 188, 176, 155, 138, 119, 97, 67, 43, - 26, 10, 0 -}; - -const opus_uint8 silk_pitch_contour_10_ms_iCDF[12] = { - 165, 119, 80, 61, 47, 35, 27, 20, - 14, 9, 4, 0 -}; - -const opus_uint8 silk_pitch_contour_10_ms_NB_iCDF[3] = { - 113, 63, 0 -}; - - diff --git a/src/opus-1.0.2/silk/tables_pulses_per_block.c b/src/opus-1.0.2/silk/tables_pulses_per_block.c deleted file mode 100644 index 521e6ff6..00000000 --- a/src/opus-1.0.2/silk/tables_pulses_per_block.c +++ /dev/null @@ -1,264 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "tables.h" - -const opus_uint8 silk_max_pulses_table[ 4 ] = { - 8, 10, 12, 16 -}; - -const opus_uint8 silk_pulses_per_block_iCDF[ 10 ][ 18 ] = { -{ - 125, 51, 26, 18, 15, 12, 11, 10, - 9, 8, 7, 6, 5, 4, 3, 2, - 1, 0 -}, -{ - 198, 105, 45, 22, 15, 12, 11, 10, - 9, 8, 7, 6, 5, 4, 3, 2, - 1, 0 -}, -{ - 213, 162, 116, 83, 59, 43, 32, 24, - 18, 15, 12, 9, 7, 6, 5, 3, - 2, 0 -}, -{ - 239, 187, 116, 59, 28, 16, 11, 10, - 9, 8, 7, 6, 5, 4, 3, 2, - 1, 0 -}, -{ - 250, 229, 188, 135, 86, 51, 30, 19, - 13, 10, 8, 6, 5, 4, 3, 2, - 1, 0 -}, -{ - 249, 235, 213, 185, 156, 128, 103, 83, - 66, 53, 42, 33, 26, 21, 17, 13, - 10, 0 -}, -{ - 254, 249, 235, 206, 164, 118, 77, 46, - 27, 16, 10, 7, 5, 4, 3, 2, - 1, 0 -}, -{ - 255, 253, 249, 239, 220, 191, 156, 119, - 85, 57, 37, 23, 15, 10, 6, 4, - 2, 0 -}, -{ - 255, 253, 251, 246, 237, 223, 203, 179, - 152, 124, 98, 75, 55, 40, 29, 21, - 15, 0 -}, -{ - 255, 254, 253, 247, 220, 162, 106, 67, - 42, 28, 18, 12, 9, 6, 4, 3, - 2, 0 -} -}; - -const opus_uint8 silk_pulses_per_block_BITS_Q5[ 9 ][ 18 ] = { -{ - 31, 57, 107, 160, 205, 205, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255 -}, -{ - 69, 47, 67, 111, 166, 205, 255, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255 -}, -{ - 82, 74, 79, 95, 109, 128, 145, 160, - 173, 205, 205, 205, 224, 255, 255, 224, - 255, 224 -}, -{ - 125, 74, 59, 69, 97, 141, 182, 255, - 255, 255, 255, 255, 255, 255, 255, 255, - 255, 255 -}, -{ - 173, 115, 85, 73, 76, 92, 115, 145, - 173, 205, 224, 224, 255, 255, 255, 255, - 255, 255 -}, -{ - 166, 134, 113, 102, 101, 102, 107, 118, - 125, 138, 145, 155, 166, 182, 192, 192, - 205, 150 -}, -{ - 224, 182, 134, 101, 83, 79, 85, 97, - 120, 145, 173, 205, 224, 255, 255, 255, - 255, 255 -}, -{ - 255, 224, 192, 150, 120, 101, 92, 89, - 93, 102, 118, 134, 160, 182, 192, 224, - 224, 224 -}, -{ - 255, 224, 224, 182, 155, 134, 118, 109, - 104, 102, 106, 111, 118, 131, 145, 160, - 173, 131 -} -}; - -const opus_uint8 silk_rate_levels_iCDF[ 2 ][ 9 ] = -{ -{ - 241, 190, 178, 132, 87, 74, 41, 14, - 0 -}, -{ - 223, 193, 157, 140, 106, 57, 39, 18, - 0 -} -}; - -const opus_uint8 silk_rate_levels_BITS_Q5[ 2 ][ 9 ] = -{ -{ - 131, 74, 141, 79, 80, 138, 95, 104, - 134 -}, -{ - 95, 99, 91, 125, 93, 76, 123, 115, - 123 -} -}; - -const opus_uint8 silk_shell_code_table0[ 152 ] = { - 128, 0, 214, 42, 0, 235, 128, 21, - 0, 244, 184, 72, 11, 0, 248, 214, - 128, 42, 7, 0, 248, 225, 170, 80, - 25, 5, 0, 251, 236, 198, 126, 54, - 18, 3, 0, 250, 238, 211, 159, 82, - 35, 15, 5, 0, 250, 231, 203, 168, - 128, 88, 53, 25, 6, 0, 252, 238, - 216, 185, 148, 108, 71, 40, 18, 4, - 0, 253, 243, 225, 199, 166, 128, 90, - 57, 31, 13, 3, 0, 254, 246, 233, - 212, 183, 147, 109, 73, 44, 23, 10, - 2, 0, 255, 250, 240, 223, 198, 166, - 128, 90, 58, 33, 16, 6, 1, 0, - 255, 251, 244, 231, 210, 181, 146, 110, - 75, 46, 25, 12, 5, 1, 0, 255, - 253, 248, 238, 221, 196, 164, 128, 92, - 60, 35, 18, 8, 3, 1, 0, 255, - 253, 249, 242, 229, 208, 180, 146, 110, - 76, 48, 27, 14, 7, 3, 1, 0 -}; - -const opus_uint8 silk_shell_code_table1[ 152 ] = { - 129, 0, 207, 50, 0, 236, 129, 20, - 0, 245, 185, 72, 10, 0, 249, 213, - 129, 42, 6, 0, 250, 226, 169, 87, - 27, 4, 0, 251, 233, 194, 130, 62, - 20, 4, 0, 250, 236, 207, 160, 99, - 47, 17, 3, 0, 255, 240, 217, 182, - 131, 81, 41, 11, 1, 0, 255, 254, - 233, 201, 159, 107, 61, 20, 2, 1, - 0, 255, 249, 233, 206, 170, 128, 86, - 50, 23, 7, 1, 0, 255, 250, 238, - 217, 186, 148, 108, 70, 39, 18, 6, - 1, 0, 255, 252, 243, 226, 200, 166, - 128, 90, 56, 30, 13, 4, 1, 0, - 255, 252, 245, 231, 209, 180, 146, 110, - 76, 47, 25, 11, 4, 1, 0, 255, - 253, 248, 237, 219, 194, 163, 128, 93, - 62, 37, 19, 8, 3, 1, 0, 255, - 254, 250, 241, 226, 205, 177, 145, 111, - 79, 51, 30, 15, 6, 2, 1, 0 -}; - -const opus_uint8 silk_shell_code_table2[ 152 ] = { - 129, 0, 203, 54, 0, 234, 129, 23, - 0, 245, 184, 73, 10, 0, 250, 215, - 129, 41, 5, 0, 252, 232, 173, 86, - 24, 3, 0, 253, 240, 200, 129, 56, - 15, 2, 0, 253, 244, 217, 164, 94, - 38, 10, 1, 0, 253, 245, 226, 189, - 132, 71, 27, 7, 1, 0, 253, 246, - 231, 203, 159, 105, 56, 23, 6, 1, - 0, 255, 248, 235, 213, 179, 133, 85, - 47, 19, 5, 1, 0, 255, 254, 243, - 221, 194, 159, 117, 70, 37, 12, 2, - 1, 0, 255, 254, 248, 234, 208, 171, - 128, 85, 48, 22, 8, 2, 1, 0, - 255, 254, 250, 240, 220, 189, 149, 107, - 67, 36, 16, 6, 2, 1, 0, 255, - 254, 251, 243, 227, 201, 166, 128, 90, - 55, 29, 13, 5, 2, 1, 0, 255, - 254, 252, 246, 234, 213, 183, 147, 109, - 73, 43, 22, 10, 4, 2, 1, 0 -}; - -const opus_uint8 silk_shell_code_table3[ 152 ] = { - 130, 0, 200, 58, 0, 231, 130, 26, - 0, 244, 184, 76, 12, 0, 249, 214, - 130, 43, 6, 0, 252, 232, 173, 87, - 24, 3, 0, 253, 241, 203, 131, 56, - 14, 2, 0, 254, 246, 221, 167, 94, - 35, 8, 1, 0, 254, 249, 232, 193, - 130, 65, 23, 5, 1, 0, 255, 251, - 239, 211, 162, 99, 45, 15, 4, 1, - 0, 255, 251, 243, 223, 186, 131, 74, - 33, 11, 3, 1, 0, 255, 252, 245, - 230, 202, 158, 105, 57, 24, 8, 2, - 1, 0, 255, 253, 247, 235, 214, 179, - 132, 84, 44, 19, 7, 2, 1, 0, - 255, 254, 250, 240, 223, 196, 159, 112, - 69, 36, 15, 6, 2, 1, 0, 255, - 254, 253, 245, 231, 209, 176, 136, 93, - 55, 27, 11, 3, 2, 1, 0, 255, - 254, 253, 252, 239, 221, 194, 158, 117, - 76, 42, 18, 4, 3, 2, 1, 0 -}; - -const opus_uint8 silk_shell_code_table_offsets[ 17 ] = { - 0, 0, 2, 5, 9, 14, 20, 27, - 35, 44, 54, 65, 77, 90, 104, 119, - 135 -}; - -const opus_uint8 silk_sign_iCDF[ 42 ] = { - 254, 49, 67, 77, 82, 93, 99, - 198, 11, 18, 24, 31, 36, 45, - 255, 46, 66, 78, 87, 94, 104, - 208, 14, 21, 32, 42, 51, 66, - 255, 94, 104, 109, 112, 115, 118, - 248, 53, 69, 80, 88, 95, 102 -}; diff --git a/src/opus-1.0.2/silk/tuning_parameters.h b/src/opus-1.0.2/silk/tuning_parameters.h deleted file mode 100644 index a26de4d2..00000000 --- a/src/opus-1.0.2/silk/tuning_parameters.h +++ /dev/null @@ -1,168 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifndef SILK_TUNING_PARAMETERS_H -#define SILK_TUNING_PARAMETERS_H - -#ifdef __cplusplus -extern "C" -{ -#endif - -/* Decay time for bitreservoir */ -#define BITRESERVOIR_DECAY_TIME_MS 500 - -/*******************/ -/* Pitch estimator */ -/*******************/ - -/* Level of noise floor for whitening filter LPC analysis in pitch analysis */ -#define FIND_PITCH_WHITE_NOISE_FRACTION 1e-3f - -/* Bandwidth expansion for whitening filter in pitch analysis */ -#define FIND_PITCH_BANDWIDTH_EXPANSION 0.99f - -/*********************/ -/* Linear prediction */ -/*********************/ - -/* LPC analysis defines: regularization and bandwidth expansion */ -#define FIND_LPC_COND_FAC 1e-5f - -/* LTP analysis defines */ -#define FIND_LTP_COND_FAC 1e-5f -#define LTP_DAMPING 0.05f -#define LTP_SMOOTHING 0.1f - -/* LTP quantization settings */ -#define MU_LTP_QUANT_NB 0.03f -#define MU_LTP_QUANT_MB 0.025f -#define MU_LTP_QUANT_WB 0.02f - -/***********************/ -/* High pass filtering */ -/***********************/ - -/* Smoothing parameters for low end of pitch frequency range estimation */ -#define VARIABLE_HP_SMTH_COEF1 0.1f -#define VARIABLE_HP_SMTH_COEF2 0.015f -#define VARIABLE_HP_MAX_DELTA_FREQ 0.4f - -/* Min and max cut-off frequency values (-3 dB points) */ -#define VARIABLE_HP_MIN_CUTOFF_HZ 60 -#define VARIABLE_HP_MAX_CUTOFF_HZ 100 - -/***********/ -/* Various */ -/***********/ - -/* VAD threshold */ -#define SPEECH_ACTIVITY_DTX_THRES 0.05f - -/* Speech Activity LBRR enable threshold */ -#define LBRR_SPEECH_ACTIVITY_THRES 0.3f - -/*************************/ -/* Perceptual parameters */ -/*************************/ - -/* reduction in coding SNR during low speech activity */ -#define BG_SNR_DECR_dB 2.0f - -/* factor for reducing quantization noise during voiced speech */ -#define HARM_SNR_INCR_dB 2.0f - -/* factor for reducing quantization noise for unvoiced sparse signals */ -#define SPARSE_SNR_INCR_dB 2.0f - -/* threshold for sparseness measure above which to use lower quantization offset during unvoiced */ -#define SPARSENESS_THRESHOLD_QNT_OFFSET 0.75f - -/* warping control */ -#define WARPING_MULTIPLIER 0.015f - -/* fraction added to first autocorrelation value */ -#define SHAPE_WHITE_NOISE_FRACTION 5e-5f - -/* noise shaping filter chirp factor */ -#define BANDWIDTH_EXPANSION 0.95f - -/* difference between chirp factors for analysis and synthesis noise shaping filters at low bitrates */ -#define LOW_RATE_BANDWIDTH_EXPANSION_DELTA 0.01f - -/* extra harmonic boosting (signal shaping) at low bitrates */ -#define LOW_RATE_HARMONIC_BOOST 0.1f - -/* extra harmonic boosting (signal shaping) for noisy input signals */ -#define LOW_INPUT_QUALITY_HARMONIC_BOOST 0.1f - -/* harmonic noise shaping */ -#define HARMONIC_SHAPING 0.3f - -/* extra harmonic noise shaping for high bitrates or noisy input */ -#define HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING 0.2f - -/* parameter for shaping noise towards higher frequencies */ -#define HP_NOISE_COEF 0.25f - -/* parameter for shaping noise even more towards higher frequencies during voiced speech */ -#define HARM_HP_NOISE_COEF 0.35f - -/* parameter for applying a high-pass tilt to the input signal */ -#define INPUT_TILT 0.05f - -/* parameter for extra high-pass tilt to the input signal at high rates */ -#define HIGH_RATE_INPUT_TILT 0.1f - -/* parameter for reducing noise at the very low frequencies */ -#define LOW_FREQ_SHAPING 4.0f - -/* less reduction of noise at the very low frequencies for signals with low SNR at low frequencies */ -#define LOW_QUALITY_LOW_FREQ_SHAPING_DECR 0.5f - -/* subframe smoothing coefficient for HarmBoost, HarmShapeGain, Tilt (lower -> more smoothing) */ -#define SUBFR_SMTH_COEF 0.4f - -/* parameters defining the R/D tradeoff in the residual quantizer */ -#define LAMBDA_OFFSET 1.2f -#define LAMBDA_SPEECH_ACT -0.2f -#define LAMBDA_DELAYED_DECISIONS -0.05f -#define LAMBDA_INPUT_QUALITY -0.1f -#define LAMBDA_CODING_QUALITY -0.2f -#define LAMBDA_QUANT_OFFSET 0.8f - -/* Compensation in bitrate calculations for 10 ms modes */ -#define REDUCE_BITRATE_10_MS_BPS 2200 - -/* Maximum time before allowing a bandwidth transition */ -#define MAX_BANDWIDTH_SWITCH_DELAY_MS 5000 - -#ifdef __cplusplus -} -#endif - -#endif /* SILK_TUNING_PARAMETERS_H */ diff --git a/src/opus-1.0.2/silk/typedef.h b/src/opus-1.0.2/silk/typedef.h deleted file mode 100644 index da981237..00000000 --- a/src/opus-1.0.2/silk/typedef.h +++ /dev/null @@ -1,77 +0,0 @@ -/*********************************************************************** -Copyright (c) 2006-2011, Skype Limited. All rights reserved. -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -- Redistributions of source code must retain the above copyright notice, -this list of conditions and the following disclaimer. -- Redistributions in binary form must reproduce the above copyright -notice, this list of conditions and the following disclaimer in the -documentation and/or other materials provided with the distribution. -- Neither the name of Internet Society, IETF or IETF Trust, nor the -names of specific contributors, may be used to endorse or promote -products derived from this software without specific prior written -permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. -***********************************************************************/ - -#ifndef SILK_TYPEDEF_H -#define SILK_TYPEDEF_H - -#include "opus_types.h" - -#ifndef FIXED_POINT -# include -# define silk_float float -# define silk_float_MAX FLT_MAX -#endif - -#define silk_int64_MAX ((opus_int64)0x7FFFFFFFFFFFFFFFLL) /* 2^63 - 1 */ -#define silk_int64_MIN ((opus_int64)0x8000000000000000LL) /* -2^63 */ -#define silk_int32_MAX 0x7FFFFFFF /* 2^31 - 1 = 2147483647 */ -#define silk_int32_MIN ((opus_int32)0x80000000) /* -2^31 = -2147483648 */ -#define silk_int16_MAX 0x7FFF /* 2^15 - 1 = 32767 */ -#define silk_int16_MIN ((opus_int16)0x8000) /* -2^15 = -32768 */ -#define silk_int8_MAX 0x7F /* 2^7 - 1 = 127 */ -#define silk_int8_MIN ((opus_int8)0x80) /* -2^7 = -128 */ -#define silk_uint8_MAX 0xFF /* 2^8 - 1 = 255 */ - -#define silk_TRUE 1 -#define silk_FALSE 0 - -/* assertions */ -#if (defined _WIN32 && !defined _WINCE && !defined(__GNUC__) && !defined(NO_ASSERTS)) -# ifndef silk_assert -# include /* ASSERTE() */ -# define silk_assert(COND) _ASSERTE(COND) -# endif -#else -# ifdef ENABLE_ASSERTIONS -# include -# include -#define silk_fatal(str) _silk_fatal(str, __FILE__, __LINE__); -#ifdef __GNUC__ -__attribute__((noreturn)) -#endif -static inline void _silk_fatal(const char *str, const char *file, int line) -{ - fprintf (stderr, "Fatal (internal) error in %s, line %d: %s\n", file, line, str); - abort(); -} -# define silk_assert(COND) {if (!(COND)) {silk_fatal("assertion failed: " #COND);}} -# else -# define silk_assert(COND) -# endif -#endif - -#endif /* SILK_TYPEDEF_H */ diff --git a/src/opus-1.0.2/src/opus.c b/src/opus-1.0.2/src/opus.c deleted file mode 100644 index d6ae7bab..00000000 --- a/src/opus-1.0.2/src/opus.c +++ /dev/null @@ -1,47 +0,0 @@ -/* Copyright (c) 2011 Xiph.Org Foundation, Skype Limited - Written by Jean-Marc Valin and Koen Vos */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "opus.h" -#include "opus_private.h" - -int encode_size(int size, unsigned char *data) -{ - if (size < 252) - { - data[0] = size; - return 1; - } else { - data[0] = 252+(size&0x3); - data[1] = (size-(int)data[0])>>2; - return 2; - } -} - diff --git a/src/opus-1.0.2/src/opus_decoder.c b/src/opus-1.0.2/src/opus_decoder.c deleted file mode 100644 index ad5f7470..00000000 --- a/src/opus-1.0.2/src/opus_decoder.c +++ /dev/null @@ -1,1051 +0,0 @@ -/* Copyright (c) 2010 Xiph.Org Foundation, Skype Limited - Written by Jean-Marc Valin and Koen Vos */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifndef OPUS_BUILD -#error "OPUS_BUILD _MUST_ be defined to build Opus. This probably means you need other defines as well, as in a config.h. See the included build files for details." -#endif - -#include -#include "celt.h" -#include "opus.h" -#include "entdec.h" -#include "modes.h" -#include "API.h" -#include "stack_alloc.h" -#include "float_cast.h" -#include "opus_private.h" -#include "os_support.h" -#include "structs.h" -#include "define.h" -#include "mathops.h" - -struct OpusDecoder { - int celt_dec_offset; - int silk_dec_offset; - int channels; - opus_int32 Fs; /** Sampling rate (at the API level) */ - silk_DecControlStruct DecControl; - int decode_gain; - - /* Everything beyond this point gets cleared on a reset */ -#define OPUS_DECODER_RESET_START stream_channels - int stream_channels; - - int bandwidth; - int mode; - int prev_mode; - int frame_size; - int prev_redundancy; - int last_packet_duration; - - opus_uint32 rangeFinal; -}; - -#ifdef FIXED_POINT -static inline opus_int16 SAT16(opus_int32 x) { - return x > 32767 ? 32767 : x < -32768 ? -32768 : (opus_int16)x; -} -#endif - - -int opus_decoder_get_size(int channels) -{ - int silkDecSizeBytes, celtDecSizeBytes; - int ret; - if (channels<1 || channels > 2) - return 0; - ret = silk_Get_Decoder_Size( &silkDecSizeBytes ); - if(ret) - return 0; - silkDecSizeBytes = align(silkDecSizeBytes); - celtDecSizeBytes = celt_decoder_get_size(channels); - return align(sizeof(OpusDecoder))+silkDecSizeBytes+celtDecSizeBytes; -} - -int opus_decoder_init(OpusDecoder *st, opus_int32 Fs, int channels) -{ - void *silk_dec; - CELTDecoder *celt_dec; - int ret, silkDecSizeBytes; - - if ((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000) - || (channels!=1&&channels!=2)) - return OPUS_BAD_ARG; - - OPUS_CLEAR((char*)st, opus_decoder_get_size(channels)); - /* Initialize SILK encoder */ - ret = silk_Get_Decoder_Size(&silkDecSizeBytes); - if (ret) - return OPUS_INTERNAL_ERROR; - - silkDecSizeBytes = align(silkDecSizeBytes); - st->silk_dec_offset = align(sizeof(OpusDecoder)); - st->celt_dec_offset = st->silk_dec_offset+silkDecSizeBytes; - silk_dec = (char*)st+st->silk_dec_offset; - celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset); - st->stream_channels = st->channels = channels; - - st->Fs = Fs; - st->DecControl.API_sampleRate = st->Fs; - st->DecControl.nChannelsAPI = st->channels; - - /* Reset decoder */ - ret = silk_InitDecoder( silk_dec ); - if(ret)return OPUS_INTERNAL_ERROR; - - /* Initialize CELT decoder */ - ret = celt_decoder_init(celt_dec, Fs, channels); - if(ret!=OPUS_OK)return OPUS_INTERNAL_ERROR; - - celt_decoder_ctl(celt_dec, CELT_SET_SIGNALLING(0)); - - st->prev_mode = 0; - st->frame_size = Fs/400; - return OPUS_OK; -} - -OpusDecoder *opus_decoder_create(opus_int32 Fs, int channels, int *error) -{ - int ret; - OpusDecoder *st; - if ((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000) - || (channels!=1&&channels!=2)) - { - if (error) - *error = OPUS_BAD_ARG; - return NULL; - } - st = (OpusDecoder *)opus_alloc(opus_decoder_get_size(channels)); - if (st == NULL) - { - if (error) - *error = OPUS_ALLOC_FAIL; - return NULL; - } - ret = opus_decoder_init(st, Fs, channels); - if (error) - *error = ret; - if (ret != OPUS_OK) - { - opus_free(st); - st = NULL; - } - return st; -} - -static void smooth_fade(const opus_val16 *in1, const opus_val16 *in2, - opus_val16 *out, int overlap, int channels, - const opus_val16 *window, opus_int32 Fs) -{ - int i, c; - int inc = 48000/Fs; - for (c=0;csilk_dec_offset; - celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset); - F20 = st->Fs/50; - F10 = F20>>1; - F5 = F10>>1; - F2_5 = F5>>1; - if (frame_size < F2_5) - { - RESTORE_STACK; - return OPUS_BUFFER_TOO_SMALL; - } - /* Limit frame_size to avoid excessive stack allocations. */ - frame_size = IMIN(frame_size, st->Fs/25*3); - /* Payloads of 1 (2 including ToC) or 0 trigger the PLC/DTX */ - if (len<=1) - { - data = NULL; - /* In that case, don't conceal more than what the ToC says */ - frame_size = IMIN(frame_size, st->frame_size); - } - if (data != NULL) - { - audiosize = st->frame_size; - mode = st->mode; - ec_dec_init(&dec,(unsigned char*)data,len); - } else { - audiosize = frame_size; - - if (st->prev_mode == 0) - { - /* If we haven't got any packet yet, all we can do is return zeros */ - for (i=0;ichannels;i++) - pcm[i] = 0; - RESTORE_STACK; - return audiosize; - } else { - mode = st->prev_mode; - } - } - - /* For CELT/hybrid PLC of more than 20 ms, opus_decode_native() will do - multiple calls */ - if (data==NULL && mode != MODE_SILK_ONLY) - frame_size = IMIN(frame_size, F20); - ALLOC(pcm_transition, F5*st->channels, opus_val16); - - if (data!=NULL && st->prev_mode > 0 && ( - (mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY && !st->prev_redundancy) - || (mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) ) - ) - { - transition = 1; - if (mode == MODE_CELT_ONLY) - opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0); - } - if (audiosize > frame_size) - { - /*fprintf(stderr, "PCM buffer too small: %d vs %d (mode = %d)\n", audiosize, frame_size, mode);*/ - RESTORE_STACK; - return OPUS_BAD_ARG; - } else { - frame_size = audiosize; - } - - ALLOC(pcm_silk, IMAX(F10, frame_size)*st->channels, opus_int16); - ALLOC(redundant_audio, F5*st->channels, opus_val16); - - /* SILK processing */ - if (mode != MODE_CELT_ONLY) - { - int lost_flag, decoded_samples; - opus_int16 *pcm_ptr = pcm_silk; - - if (st->prev_mode==MODE_CELT_ONLY) - silk_InitDecoder( silk_dec ); - - /* The SILK PLC cannot produce frames of less than 10 ms */ - st->DecControl.payloadSize_ms = IMAX(10, 1000 * audiosize / st->Fs); - - if (data != NULL) - { - st->DecControl.nChannelsInternal = st->stream_channels; - if( mode == MODE_SILK_ONLY ) { - if( st->bandwidth == OPUS_BANDWIDTH_NARROWBAND ) { - st->DecControl.internalSampleRate = 8000; - } else if( st->bandwidth == OPUS_BANDWIDTH_MEDIUMBAND ) { - st->DecControl.internalSampleRate = 12000; - } else if( st->bandwidth == OPUS_BANDWIDTH_WIDEBAND ) { - st->DecControl.internalSampleRate = 16000; - } else { - st->DecControl.internalSampleRate = 16000; - silk_assert( 0 ); - } - } else { - /* Hybrid mode */ - st->DecControl.internalSampleRate = 16000; - } - } - - lost_flag = data == NULL ? 1 : 2 * decode_fec; - decoded_samples = 0; - do { - /* Call SILK decoder */ - int first_frame = decoded_samples == 0; - silk_ret = silk_Decode( silk_dec, &st->DecControl, - lost_flag, first_frame, &dec, pcm_ptr, &silk_frame_size ); - if( silk_ret ) { - if (lost_flag) { - /* PLC failure should not be fatal */ - silk_frame_size = frame_size; - for (i=0;ichannels;i++) - pcm_ptr[i] = 0; - } else { - RESTORE_STACK; - return OPUS_INVALID_PACKET; - } - } - pcm_ptr += silk_frame_size * st->channels; - decoded_samples += silk_frame_size; - } while( decoded_samples < frame_size ); - } - - start_band = 0; - if (!decode_fec && mode != MODE_CELT_ONLY && data != NULL - && ec_tell(&dec)+17+20*(st->mode == MODE_HYBRID) <= 8*len) - { - /* Check if we have a redundant 0-8 kHz band */ - if (mode == MODE_HYBRID) - redundancy = ec_dec_bit_logp(&dec, 12); - else - redundancy = 1; - if (redundancy) - { - celt_to_silk = ec_dec_bit_logp(&dec, 1); - /* redundancy_bytes will be at least two, in the non-hybrid - case due to the ec_tell() check above */ - redundancy_bytes = mode==MODE_HYBRID ? - (opus_int32)ec_dec_uint(&dec, 256)+2 : - len-((ec_tell(&dec)+7)>>3); - len -= redundancy_bytes; - /* This is a sanity check. It should never happen for a valid - packet, so the exact behaviour is not normative. */ - if (len*8 < ec_tell(&dec)) - { - len = 0; - redundancy_bytes = 0; - redundancy = 0; - } - /* Shrink decoder because of raw bits */ - dec.storage -= redundancy_bytes; - } - } - if (mode != MODE_CELT_ONLY) - start_band = 17; - - { - int endband=21; - - switch(st->bandwidth) - { - case OPUS_BANDWIDTH_NARROWBAND: - endband = 13; - break; - case OPUS_BANDWIDTH_MEDIUMBAND: - case OPUS_BANDWIDTH_WIDEBAND: - endband = 17; - break; - case OPUS_BANDWIDTH_SUPERWIDEBAND: - endband = 19; - break; - case OPUS_BANDWIDTH_FULLBAND: - endband = 21; - break; - } - celt_decoder_ctl(celt_dec, CELT_SET_END_BAND(endband)); - celt_decoder_ctl(celt_dec, CELT_SET_CHANNELS(st->stream_channels)); - } - - if (redundancy) - transition = 0; - - if (transition && mode != MODE_CELT_ONLY) - opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0); - - /* 5 ms redundant frame for CELT->SILK*/ - if (redundancy && celt_to_silk) - { - celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)); - celt_decode_with_ec(celt_dec, data+len, redundancy_bytes, - redundant_audio, F5, NULL); - celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng)); - } - - /* MUST be after PLC */ - celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(start_band)); - - if (mode != MODE_SILK_ONLY) - { - int celt_frame_size = IMIN(F20, frame_size); - /* Make sure to discard any previous CELT state */ - if (mode != st->prev_mode && st->prev_mode > 0 && !st->prev_redundancy) - celt_decoder_ctl(celt_dec, OPUS_RESET_STATE); - /* Decode CELT */ - celt_ret = celt_decode_with_ec(celt_dec, decode_fec ? NULL : data, - len, pcm, celt_frame_size, &dec); - } else { - unsigned char silence[2] = {0xFF, 0xFF}; - for (i=0;ichannels;i++) - pcm[i] = 0; - /* For hybrid -> SILK transitions, we let the CELT MDCT - do a fade-out by decoding a silence frame */ - if (st->prev_mode == MODE_HYBRID && !(redundancy && celt_to_silk && st->prev_redundancy) ) - { - celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)); - celt_decode_with_ec(celt_dec, silence, 2, pcm, F2_5, NULL); - } - } - - if (mode != MODE_CELT_ONLY) - { -#ifdef FIXED_POINT - for (i=0;ichannels;i++) - pcm[i] = SAT16(pcm[i] + pcm_silk[i]); -#else - for (i=0;ichannels;i++) - pcm[i] = pcm[i] + (opus_val16)((1.f/32768.f)*pcm_silk[i]); -#endif - } - - { - const CELTMode *celt_mode; - celt_decoder_ctl(celt_dec, CELT_GET_MODE(&celt_mode)); - window = celt_mode->window; - } - - /* 5 ms redundant frame for SILK->CELT */ - if (redundancy && !celt_to_silk) - { - celt_decoder_ctl(celt_dec, OPUS_RESET_STATE); - celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)); - - celt_decode_with_ec(celt_dec, data+len, redundancy_bytes, redundant_audio, F5, NULL); - celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng)); - smooth_fade(pcm+st->channels*(frame_size-F2_5), redundant_audio+st->channels*F2_5, - pcm+st->channels*(frame_size-F2_5), F2_5, st->channels, window, st->Fs); - } - if (redundancy && celt_to_silk) - { - for (c=0;cchannels;c++) - { - for (i=0;ichannels*i+c] = redundant_audio[st->channels*i+c]; - } - smooth_fade(redundant_audio+st->channels*F2_5, pcm+st->channels*F2_5, - pcm+st->channels*F2_5, F2_5, st->channels, window, st->Fs); - } - if (transition) - { - if (audiosize >= F5) - { - for (i=0;ichannels*F2_5;i++) - pcm[i] = pcm_transition[i]; - smooth_fade(pcm_transition+st->channels*F2_5, pcm+st->channels*F2_5, - pcm+st->channels*F2_5, F2_5, - st->channels, window, st->Fs); - } else { - /* Not enough time to do a clean transition, but we do it anyway - This will not preserve amplitude perfectly and may introduce - a bit of temporal aliasing, but it shouldn't be too bad and - that's pretty much the best we can do. In any case, generating this - transition it pretty silly in the first place */ - smooth_fade(pcm_transition, pcm, - pcm, F2_5, - st->channels, window, st->Fs); - } - } - - if(st->decode_gain) - { - opus_val32 gain; - gain = celt_exp2(MULT16_16_P15(QCONST16(6.48814081e-4f, 25), st->decode_gain)); - for (i=0;ichannels;i++) - { - opus_val32 x; - x = MULT16_32_P16(pcm[i],gain); - pcm[i] = SATURATE(x, 32767); - } - } - - if (len <= 1) - st->rangeFinal = 0; - else - st->rangeFinal = dec.rng ^ redundant_rng; - - st->prev_mode = mode; - st->prev_redundancy = redundancy && !celt_to_silk; - RESTORE_STACK; - return celt_ret < 0 ? celt_ret : audiosize; - -} - -static int parse_size(const unsigned char *data, opus_int32 len, short *size) -{ - if (len<1) - { - *size = -1; - return -1; - } else if (data[0]<252) - { - *size = data[0]; - return 1; - } else if (len<2) - { - *size = -1; - return -1; - } else { - *size = 4*data[1] + data[0]; - return 2; - } -} - -static int opus_packet_parse_impl(const unsigned char *data, opus_int32 len, - int self_delimited, unsigned char *out_toc, - const unsigned char *frames[48], short size[48], int *payload_offset) -{ - int i, bytes; - int count; - int cbr; - unsigned char ch, toc; - int framesize; - opus_int32 last_size; - const unsigned char *data0 = data; - - if (size==NULL) - return OPUS_BAD_ARG; - - framesize = opus_packet_get_samples_per_frame(data, 48000); - - cbr = 0; - toc = *data++; - len--; - last_size = len; - switch (toc&0x3) - { - /* One frame */ - case 0: - count=1; - break; - /* Two CBR frames */ - case 1: - count=2; - cbr = 1; - if (!self_delimited) - { - if (len&0x1) - return OPUS_INVALID_PACKET; - last_size = len/2; - /* If last_size doesn't fit in size[0], we'll catch it later */ - size[0] = (short)last_size; - } - break; - /* Two VBR frames */ - case 2: - count = 2; - bytes = parse_size(data, len, size); - len -= bytes; - if (size[0]<0 || size[0] > len) - return OPUS_INVALID_PACKET; - data += bytes; - last_size = len-size[0]; - break; - /* Multiple CBR/VBR frames (from 0 to 120 ms) */ - default: /*case 3:*/ - if (len<1) - return OPUS_INVALID_PACKET; - /* Number of frames encoded in bits 0 to 5 */ - ch = *data++; - count = ch&0x3F; - if (count <= 0 || framesize*count > 5760) - return OPUS_INVALID_PACKET; - len--; - /* Padding flag is bit 6 */ - if (ch&0x40) - { - int p; - do { - if (len<=0) - return OPUS_INVALID_PACKET; - p = *data++; - len--; - len -= p==255 ? 254: p; - } while (p==255); - } - if (len<0) - return OPUS_INVALID_PACKET; - /* VBR flag is bit 7 */ - cbr = !(ch&0x80); - if (!cbr) - { - /* VBR case */ - last_size = len; - for (i=0;i len) - return OPUS_INVALID_PACKET; - data += bytes; - last_size -= bytes+size[i]; - } - if (last_size<0) - return OPUS_INVALID_PACKET; - } else if (!self_delimited) - { - /* CBR case */ - last_size = len/count; - if (last_size*count!=len) - return OPUS_INVALID_PACKET; - for (i=0;i len) - return OPUS_INVALID_PACKET; - data += bytes; - /* For CBR packets, apply the size to all the frames. */ - if (cbr) - { - if (size[count-1]*count > len) - return OPUS_INVALID_PACKET; - for (i=0;i last_size) - return OPUS_INVALID_PACKET; - } else - { - /* Because it's not encoded explicitly, it's possible the size of the - last packet (or all the packets, for the CBR case) is larger than - 1275. Reject them here.*/ - if (last_size > 1275) - return OPUS_INVALID_PACKET; - size[count-1] = (short)last_size; - } - - if (frames) - { - for (i=0;i1) - return OPUS_BAD_ARG; - /* For FEC/PLC, frame_size has to be to have a multiple of 2.5 ms */ - if ((decode_fec || len==0 || data==NULL) && frame_size%(st->Fs/400)!=0) - return OPUS_BAD_ARG; - if (len==0 || data==NULL) - { - int pcm_count=0; - do { - int ret; - ret = opus_decode_frame(st, NULL, 0, pcm, frame_size-pcm_count, 0); - if (ret<0) - return ret; - pcm += st->channels*ret; - pcm_count += ret; - } while (pcm_count < frame_size); - st->last_packet_duration = pcm_count; - return pcm_count; - } else if (len<0) - return OPUS_BAD_ARG; - - packet_mode = opus_packet_get_mode(data); - packet_bandwidth = opus_packet_get_bandwidth(data); - packet_frame_size = opus_packet_get_samples_per_frame(data, st->Fs); - packet_stream_channels = opus_packet_get_nb_channels(data); - - count = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL, size, &offset); - - data += offset; - - if (decode_fec) - { - int duration_copy; - int ret; - /* If no FEC can be present, run the PLC (recursive call) */ - if (frame_size <= packet_frame_size || packet_mode == MODE_CELT_ONLY || st->mode == MODE_CELT_ONLY) - return opus_decode_native(st, NULL, 0, pcm, frame_size, 0, 0, NULL); - /* Otherwise, run the PLC on everything except the size for which we might have FEC */ - duration_copy = st->last_packet_duration; - ret = opus_decode_native(st, NULL, 0, pcm, frame_size-packet_frame_size, 0, 0, NULL); - if (ret<0) - { - st->last_packet_duration = duration_copy; - return ret; - } - /* Complete with FEC */ - st->mode = packet_mode; - st->bandwidth = packet_bandwidth; - st->frame_size = packet_frame_size; - st->stream_channels = packet_stream_channels; - ret = opus_decode_frame(st, data, size[0], pcm+st->channels*(frame_size-packet_frame_size), - packet_frame_size, 1); - if (ret<0) - return ret; - st->last_packet_duration = frame_size; - return frame_size; - } - tot_offset = 0; - if (count < 0) - return count; - - tot_offset += offset; - - if (count*packet_frame_size > frame_size) - return OPUS_BUFFER_TOO_SMALL; - - /* Update the state as the last step to avoid updating it on an invalid packet */ - st->mode = packet_mode; - st->bandwidth = packet_bandwidth; - st->frame_size = packet_frame_size; - st->stream_channels = packet_stream_channels; - - nb_samples=0; - for (i=0;ichannels; - nb_samples += ret; - } - if (packet_offset != NULL) - *packet_offset = tot_offset; - st->last_packet_duration = nb_samples; - return nb_samples; -} - -#ifdef FIXED_POINT - -int opus_decode(OpusDecoder *st, const unsigned char *data, - opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec) -{ - return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL); -} - -#ifndef DISABLE_FLOAT_API -int opus_decode_float(OpusDecoder *st, const unsigned char *data, - opus_int32 len, float *pcm, int frame_size, int decode_fec) -{ - VARDECL(opus_int16, out); - int ret, i; - ALLOC_STACK; - - ALLOC(out, frame_size*st->channels, opus_int16); - - ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL); - if (ret > 0) - { - for (i=0;ichannels;i++) - pcm[i] = (1.f/32768.f)*(out[i]); - } - RESTORE_STACK; - return ret; -} -#endif - - -#else -int opus_decode(OpusDecoder *st, const unsigned char *data, - opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec) -{ - VARDECL(float, out); - int ret, i; - ALLOC_STACK; - - if(frame_size<0) - { - RESTORE_STACK; - return OPUS_BAD_ARG; - } - - ALLOC(out, frame_size*st->channels, float); - - ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL); - if (ret > 0) - { - for (i=0;ichannels;i++) - pcm[i] = FLOAT2INT16(out[i]); - } - RESTORE_STACK; - return ret; -} - -int opus_decode_float(OpusDecoder *st, const unsigned char *data, - opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec) -{ - return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL); -} - -#endif - -int opus_decoder_ctl(OpusDecoder *st, int request, ...) -{ - int ret = OPUS_OK; - va_list ap; - void *silk_dec; - CELTDecoder *celt_dec; - - silk_dec = (char*)st+st->silk_dec_offset; - celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset); - - - va_start(ap, request); - - switch (request) - { - case OPUS_GET_BANDWIDTH_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - *value = st->bandwidth; - } - break; - case OPUS_GET_FINAL_RANGE_REQUEST: - { - opus_uint32 *value = va_arg(ap, opus_uint32*); - *value = st->rangeFinal; - } - break; - case OPUS_RESET_STATE: - { - OPUS_CLEAR((char*)&st->OPUS_DECODER_RESET_START, - sizeof(OpusDecoder)- - ((char*)&st->OPUS_DECODER_RESET_START - (char*)st)); - - celt_decoder_ctl(celt_dec, OPUS_RESET_STATE); - silk_InitDecoder( silk_dec ); - st->stream_channels = st->channels; - st->frame_size = st->Fs/400; - } - break; - case OPUS_GET_SAMPLE_RATE_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - if (value==NULL) - { - ret = OPUS_BAD_ARG; - break; - } - *value = st->Fs; - } - break; - case OPUS_GET_PITCH_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - if (value==NULL) - { - ret = OPUS_BAD_ARG; - break; - } - if (st->prev_mode == MODE_CELT_ONLY) - celt_decoder_ctl(celt_dec, OPUS_GET_PITCH(value)); - else - *value = st->DecControl.prevPitchLag; - } - break; - case OPUS_GET_GAIN_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - if (value==NULL) - { - ret = OPUS_BAD_ARG; - break; - } - *value = st->decode_gain; - } - break; - case OPUS_SET_GAIN_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if (value<-32768 || value>32767) - { - ret = OPUS_BAD_ARG; - break; - } - st->decode_gain = value; - } - break; - case OPUS_GET_LAST_PACKET_DURATION_REQUEST: - { - opus_uint32 *value = va_arg(ap, opus_uint32*); - *value = st->last_packet_duration; - } - break; - default: - /*fprintf(stderr, "unknown opus_decoder_ctl() request: %d", request);*/ - ret = OPUS_UNIMPLEMENTED; - break; - } - - va_end(ap); - return ret; -} - -void opus_decoder_destroy(OpusDecoder *st) -{ - opus_free(st); -} - - -int opus_packet_get_bandwidth(const unsigned char *data) -{ - int bandwidth; - if (data[0]&0x80) - { - bandwidth = OPUS_BANDWIDTH_MEDIUMBAND + ((data[0]>>5)&0x3); - if (bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) - bandwidth = OPUS_BANDWIDTH_NARROWBAND; - } else if ((data[0]&0x60) == 0x60) - { - bandwidth = (data[0]&0x10) ? OPUS_BANDWIDTH_FULLBAND : - OPUS_BANDWIDTH_SUPERWIDEBAND; - } else { - bandwidth = OPUS_BANDWIDTH_NARROWBAND + ((data[0]>>5)&0x3); - } - return bandwidth; -} - -int opus_packet_get_samples_per_frame(const unsigned char *data, - opus_int32 Fs) -{ - int audiosize; - if (data[0]&0x80) - { - audiosize = ((data[0]>>3)&0x3); - audiosize = (Fs<>3)&0x3); - if (audiosize == 3) - audiosize = Fs*60/1000; - else - audiosize = (Fs< Fs*3) - return OPUS_INVALID_PACKET; - else - return samples; -} - -int opus_decoder_get_nb_samples(const OpusDecoder *dec, - const unsigned char packet[], opus_int32 len) -{ - return opus_packet_get_nb_samples(packet, len, dec->Fs); -} diff --git a/src/opus-1.0.2/src/opus_encoder.c b/src/opus-1.0.2/src/opus_encoder.c deleted file mode 100644 index aae31256..00000000 --- a/src/opus-1.0.2/src/opus_encoder.c +++ /dev/null @@ -1,1617 +0,0 @@ -/* Copyright (c) 2010-2011 Xiph.Org Foundation, Skype Limited - Written by Jean-Marc Valin and Koen Vos */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "celt.h" -#include "entenc.h" -#include "modes.h" -#include "API.h" -#include "stack_alloc.h" -#include "float_cast.h" -#include "opus.h" -#include "arch.h" -#include "opus_private.h" -#include "os_support.h" - -#include "tuning_parameters.h" -#ifdef FIXED_POINT -#include "fixed/structs_FIX.h" -#else -#include "float/structs_FLP.h" -#endif - -#define MAX_ENCODER_BUFFER 480 - -struct OpusEncoder { - int celt_enc_offset; - int silk_enc_offset; - silk_EncControlStruct silk_mode; - int application; - int channels; - int delay_compensation; - int force_channels; - int signal_type; - int user_bandwidth; - int max_bandwidth; - int user_forced_mode; - int voice_ratio; - opus_int32 Fs; - int use_vbr; - int vbr_constraint; - opus_int32 bitrate_bps; - opus_int32 user_bitrate_bps; - int encoder_buffer; - -#define OPUS_ENCODER_RESET_START stream_channels - int stream_channels; - opus_int16 hybrid_stereo_width_Q14; - opus_int32 variable_HP_smth2_Q15; - opus_val32 hp_mem[4]; - int mode; - int prev_mode; - int prev_channels; - int prev_framesize; - int bandwidth; - int silk_bw_switch; - /* Sampling rate (at the API level) */ - int first; - opus_val16 delay_buffer[MAX_ENCODER_BUFFER*2]; - - opus_uint32 rangeFinal; -}; - -/* Transition tables for the voice and music. First column is the - middle (memoriless) threshold. The second column is the hysteresis - (difference with the middle) */ -static const opus_int32 mono_voice_bandwidth_thresholds[8] = { - 11000, 1000, /* NB<->MB */ - 14000, 1000, /* MB<->WB */ - 21000, 2000, /* WB<->SWB */ - 29000, 2000, /* SWB<->FB */ -}; -static const opus_int32 mono_music_bandwidth_thresholds[8] = { - 14000, 1000, /* MB not allowed */ - 18000, 2000, /* MB<->WB */ - 24000, 2000, /* WB<->SWB */ - 33000, 2000, /* SWB<->FB */ -}; -static const opus_int32 stereo_voice_bandwidth_thresholds[8] = { - 11000, 1000, /* NB<->MB */ - 14000, 1000, /* MB<->WB */ - 21000, 2000, /* WB<->SWB */ - 32000, 2000, /* SWB<->FB */ -}; -static const opus_int32 stereo_music_bandwidth_thresholds[8] = { - 14000, 1000, /* MB not allowed */ - 18000, 2000, /* MB<->WB */ - 24000, 2000, /* WB<->SWB */ - 48000, 2000, /* SWB<->FB */ -}; -/* Threshold bit-rates for switching between mono and stereo */ -static const opus_int32 stereo_voice_threshold = 26000; -static const opus_int32 stereo_music_threshold = 36000; - -/* Threshold bit-rate for switching between SILK/hybrid and CELT-only */ -static const opus_int32 mode_thresholds[2][2] = { - /* voice */ /* music */ - { 48000, 24000}, /* mono */ - { 48000, 24000}, /* stereo */ -}; - -int opus_encoder_get_size(int channels) -{ - int silkEncSizeBytes, celtEncSizeBytes; - int ret; - if (channels<1 || channels > 2) - return 0; - ret = silk_Get_Encoder_Size( &silkEncSizeBytes ); - if (ret) - return 0; - silkEncSizeBytes = align(silkEncSizeBytes); - celtEncSizeBytes = celt_encoder_get_size(channels); - return align(sizeof(OpusEncoder))+silkEncSizeBytes+celtEncSizeBytes; -} - -int opus_encoder_init(OpusEncoder* st, opus_int32 Fs, int channels, int application) -{ - void *silk_enc; - CELTEncoder *celt_enc; - int err; - int ret, silkEncSizeBytes; - - if((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)||(channels!=1&&channels!=2)|| - (application != OPUS_APPLICATION_VOIP && application != OPUS_APPLICATION_AUDIO - && application != OPUS_APPLICATION_RESTRICTED_LOWDELAY)) - return OPUS_BAD_ARG; - - OPUS_CLEAR((char*)st, opus_encoder_get_size(channels)); - /* Create SILK encoder */ - ret = silk_Get_Encoder_Size( &silkEncSizeBytes ); - if (ret) - return OPUS_BAD_ARG; - silkEncSizeBytes = align(silkEncSizeBytes); - st->silk_enc_offset = align(sizeof(OpusEncoder)); - st->celt_enc_offset = st->silk_enc_offset+silkEncSizeBytes; - silk_enc = (char*)st+st->silk_enc_offset; - celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset); - - st->stream_channels = st->channels = channels; - - st->Fs = Fs; - - ret = silk_InitEncoder( silk_enc, &st->silk_mode ); - if(ret)return OPUS_INTERNAL_ERROR; - - /* default SILK parameters */ - st->silk_mode.nChannelsAPI = channels; - st->silk_mode.nChannelsInternal = channels; - st->silk_mode.API_sampleRate = st->Fs; - st->silk_mode.maxInternalSampleRate = 16000; - st->silk_mode.minInternalSampleRate = 8000; - st->silk_mode.desiredInternalSampleRate = 16000; - st->silk_mode.payloadSize_ms = 20; - st->silk_mode.bitRate = 25000; - st->silk_mode.packetLossPercentage = 0; - st->silk_mode.complexity = 10; - st->silk_mode.useInBandFEC = 0; - st->silk_mode.useDTX = 0; - st->silk_mode.useCBR = 0; - - /* Create CELT encoder */ - /* Initialize CELT encoder */ - err = celt_encoder_init(celt_enc, Fs, channels); - if(err!=OPUS_OK)return OPUS_INTERNAL_ERROR; - - celt_encoder_ctl(celt_enc, CELT_SET_SIGNALLING(0)); - celt_encoder_ctl(celt_enc, OPUS_SET_COMPLEXITY(10)); - - st->use_vbr = 1; - /* Makes constrained VBR the default (safer for real-time use) */ - st->vbr_constraint = 1; - st->user_bitrate_bps = OPUS_AUTO; - st->bitrate_bps = 3000+Fs*channels; - st->application = application; - st->signal_type = OPUS_AUTO; - st->user_bandwidth = OPUS_AUTO; - st->max_bandwidth = OPUS_BANDWIDTH_FULLBAND; - st->force_channels = OPUS_AUTO; - st->user_forced_mode = OPUS_AUTO; - st->voice_ratio = -1; - st->encoder_buffer = st->Fs/100; - - /* Delay compensation of 4 ms (2.5 ms for SILK's extra look-ahead - + 1.5 ms for SILK resamplers and stereo prediction) */ - st->delay_compensation = st->Fs/250; - - st->hybrid_stereo_width_Q14 = 1 << 14; - st->variable_HP_smth2_Q15 = silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 ); - st->first = 1; - st->mode = MODE_HYBRID; - st->bandwidth = OPUS_BANDWIDTH_FULLBAND; - - return OPUS_OK; -} - -static int pad_frame(unsigned char *data, opus_int32 len, opus_int32 new_len) -{ - if (len == new_len) - return 0; - if (len > new_len) - return 1; - - if ((data[0]&0x3)==0) - { - int i; - int padding, nb_255s; - - padding = new_len - len; - if (padding >= 2) - { - nb_255s = (padding-2)/255; - - for (i=len-1;i>=1;i--) - data[i+nb_255s+2] = data[i]; - data[0] |= 0x3; - data[1] = 0x41; - for (i=0;i=1;i--) - data[i+1] = data[i]; - data[0] |= 0x3; - data[1] = 1; - } - return 0; - } else { - return 1; - } -} - -static unsigned char gen_toc(int mode, int framerate, int bandwidth, int channels) -{ - int period; - unsigned char toc; - period = 0; - while (framerate < 400) - { - framerate <<= 1; - period++; - } - if (mode == MODE_SILK_ONLY) - { - toc = (bandwidth-OPUS_BANDWIDTH_NARROWBAND)<<5; - toc |= (period-2)<<3; - } else if (mode == MODE_CELT_ONLY) - { - int tmp = bandwidth-OPUS_BANDWIDTH_MEDIUMBAND; - if (tmp < 0) - tmp = 0; - toc = 0x80; - toc |= tmp << 5; - toc |= period<<3; - } else /* Hybrid */ - { - toc = 0x60; - toc |= (bandwidth-OPUS_BANDWIDTH_SUPERWIDEBAND)<<4; - toc |= (period-2)<<3; - } - toc |= (channels==2)<<2; - return toc; -} - -#ifndef FIXED_POINT -static void silk_biquad_float( - const opus_val16 *in, /* I: Input signal */ - const opus_int32 *B_Q28, /* I: MA coefficients [3] */ - const opus_int32 *A_Q28, /* I: AR coefficients [2] */ - opus_val32 *S, /* I/O: State vector [2] */ - opus_val16 *out, /* O: Output signal */ - const opus_int32 len, /* I: Signal length (must be even) */ - int stride -) -{ - /* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */ - opus_int k; - opus_val32 vout; - opus_val32 inval; - opus_val32 A[2], B[3]; - - A[0] = (opus_val32)(A_Q28[0] * (1.f/((opus_int32)1<<28))); - A[1] = (opus_val32)(A_Q28[1] * (1.f/((opus_int32)1<<28))); - B[0] = (opus_val32)(B_Q28[0] * (1.f/((opus_int32)1<<28))); - B[1] = (opus_val32)(B_Q28[1] * (1.f/((opus_int32)1<<28))); - B[2] = (opus_val32)(B_Q28[2] * (1.f/((opus_int32)1<<28))); - - /* Negate A_Q28 values and split in two parts */ - - for( k = 0; k < len; k++ ) { - /* S[ 0 ], S[ 1 ]: Q12 */ - inval = in[ k*stride ]; - vout = S[ 0 ] + B[0]*inval; - - S[ 0 ] = S[1] - vout*A[0] + B[1]*inval; - - S[ 1 ] = - vout*A[1] + B[2]*inval; - - /* Scale back to Q0 and saturate */ - out[ k*stride ] = vout; - } -} -#endif - -static void hp_cutoff(const opus_val16 *in, opus_int32 cutoff_Hz, opus_val16 *out, opus_val32 *hp_mem, int len, int channels, opus_int32 Fs) -{ - opus_int32 B_Q28[ 3 ], A_Q28[ 2 ]; - opus_int32 Fc_Q19, r_Q28, r_Q22; - - silk_assert( cutoff_Hz <= silk_int32_MAX / SILK_FIX_CONST( 1.5 * 3.14159 / 1000, 19 ) ); - Fc_Q19 = silk_DIV32_16( silk_SMULBB( SILK_FIX_CONST( 1.5 * 3.14159 / 1000, 19 ), cutoff_Hz ), Fs/1000 ); - silk_assert( Fc_Q19 > 0 && Fc_Q19 < 32768 ); - - r_Q28 = SILK_FIX_CONST( 1.0, 28 ) - silk_MUL( SILK_FIX_CONST( 0.92, 9 ), Fc_Q19 ); - - /* b = r * [ 1; -2; 1 ]; */ - /* a = [ 1; -2 * r * ( 1 - 0.5 * Fc^2 ); r^2 ]; */ - B_Q28[ 0 ] = r_Q28; - B_Q28[ 1 ] = silk_LSHIFT( -r_Q28, 1 ); - B_Q28[ 2 ] = r_Q28; - - /* -r * ( 2 - Fc * Fc ); */ - r_Q22 = silk_RSHIFT( r_Q28, 6 ); - A_Q28[ 0 ] = silk_SMULWW( r_Q22, silk_SMULWW( Fc_Q19, Fc_Q19 ) - SILK_FIX_CONST( 2.0, 22 ) ); - A_Q28[ 1 ] = silk_SMULWW( r_Q22, r_Q22 ); - -#ifdef FIXED_POINT - silk_biquad_alt( in, B_Q28, A_Q28, hp_mem, out, len, channels ); - if( channels == 2 ) { - silk_biquad_alt( in+1, B_Q28, A_Q28, hp_mem+2, out+1, len, channels ); - } -#else - silk_biquad_float( in, B_Q28, A_Q28, hp_mem, out, len, channels ); - if( channels == 2 ) { - silk_biquad_float( in+1, B_Q28, A_Q28, hp_mem+2, out+1, len, channels ); - } -#endif -} - -static void stereo_fade(const opus_val16 *in, opus_val16 *out, opus_val16 g1, opus_val16 g2, - int overlap48, int frame_size, int channels, const opus_val16 *window, opus_int32 Fs) -{ - int i; - int overlap; - int inc; - inc = 48000/Fs; - overlap=overlap48/inc; - g1 = Q15ONE-g1; - g2 = Q15ONE-g2; - for (i=0;iFs/400; - if (st->user_bitrate_bps==OPUS_AUTO) - return 60*st->Fs/frame_size + st->Fs*st->channels; - else if (st->user_bitrate_bps==OPUS_BITRATE_MAX) - return max_data_bytes*8*st->Fs/frame_size; - else - return st->user_bitrate_bps; -} - -#ifdef FIXED_POINT -#define opus_encode_native opus_encode -opus_int32 opus_encode(OpusEncoder *st, const opus_val16 *pcm, int frame_size, - unsigned char *data, opus_int32 out_data_bytes) -#else -#define opus_encode_native opus_encode_float -opus_int32 opus_encode_float(OpusEncoder *st, const opus_val16 *pcm, int frame_size, - unsigned char *data, opus_int32 out_data_bytes) -#endif -{ - void *silk_enc; - CELTEncoder *celt_enc; - int i; - int ret=0; - opus_int32 nBytes; - ec_enc enc; - int bytes_target; - int prefill=0; - int start_band = 0; - int redundancy = 0; - int redundancy_bytes = 0; /* Number of bytes to use for redundancy frame */ - int celt_to_silk = 0; - VARDECL(opus_val16, pcm_buf); - int nb_compr_bytes; - int to_celt = 0; - opus_uint32 redundant_rng = 0; - int cutoff_Hz, hp_freq_smth1; - int voice_est; /* Probability of voice in Q7 */ - opus_int32 equiv_rate; - int delay_compensation; - int frame_rate; - opus_int32 max_rate; /* Max bitrate we're allowed to use */ - int curr_bandwidth; - opus_int32 max_data_bytes; /* Max number of bytes we're allowed to use */ - VARDECL(opus_val16, tmp_prefill); - - ALLOC_STACK; - - max_data_bytes = IMIN(1276, out_data_bytes); - - st->rangeFinal = 0; - if (400*frame_size != st->Fs && 200*frame_size != st->Fs && 100*frame_size != st->Fs && - 50*frame_size != st->Fs && 25*frame_size != st->Fs && 50*frame_size != 3*st->Fs) - { - RESTORE_STACK; - return OPUS_BAD_ARG; - } - if (max_data_bytes<=0) - { - RESTORE_STACK; - return OPUS_BAD_ARG; - } - silk_enc = (char*)st+st->silk_enc_offset; - celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset); - - if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY) - delay_compensation = 0; - else - delay_compensation = st->delay_compensation; - - st->bitrate_bps = user_bitrate_to_bitrate(st, frame_size, max_data_bytes); - - frame_rate = st->Fs/frame_size; - if (max_data_bytes<3 || st->bitrate_bps < 3*frame_rate*8 - || (frame_rate<50 && (max_data_bytes*frame_rate<300 || st->bitrate_bps < 2400))) - { - /*If the space is too low to do something useful, emit 'PLC' frames.*/ - int tocmode = st->mode; - int bw = st->bandwidth == 0 ? OPUS_BANDWIDTH_NARROWBAND : st->bandwidth; - if (tocmode==0) - tocmode = MODE_SILK_ONLY; - if (frame_rate>100) - tocmode = MODE_CELT_ONLY; - if (frame_rate < 50) - tocmode = MODE_SILK_ONLY; - if(tocmode==MODE_SILK_ONLY&&bw>OPUS_BANDWIDTH_WIDEBAND) - bw=OPUS_BANDWIDTH_WIDEBAND; - else if (tocmode==MODE_CELT_ONLY&&bw==OPUS_BANDWIDTH_MEDIUMBAND) - bw=OPUS_BANDWIDTH_NARROWBAND; - else if (bw<=OPUS_BANDWIDTH_SUPERWIDEBAND) - bw=OPUS_BANDWIDTH_SUPERWIDEBAND; - data[0] = gen_toc(tocmode, frame_rate, bw, st->stream_channels); - RESTORE_STACK; - return 1; - } - if (!st->use_vbr) - { - int cbrBytes; - cbrBytes = IMIN( (st->bitrate_bps + 4*frame_rate)/(8*frame_rate) , max_data_bytes); - st->bitrate_bps = cbrBytes * (8*frame_rate); - max_data_bytes = cbrBytes; - } - max_rate = frame_rate*max_data_bytes*8; - - /* Equivalent 20-ms rate for mode/channel/bandwidth decisions */ - equiv_rate = st->bitrate_bps - 60*(st->Fs/frame_size - 50); - - if (st->signal_type == OPUS_SIGNAL_VOICE) - voice_est = 127; - else if (st->signal_type == OPUS_SIGNAL_MUSIC) - voice_est = 0; - else if (st->voice_ratio >= 0) - voice_est = st->voice_ratio*327>>8; - else if (st->application == OPUS_APPLICATION_VOIP) - voice_est = 115; - else - voice_est = 48; - - if (st->force_channels!=OPUS_AUTO && st->channels == 2) - { - st->stream_channels = st->force_channels; - } else { -#ifdef FUZZING - /* Random mono/stereo decision */ - if (st->channels == 2 && (rand()&0x1F)==0) - st->stream_channels = 3-st->stream_channels; -#else - /* Rate-dependent mono-stereo decision */ - if (st->channels == 2) - { - opus_int32 stereo_threshold; - stereo_threshold = stereo_music_threshold + ((voice_est*voice_est*(stereo_voice_threshold-stereo_music_threshold))>>14); - if (st->stream_channels == 2) - stereo_threshold -= 4000; - else - stereo_threshold += 4000; - st->stream_channels = (equiv_rate > stereo_threshold) ? 2 : 1; - } else { - st->stream_channels = st->channels; - } -#endif - } - - /* Mode selection depending on application and signal type */ - if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY) - { - st->mode = MODE_CELT_ONLY; - } else if (st->user_forced_mode == OPUS_AUTO) - { -#ifdef FUZZING - /* Random mode switching */ - if ((rand()&0xF)==0) - { - if ((rand()&0x1)==0) - st->mode = MODE_CELT_ONLY; - else - st->mode = MODE_SILK_ONLY; - } else { - if (st->prev_mode==MODE_CELT_ONLY) - st->mode = MODE_CELT_ONLY; - else - st->mode = MODE_SILK_ONLY; - } -#else - int chan; - opus_int32 mode_voice, mode_music; - opus_int32 threshold; - - chan = (st->channels==2) && st->force_channels!=1; - mode_voice = mode_thresholds[chan][0]; - mode_music = mode_thresholds[chan][1]; - threshold = mode_music + ((voice_est*voice_est*(mode_voice-mode_music))>>14); - - /* Hysteresis */ - if (st->prev_mode == MODE_CELT_ONLY) - threshold -= 4000; - else if (st->prev_mode>0) - threshold += 4000; - - st->mode = (equiv_rate >= threshold) ? MODE_CELT_ONLY: MODE_SILK_ONLY; - - /* When FEC is enabled and there's enough packet loss, use SILK */ - if (st->silk_mode.useInBandFEC && st->silk_mode.packetLossPercentage > (128-voice_est)>>4) - st->mode = MODE_SILK_ONLY; - /* When encoding voice and DTX is enabled, set the encoder to SILK mode (at least for now) */ - if (st->silk_mode.useDTX && voice_est > 100) - st->mode = MODE_SILK_ONLY; -#endif - } else { - st->mode = st->user_forced_mode; - } - - /* Override the chosen mode to make sure we meet the requested frame size */ - if (st->mode != MODE_CELT_ONLY && frame_size < st->Fs/100) - st->mode = MODE_CELT_ONLY; - - if (st->stream_channels == 1 && st->prev_channels ==2 && st->silk_mode.toMono==0 - && st->mode != MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY) - { - /* Delay stereo->mono transition by two frames so that SILK can do a smooth downmix */ - st->silk_mode.toMono = 1; - st->stream_channels = 2; - } else { - st->silk_mode.toMono = 0; - } - - if (st->prev_mode > 0 && - ((st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) || - (st->mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY))) - { - redundancy = 1; - celt_to_silk = (st->mode != MODE_CELT_ONLY); - if (!celt_to_silk) - { - /* Switch to SILK/hybrid if frame size is 10 ms or more*/ - if (frame_size >= st->Fs/100) - { - st->mode = st->prev_mode; - to_celt = 1; - } else { - redundancy=0; - } - } - } - /* For the first frame at a new SILK bandwidth */ - if (st->silk_bw_switch) - { - redundancy = 1; - celt_to_silk = 1; - st->silk_bw_switch = 0; - } - - if (redundancy) - { - /* Fair share of the max size allowed */ - redundancy_bytes = IMIN(257, max_data_bytes*(opus_int32)(st->Fs/200)/(frame_size+st->Fs/200)); - /* For VBR, target the actual bitrate (subject to the limit above) */ - if (st->use_vbr) - redundancy_bytes = IMIN(redundancy_bytes, st->bitrate_bps/1600); - } - - if (st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) - { - silk_EncControlStruct dummy; - silk_InitEncoder( silk_enc, &dummy); - prefill=1; - } - - /* Automatic (rate-dependent) bandwidth selection */ - if (st->mode == MODE_CELT_ONLY || st->first || st->silk_mode.allowBandwidthSwitch) - { - const opus_int32 *voice_bandwidth_thresholds, *music_bandwidth_thresholds; - opus_int32 bandwidth_thresholds[8]; - int bandwidth = OPUS_BANDWIDTH_FULLBAND; - opus_int32 equiv_rate2; - - equiv_rate2 = equiv_rate; - if (st->mode != MODE_CELT_ONLY) - { - /* Adjust the threshold +/- 10% depending on complexity */ - equiv_rate2 = equiv_rate2 * (45+st->silk_mode.complexity)/50; - /* CBR is less efficient by ~1 kb/s */ - if (!st->use_vbr) - equiv_rate2 -= 1000; - } - if (st->channels==2 && st->force_channels!=1) - { - voice_bandwidth_thresholds = stereo_voice_bandwidth_thresholds; - music_bandwidth_thresholds = stereo_music_bandwidth_thresholds; - } else { - voice_bandwidth_thresholds = mono_voice_bandwidth_thresholds; - music_bandwidth_thresholds = mono_music_bandwidth_thresholds; - } - /* Interpolate bandwidth thresholds depending on voice estimation */ - for (i=0;i<8;i++) - { - bandwidth_thresholds[i] = music_bandwidth_thresholds[i] - + ((voice_est*voice_est*(voice_bandwidth_thresholds[i]-music_bandwidth_thresholds[i]))>>14); - } - do { - int threshold, hysteresis; - threshold = bandwidth_thresholds[2*(bandwidth-OPUS_BANDWIDTH_MEDIUMBAND)]; - hysteresis = bandwidth_thresholds[2*(bandwidth-OPUS_BANDWIDTH_MEDIUMBAND)+1]; - if (!st->first) - { - if (st->bandwidth >= bandwidth) - threshold -= hysteresis; - else - threshold += hysteresis; - } - if (equiv_rate2 >= threshold) - break; - } while (--bandwidth>OPUS_BANDWIDTH_NARROWBAND); - st->bandwidth = bandwidth; - /* Prevents any transition to SWB/FB until the SILK layer has fully - switched to WB mode and turned the variable LP filter off */ - if (!st->first && st->mode != MODE_CELT_ONLY && !st->silk_mode.inWBmodeWithoutVariableLP && st->bandwidth > OPUS_BANDWIDTH_WIDEBAND) - st->bandwidth = OPUS_BANDWIDTH_WIDEBAND; - } - - if (st->bandwidth>st->max_bandwidth) - st->bandwidth = st->max_bandwidth; - - if (st->user_bandwidth != OPUS_AUTO) - st->bandwidth = st->user_bandwidth; - - /* This prevents us from using hybrid at unsafe CBR/max rates */ - if (st->mode != MODE_CELT_ONLY && max_rate < 15000) - { - st->bandwidth = IMIN(st->bandwidth, OPUS_BANDWIDTH_WIDEBAND); - } - - /* Prevents Opus from wasting bits on frequencies that are above - the Nyquist rate of the input signal */ - if (st->Fs <= 24000 && st->bandwidth > OPUS_BANDWIDTH_SUPERWIDEBAND) - st->bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND; - if (st->Fs <= 16000 && st->bandwidth > OPUS_BANDWIDTH_WIDEBAND) - st->bandwidth = OPUS_BANDWIDTH_WIDEBAND; - if (st->Fs <= 12000 && st->bandwidth > OPUS_BANDWIDTH_MEDIUMBAND) - st->bandwidth = OPUS_BANDWIDTH_MEDIUMBAND; - if (st->Fs <= 8000 && st->bandwidth > OPUS_BANDWIDTH_NARROWBAND) - st->bandwidth = OPUS_BANDWIDTH_NARROWBAND; - - /* If max_data_bytes represents less than 8 kb/s, switch to CELT-only mode */ - if (max_data_bytes < (frame_rate > 50 ? 12000 : 8000)*frame_size / (st->Fs * 8)) - st->mode = MODE_CELT_ONLY; - - /* CELT mode doesn't support mediumband, use wideband instead */ - if (st->mode == MODE_CELT_ONLY && st->bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) - st->bandwidth = OPUS_BANDWIDTH_WIDEBAND; - - /* Can't support higher than wideband for >20 ms frames */ - if (frame_size > st->Fs/50 && (st->mode == MODE_CELT_ONLY || st->bandwidth > OPUS_BANDWIDTH_WIDEBAND)) - { - VARDECL(unsigned char, tmp_data); - int nb_frames; - int bak_mode, bak_bandwidth, bak_channels, bak_to_mono; - OpusRepacketizer rp; - opus_int32 bytes_per_frame; - - - nb_frames = frame_size > st->Fs/25 ? 3 : 2; - bytes_per_frame = IMIN(1276,(out_data_bytes-3)/nb_frames); - - ALLOC(tmp_data, nb_frames*bytes_per_frame, unsigned char); - - opus_repacketizer_init(&rp); - - bak_mode = st->user_forced_mode; - bak_bandwidth = st->user_bandwidth; - bak_channels = st->force_channels; - - st->user_forced_mode = st->mode; - st->user_bandwidth = st->bandwidth; - st->force_channels = st->stream_channels; - bak_to_mono = st->silk_mode.toMono; - - if (bak_to_mono) - st->force_channels = 1; - else - st->prev_channels = st->stream_channels; - for (i=0;isilk_mode.toMono = 0; - /* When switching from SILK/Hybrid to CELT, only ask for a switch at the last frame */ - if (to_celt && i==nb_frames-1) - st->user_forced_mode = MODE_CELT_ONLY; - tmp_len = opus_encode_native(st, pcm+i*(st->channels*st->Fs/50), st->Fs/50, tmp_data+i*bytes_per_frame, bytes_per_frame); - if (tmp_len<0) - { - RESTORE_STACK; - return OPUS_INTERNAL_ERROR; - } - ret = opus_repacketizer_cat(&rp, tmp_data+i*bytes_per_frame, tmp_len); - if (ret<0) - { - RESTORE_STACK; - return OPUS_INTERNAL_ERROR; - } - } - ret = opus_repacketizer_out(&rp, data, out_data_bytes); - if (ret<0) - { - RESTORE_STACK; - return OPUS_INTERNAL_ERROR; - } - st->user_forced_mode = bak_mode; - st->user_bandwidth = bak_bandwidth; - st->force_channels = bak_channels; - st->silk_mode.toMono = bak_to_mono; - RESTORE_STACK; - return ret; - } - - curr_bandwidth = st->bandwidth; - - /* Chooses the appropriate mode for speech - *NEVER* switch to/from CELT-only mode here as this will invalidate some assumptions */ - if (st->mode == MODE_SILK_ONLY && curr_bandwidth > OPUS_BANDWIDTH_WIDEBAND) - st->mode = MODE_HYBRID; - if (st->mode == MODE_HYBRID && curr_bandwidth <= OPUS_BANDWIDTH_WIDEBAND) - st->mode = MODE_SILK_ONLY; - - /* printf("%d %d %d %d\n", st->bitrate_bps, st->stream_channels, st->mode, curr_bandwidth); */ - bytes_target = IMIN(max_data_bytes-redundancy_bytes, st->bitrate_bps * frame_size / (st->Fs * 8)) - 1; - - data += 1; - - ec_enc_init(&enc, data, max_data_bytes-1); - - ALLOC(pcm_buf, (delay_compensation+frame_size)*st->channels, opus_val16); - for (i=0;ichannels;i++) - pcm_buf[i] = st->delay_buffer[(st->encoder_buffer-delay_compensation)*st->channels+i]; - - if (st->mode == MODE_CELT_ONLY) - hp_freq_smth1 = silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 ); - else - hp_freq_smth1 = ((silk_encoder*)silk_enc)->state_Fxx[0].sCmn.variable_HP_smth1_Q15; - - st->variable_HP_smth2_Q15 = silk_SMLAWB( st->variable_HP_smth2_Q15, - hp_freq_smth1 - st->variable_HP_smth2_Q15, SILK_FIX_CONST( VARIABLE_HP_SMTH_COEF2, 16 ) ); - - /* convert from log scale to Hertz */ - cutoff_Hz = silk_log2lin( silk_RSHIFT( st->variable_HP_smth2_Q15, 8 ) ); - - if (st->application == OPUS_APPLICATION_VOIP) - { - hp_cutoff(pcm, cutoff_Hz, &pcm_buf[delay_compensation*st->channels], st->hp_mem, frame_size, st->channels, st->Fs); - } else { - for (i=0;ichannels;i++) - pcm_buf[delay_compensation*st->channels + i] = pcm[i]; - } - - /* SILK processing */ - if (st->mode != MODE_CELT_ONLY) - { -#ifdef FIXED_POINT - const opus_int16 *pcm_silk; -#else - VARDECL(opus_int16, pcm_silk); - ALLOC(pcm_silk, st->channels*frame_size, opus_int16); -#endif - st->silk_mode.bitRate = 8*bytes_target*frame_rate; - if( st->mode == MODE_HYBRID ) { - st->silk_mode.bitRate /= st->stream_channels; - if( curr_bandwidth == OPUS_BANDWIDTH_SUPERWIDEBAND ) { - if( st->Fs == 100 * frame_size ) { - /* 24 kHz, 10 ms */ - st->silk_mode.bitRate = ( ( st->silk_mode.bitRate + 2000 + st->use_vbr * 1000 ) * 2 ) / 3; - } else { - /* 24 kHz, 20 ms */ - st->silk_mode.bitRate = ( ( st->silk_mode.bitRate + 1000 + st->use_vbr * 1000 ) * 2 ) / 3; - } - } else { - if( st->Fs == 100 * frame_size ) { - /* 48 kHz, 10 ms */ - st->silk_mode.bitRate = ( st->silk_mode.bitRate + 8000 + st->use_vbr * 3000 ) / 2; - } else { - /* 48 kHz, 20 ms */ - st->silk_mode.bitRate = ( st->silk_mode.bitRate + 9000 + st->use_vbr * 1000 ) / 2; - } - } - st->silk_mode.bitRate *= st->stream_channels; - /* don't let SILK use more than 80% */ - if( st->silk_mode.bitRate > ( st->bitrate_bps - 8*st->Fs/frame_size ) * 4/5 ) { - st->silk_mode.bitRate = ( st->bitrate_bps - 8*st->Fs/frame_size ) * 4/5; - } - } - - st->silk_mode.payloadSize_ms = 1000 * frame_size / st->Fs; - st->silk_mode.nChannelsAPI = st->channels; - st->silk_mode.nChannelsInternal = st->stream_channels; - if (curr_bandwidth == OPUS_BANDWIDTH_NARROWBAND) { - st->silk_mode.desiredInternalSampleRate = 8000; - } else if (curr_bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) { - st->silk_mode.desiredInternalSampleRate = 12000; - } else { - silk_assert( st->mode == MODE_HYBRID || curr_bandwidth == OPUS_BANDWIDTH_WIDEBAND ); - st->silk_mode.desiredInternalSampleRate = 16000; - } - if( st->mode == MODE_HYBRID ) { - /* Don't allow bandwidth reduction at lowest bitrates in hybrid mode */ - st->silk_mode.minInternalSampleRate = 16000; - } else { - st->silk_mode.minInternalSampleRate = 8000; - } - - if (st->mode == MODE_SILK_ONLY) - { - opus_int32 effective_max_rate = max_rate; - st->silk_mode.maxInternalSampleRate = 16000; - if (frame_rate > 50) - effective_max_rate = effective_max_rate*2/3; - if (effective_max_rate < 13000) - { - st->silk_mode.maxInternalSampleRate = 12000; - st->silk_mode.desiredInternalSampleRate = IMIN(12000, st->silk_mode.desiredInternalSampleRate); - } - if (effective_max_rate < 9600) - { - st->silk_mode.maxInternalSampleRate = 8000; - st->silk_mode.desiredInternalSampleRate = IMIN(8000, st->silk_mode.desiredInternalSampleRate); - } - } else { - st->silk_mode.maxInternalSampleRate = 16000; - } - - st->silk_mode.useCBR = !st->use_vbr; - - /* Call SILK encoder for the low band */ - nBytes = IMIN(1275, max_data_bytes-1-redundancy_bytes); - - st->silk_mode.maxBits = nBytes*8; - /* Only allow up to 90% of the bits for hybrid mode*/ - if (st->mode == MODE_HYBRID) - st->silk_mode.maxBits = (opus_int32)st->silk_mode.maxBits*9/10; - if (st->silk_mode.useCBR) - { - st->silk_mode.maxBits = (st->silk_mode.bitRate * frame_size / (st->Fs * 8))*8; - /* Reduce the initial target to make it easier to reach the CBR rate */ - st->silk_mode.bitRate = IMAX(1, st->silk_mode.bitRate-2000); - } - - if (prefill) - { - opus_int32 zero=0; -#ifdef FIXED_POINT - pcm_silk = st->delay_buffer; -#else - for (i=0;iencoder_buffer*st->channels;i++) - pcm_silk[i] = FLOAT2INT16(st->delay_buffer[i]); -#endif - silk_Encode( silk_enc, &st->silk_mode, pcm_silk, st->encoder_buffer, NULL, &zero, 1 ); - } - -#ifdef FIXED_POINT - pcm_silk = pcm_buf+delay_compensation*st->channels; -#else - for (i=0;ichannels;i++) - pcm_silk[i] = FLOAT2INT16(pcm_buf[delay_compensation*st->channels + i]); -#endif - ret = silk_Encode( silk_enc, &st->silk_mode, pcm_silk, frame_size, &enc, &nBytes, 0 ); - if( ret ) { - /*fprintf (stderr, "SILK encode error: %d\n", ret);*/ - /* Handle error */ - RESTORE_STACK; - return OPUS_INTERNAL_ERROR; - } - if (nBytes==0) - { - st->rangeFinal = 0; - data[-1] = gen_toc(st->mode, st->Fs/frame_size, curr_bandwidth, st->stream_channels); - RESTORE_STACK; - return 1; - } - /* Extract SILK internal bandwidth for signaling in first byte */ - if( st->mode == MODE_SILK_ONLY ) { - if( st->silk_mode.internalSampleRate == 8000 ) { - curr_bandwidth = OPUS_BANDWIDTH_NARROWBAND; - } else if( st->silk_mode.internalSampleRate == 12000 ) { - curr_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND; - } else if( st->silk_mode.internalSampleRate == 16000 ) { - curr_bandwidth = OPUS_BANDWIDTH_WIDEBAND; - } - } else { - silk_assert( st->silk_mode.internalSampleRate == 16000 ); - } - - st->silk_mode.opusCanSwitch = st->silk_mode.switchReady; - /* FIXME: How do we allocate the redundancy for CBR? */ - if (st->silk_mode.opusCanSwitch) - { - redundancy = 1; - celt_to_silk = 0; - st->silk_bw_switch = 1; - } - } - - /* CELT processing */ - { - int endband=21; - - switch(curr_bandwidth) - { - case OPUS_BANDWIDTH_NARROWBAND: - endband = 13; - break; - case OPUS_BANDWIDTH_MEDIUMBAND: - case OPUS_BANDWIDTH_WIDEBAND: - endband = 17; - break; - case OPUS_BANDWIDTH_SUPERWIDEBAND: - endband = 19; - break; - case OPUS_BANDWIDTH_FULLBAND: - endband = 21; - break; - } - celt_encoder_ctl(celt_enc, CELT_SET_END_BAND(endband)); - celt_encoder_ctl(celt_enc, CELT_SET_CHANNELS(st->stream_channels)); - } - celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(OPUS_BITRATE_MAX)); - if (st->mode != MODE_SILK_ONLY) - { - celt_encoder_ctl(celt_enc, OPUS_SET_VBR(0)); - /* Allow prediction unless we decide to disable it later */ - celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(2)); - - if (st->mode == MODE_HYBRID) - { - int len; - - len = (ec_tell(&enc)+7)>>3; - if (redundancy) - len += st->mode == MODE_HYBRID ? 3 : 1; - if( st->use_vbr ) { - nb_compr_bytes = len + bytes_target - (st->silk_mode.bitRate * frame_size) / (8 * st->Fs); - } else { - /* check if SILK used up too much */ - nb_compr_bytes = len > bytes_target ? len : bytes_target; - } - } else { - if (st->use_vbr) - { - celt_encoder_ctl(celt_enc, OPUS_SET_VBR(1)); - celt_encoder_ctl(celt_enc, OPUS_SET_VBR_CONSTRAINT(st->vbr_constraint)); - celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(st->bitrate_bps)); - nb_compr_bytes = max_data_bytes-1-redundancy_bytes; - } else { - nb_compr_bytes = bytes_target; - } - } - - } else { - nb_compr_bytes = 0; - } - - ALLOC(tmp_prefill, st->channels*st->Fs/400, opus_val16); - if (st->mode != MODE_SILK_ONLY && st->mode != st->prev_mode && st->prev_mode > 0) - { - for (i=0;ichannels*st->Fs/400;i++) - tmp_prefill[i] = st->delay_buffer[(st->encoder_buffer-st->delay_compensation-st->Fs/400)*st->channels + i]; - } - - for (i=0;ichannels*(st->encoder_buffer-(frame_size+delay_compensation));i++) - st->delay_buffer[i] = st->delay_buffer[i+st->channels*frame_size]; - for (;iencoder_buffer*st->channels;i++) - st->delay_buffer[i] = pcm_buf[(frame_size+delay_compensation-st->encoder_buffer)*st->channels+i]; - - - if (st->mode != MODE_HYBRID || st->stream_channels==1) - st->silk_mode.stereoWidth_Q14 = 1<<14; - if( st->channels == 2 ) { - /* Apply stereo width reduction (at low bitrates) */ - if( st->hybrid_stereo_width_Q14 < (1 << 14) || st->silk_mode.stereoWidth_Q14 < (1 << 14) ) { - opus_val16 g1, g2; - const CELTMode *celt_mode; - - celt_encoder_ctl(celt_enc, CELT_GET_MODE(&celt_mode)); - g1 = st->hybrid_stereo_width_Q14; - g2 = (opus_val16)(st->silk_mode.stereoWidth_Q14); -#ifdef FIXED_POINT - g1 = g1==16384 ? Q15ONE : SHL16(g1,1); - g2 = g2==16384 ? Q15ONE : SHL16(g2,1); -#else - g1 *= (1.f/16384); - g2 *= (1.f/16384); -#endif - stereo_fade(pcm_buf, pcm_buf, g1, g2, celt_mode->overlap, - frame_size, st->channels, celt_mode->window, st->Fs); - st->hybrid_stereo_width_Q14 = st->silk_mode.stereoWidth_Q14; - } - } - - if ( st->mode != MODE_CELT_ONLY && ec_tell(&enc)+17+20*(st->mode == MODE_HYBRID) <= 8*(max_data_bytes-1)) - { - /* For SILK mode, the redundancy is inferred from the length */ - if (st->mode == MODE_HYBRID && (redundancy || ec_tell(&enc)+37 <= 8*nb_compr_bytes)) - ec_enc_bit_logp(&enc, redundancy, 12); - if (redundancy) - { - int max_redundancy; - ec_enc_bit_logp(&enc, celt_to_silk, 1); - if (st->mode == MODE_HYBRID) - max_redundancy = (max_data_bytes-1)-nb_compr_bytes-1; - else - max_redundancy = (max_data_bytes-1)-((ec_tell(&enc)+7)>>3); - /* Target the same bit-rate for redundancy as for the rest, - up to a max of 257 bytes */ - redundancy_bytes = IMIN(max_redundancy, st->bitrate_bps/1600); - redundancy_bytes = IMIN(257, IMAX(2, redundancy_bytes)); - if (st->mode == MODE_HYBRID) - ec_enc_uint(&enc, redundancy_bytes-2, 256); - } - } else { - redundancy = 0; - } - - if (!redundancy) - { - st->silk_bw_switch = 0; - redundancy_bytes = 0; - } - if (st->mode != MODE_CELT_ONLY)start_band=17; - - if (st->mode == MODE_SILK_ONLY) - { - ret = (ec_tell(&enc)+7)>>3; - ec_enc_done(&enc); - nb_compr_bytes = ret; - } else { - nb_compr_bytes = IMIN((max_data_bytes-1)-redundancy_bytes, nb_compr_bytes); - ec_enc_shrink(&enc, nb_compr_bytes); - } - - - /* 5 ms redundant frame for CELT->SILK */ - if (redundancy && celt_to_silk) - { - int err; - celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0)); - celt_encoder_ctl(celt_enc, OPUS_SET_VBR(0)); - err = celt_encode_with_ec(celt_enc, pcm_buf, st->Fs/200, data+nb_compr_bytes, redundancy_bytes, NULL); - if (err < 0) - { - RESTORE_STACK; - return OPUS_INTERNAL_ERROR; - } - celt_encoder_ctl(celt_enc, OPUS_GET_FINAL_RANGE(&redundant_rng)); - celt_encoder_ctl(celt_enc, OPUS_RESET_STATE); - } - - celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(start_band)); - - if (st->mode != MODE_SILK_ONLY) - { - if (st->mode != st->prev_mode && st->prev_mode > 0) - { - unsigned char dummy[2]; - celt_encoder_ctl(celt_enc, OPUS_RESET_STATE); - - /* Prefilling */ - celt_encode_with_ec(celt_enc, tmp_prefill, st->Fs/400, dummy, 2, NULL); - celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(0)); - } - /* If false, we already busted the budget and we'll end up with a "PLC packet" */ - if (ec_tell(&enc) <= 8*nb_compr_bytes) - { - ret = celt_encode_with_ec(celt_enc, pcm_buf, frame_size, NULL, nb_compr_bytes, &enc); - if (ret < 0) - { - RESTORE_STACK; - return OPUS_INTERNAL_ERROR; - } - } - } - - /* 5 ms redundant frame for SILK->CELT */ - if (redundancy && !celt_to_silk) - { - int err; - unsigned char dummy[2]; - int N2, N4; - N2 = st->Fs/200; - N4 = st->Fs/400; - - celt_encoder_ctl(celt_enc, OPUS_RESET_STATE); - celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0)); - celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(0)); - - /* NOTE: We could speed this up slightly (at the expense of code size) by just adding a function that prefills the buffer */ - celt_encode_with_ec(celt_enc, pcm_buf+st->channels*(frame_size-N2-N4), N4, dummy, 2, NULL); - - err = celt_encode_with_ec(celt_enc, pcm_buf+st->channels*(frame_size-N2), N2, data+nb_compr_bytes, redundancy_bytes, NULL); - if (err < 0) - { - RESTORE_STACK; - return OPUS_INTERNAL_ERROR; - } - celt_encoder_ctl(celt_enc, OPUS_GET_FINAL_RANGE(&redundant_rng)); - } - - - - /* Signalling the mode in the first byte */ - data--; - data[0] = gen_toc(st->mode, st->Fs/frame_size, curr_bandwidth, st->stream_channels); - - st->rangeFinal = enc.rng ^ redundant_rng; - - if (to_celt) - st->prev_mode = MODE_CELT_ONLY; - else - st->prev_mode = st->mode; - st->prev_channels = st->stream_channels; - st->prev_framesize = frame_size; - - st->first = 0; - - /* In the unlikely case that the SILK encoder busted its target, tell - the decoder to call the PLC */ - if (ec_tell(&enc) > (max_data_bytes-1)*8) - { - if (max_data_bytes < 2) - { - RESTORE_STACK; - return OPUS_BUFFER_TOO_SMALL; - } - data[1] = 0; - ret = 1; - st->rangeFinal = 0; - } else if (st->mode==MODE_SILK_ONLY&&!redundancy) - { - /*When in LPC only mode it's perfectly - reasonable to strip off trailing zero bytes as - the required range decoder behavior is to - fill these in. This can't be done when the MDCT - modes are used because the decoder needs to know - the actual length for allocation purposes.*/ - while(ret>2&&data[ret]==0)ret--; - } - /* Count ToC and redundancy */ - ret += 1+redundancy_bytes; - if (!st->use_vbr && ret >= 3) - { - if (pad_frame(data, ret, max_data_bytes)) - { - RESTORE_STACK; - return OPUS_INTERNAL_ERROR; - } - ret = max_data_bytes; - } - RESTORE_STACK; - return ret; -} - -#ifdef FIXED_POINT - -#ifndef DISABLE_FLOAT_API -opus_int32 opus_encode_float(OpusEncoder *st, const float *pcm, int frame_size, - unsigned char *data, opus_int32 max_data_bytes) -{ - int i, ret; - VARDECL(opus_int16, in); - ALLOC_STACK; - - if(frame_size<0) - { - RESTORE_STACK; - return OPUS_BAD_ARG; - } - - ALLOC(in, frame_size*st->channels, opus_int16); - - for (i=0;ichannels;i++) - in[i] = FLOAT2INT16(pcm[i]); - ret = opus_encode(st, in, frame_size, data, max_data_bytes); - RESTORE_STACK; - return ret; -} -#endif - -#else -opus_int32 opus_encode(OpusEncoder *st, const opus_int16 *pcm, int frame_size, - unsigned char *data, opus_int32 max_data_bytes) -{ - int i, ret; - VARDECL(float, in); - ALLOC_STACK; - - ALLOC(in, frame_size*st->channels, float); - - for (i=0;ichannels;i++) - in[i] = (1.0f/32768)*pcm[i]; - ret = opus_encode_float(st, in, frame_size, data, max_data_bytes); - RESTORE_STACK; - return ret; -} -#endif - - -int opus_encoder_ctl(OpusEncoder *st, int request, ...) -{ - int ret; - CELTEncoder *celt_enc; - va_list ap; - - ret = OPUS_OK; - va_start(ap, request); - - celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset); - - switch (request) - { - case OPUS_SET_APPLICATION_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if ( (value != OPUS_APPLICATION_VOIP && value != OPUS_APPLICATION_AUDIO - && value != OPUS_APPLICATION_RESTRICTED_LOWDELAY) - || (!st->first && st->application != value)) - { - ret = OPUS_BAD_ARG; - break; - } - st->application = value; - } - break; - case OPUS_GET_APPLICATION_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - *value = st->application; - } - break; - case OPUS_SET_BITRATE_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if (value != OPUS_AUTO && value != OPUS_BITRATE_MAX) - { - if (value <= 0) - goto bad_arg; - else if (value <= 500) - value = 500; - else if (value > (opus_int32)300000*st->channels) - value = (opus_int32)300000*st->channels; - } - st->user_bitrate_bps = value; - } - break; - case OPUS_GET_BITRATE_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - *value = user_bitrate_to_bitrate(st, st->prev_framesize, 1276); - } - break; - case OPUS_SET_FORCE_CHANNELS_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if((value<1 || value>st->channels) && value != OPUS_AUTO) - return OPUS_BAD_ARG; - st->force_channels = value; - } - break; - case OPUS_GET_FORCE_CHANNELS_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - *value = st->force_channels; - } - break; - case OPUS_SET_MAX_BANDWIDTH_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if (value < OPUS_BANDWIDTH_NARROWBAND || value > OPUS_BANDWIDTH_FULLBAND) - return OPUS_BAD_ARG; - st->max_bandwidth = value; - if (st->max_bandwidth == OPUS_BANDWIDTH_NARROWBAND) { - st->silk_mode.maxInternalSampleRate = 8000; - } else if (st->max_bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) { - st->silk_mode.maxInternalSampleRate = 12000; - } else { - st->silk_mode.maxInternalSampleRate = 16000; - } - } - break; - case OPUS_GET_MAX_BANDWIDTH_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - *value = st->max_bandwidth; - } - break; - case OPUS_SET_BANDWIDTH_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if ((value < OPUS_BANDWIDTH_NARROWBAND || value > OPUS_BANDWIDTH_FULLBAND) && value != OPUS_AUTO) - return OPUS_BAD_ARG; - st->user_bandwidth = value; - if (st->user_bandwidth == OPUS_BANDWIDTH_NARROWBAND) { - st->silk_mode.maxInternalSampleRate = 8000; - } else if (st->user_bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) { - st->silk_mode.maxInternalSampleRate = 12000; - } else { - st->silk_mode.maxInternalSampleRate = 16000; - } - } - break; - case OPUS_GET_BANDWIDTH_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - *value = st->bandwidth; - } - break; - case OPUS_SET_DTX_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if(value<0 || value>1) - return OPUS_BAD_ARG; - st->silk_mode.useDTX = value; - } - break; - case OPUS_GET_DTX_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - *value = st->silk_mode.useDTX; - } - break; - case OPUS_SET_COMPLEXITY_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if(value<0 || value>10) - return OPUS_BAD_ARG; - st->silk_mode.complexity = value; - celt_encoder_ctl(celt_enc, OPUS_SET_COMPLEXITY(value)); - } - break; - case OPUS_GET_COMPLEXITY_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - *value = st->silk_mode.complexity; - } - break; - case OPUS_SET_INBAND_FEC_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if(value<0 || value>1) - return OPUS_BAD_ARG; - st->silk_mode.useInBandFEC = value; - } - break; - case OPUS_GET_INBAND_FEC_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - *value = st->silk_mode.useInBandFEC; - } - break; - case OPUS_SET_PACKET_LOSS_PERC_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if (value < 0 || value > 100) - return OPUS_BAD_ARG; - st->silk_mode.packetLossPercentage = value; - celt_encoder_ctl(celt_enc, OPUS_SET_PACKET_LOSS_PERC(value)); - } - break; - case OPUS_GET_PACKET_LOSS_PERC_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - *value = st->silk_mode.packetLossPercentage; - } - break; - case OPUS_SET_VBR_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if(value<0 || value>1) - return OPUS_BAD_ARG; - st->use_vbr = value; - st->silk_mode.useCBR = 1-value; - } - break; - case OPUS_GET_VBR_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - *value = st->use_vbr; - } - break; - case OPUS_SET_VOICE_RATIO_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if (value>100 || value<-1) - goto bad_arg; - st->voice_ratio = value; - } - break; - case OPUS_GET_VOICE_RATIO_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - *value = st->voice_ratio; - } - break; - case OPUS_SET_VBR_CONSTRAINT_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if(value<0 || value>1) - return OPUS_BAD_ARG; - st->vbr_constraint = value; - } - break; - case OPUS_GET_VBR_CONSTRAINT_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - *value = st->vbr_constraint; - } - break; - case OPUS_SET_SIGNAL_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if(value!=OPUS_AUTO && value!=OPUS_SIGNAL_VOICE && value!=OPUS_SIGNAL_MUSIC) - return OPUS_BAD_ARG; - st->signal_type = value; - } - break; - case OPUS_GET_SIGNAL_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - *value = st->signal_type; - } - break; - case OPUS_GET_LOOKAHEAD_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - *value = st->Fs/400; - if (st->application != OPUS_APPLICATION_RESTRICTED_LOWDELAY) - *value += st->delay_compensation; - } - break; - case OPUS_GET_SAMPLE_RATE_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - if (value==NULL) - { - ret = OPUS_BAD_ARG; - break; - } - *value = st->Fs; - } - break; - case OPUS_GET_FINAL_RANGE_REQUEST: - { - opus_uint32 *value = va_arg(ap, opus_uint32*); - *value = st->rangeFinal; - } - break; - case OPUS_SET_LSB_DEPTH_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - ret = celt_encoder_ctl(celt_enc, OPUS_SET_LSB_DEPTH(value)); - } - break; - case OPUS_GET_LSB_DEPTH_REQUEST: - { - opus_int32 *value = va_arg(ap, opus_int32*); - celt_encoder_ctl(celt_enc, OPUS_GET_LSB_DEPTH(value)); - } - break; - case OPUS_RESET_STATE: - { - void *silk_enc; - silk_EncControlStruct dummy; - silk_enc = (char*)st+st->silk_enc_offset; - - OPUS_CLEAR((char*)&st->OPUS_ENCODER_RESET_START, - sizeof(OpusEncoder)- - ((char*)&st->OPUS_ENCODER_RESET_START - (char*)st)); - - celt_encoder_ctl(celt_enc, OPUS_RESET_STATE); - silk_InitEncoder( silk_enc, &dummy ); - st->stream_channels = st->channels; - st->hybrid_stereo_width_Q14 = 1 << 14; - st->first = 1; - st->mode = MODE_HYBRID; - st->bandwidth = OPUS_BANDWIDTH_FULLBAND; - st->variable_HP_smth2_Q15 = silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 ); - } - break; - case OPUS_SET_FORCE_MODE_REQUEST: - { - opus_int32 value = va_arg(ap, opus_int32); - if ((value < MODE_SILK_ONLY || value > MODE_CELT_ONLY) && value != OPUS_AUTO) - goto bad_arg; - st->user_forced_mode = value; - } - break; - default: - /* fprintf(stderr, "unknown opus_encoder_ctl() request: %d", request);*/ - ret = OPUS_UNIMPLEMENTED; - break; - } - va_end(ap); - return ret; -bad_arg: - va_end(ap); - return OPUS_BAD_ARG; -} - -void opus_encoder_destroy(OpusEncoder *st) -{ - opus_free(st); -} diff --git a/src/opus-1.0.2/src/opus_multistream.c b/src/opus-1.0.2/src/opus_multistream.c deleted file mode 100644 index a7f25a52..00000000 --- a/src/opus-1.0.2/src/opus_multistream.c +++ /dev/null @@ -1,1027 +0,0 @@ -/* Copyright (c) 2011 Xiph.Org Foundation - Written by Jean-Marc Valin */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "opus_multistream.h" -#include "opus.h" -#include "opus_private.h" -#include "stack_alloc.h" -#include -#include "float_cast.h" -#include "os_support.h" - -typedef struct ChannelLayout { - int nb_channels; - int nb_streams; - int nb_coupled_streams; - unsigned char mapping[256]; -} ChannelLayout; - -struct OpusMSEncoder { - ChannelLayout layout; - int bitrate; - /* Encoder states go here */ -}; - -struct OpusMSDecoder { - ChannelLayout layout; - /* Decoder states go here */ -}; - -#ifdef FIXED_POINT -#define opus_encode_native opus_encode -#else -#define opus_encode_native opus_encode_float -#endif - -static int validate_layout(const ChannelLayout *layout) -{ - int i, max_channel; - - max_channel = layout->nb_streams+layout->nb_coupled_streams; - if (max_channel>255) - return 0; - for (i=0;inb_channels;i++) - { - if (layout->mapping[i] >= max_channel && layout->mapping[i] != 255) - return 0; - } - return 1; -} - - -static int get_left_channel(const ChannelLayout *layout, int stream_id, int prev) -{ - int i; - i = (prev<0) ? 0 : prev+1; - for (;inb_channels;i++) - { - if (layout->mapping[i]==stream_id*2) - return i; - } - return -1; -} - -static int get_right_channel(const ChannelLayout *layout, int stream_id, int prev) -{ - int i; - i = (prev<0) ? 0 : prev+1; - for (;inb_channels;i++) - { - if (layout->mapping[i]==stream_id*2+1) - return i; - } - return -1; -} - -static int get_mono_channel(const ChannelLayout *layout, int stream_id, int prev) -{ - int i; - i = (prev<0) ? 0 : prev+1; - for (;inb_channels;i++) - { - if (layout->mapping[i]==stream_id+layout->nb_coupled_streams) - return i; - } - return -1; -} - -static int validate_encoder_layout(const ChannelLayout *layout) -{ - int s; - for (s=0;snb_streams;s++) - { - if (s < layout->nb_coupled_streams) - { - if (get_left_channel(layout, s, -1)==-1) - return 0; - if (get_right_channel(layout, s, -1)==-1) - return 0; - } else { - if (get_mono_channel(layout, s, -1)==-1) - return 0; - } - } - return 1; -} - -opus_int32 opus_multistream_encoder_get_size(int nb_streams, int nb_coupled_streams) -{ - int coupled_size; - int mono_size; - - if(nb_streams<1||nb_coupled_streams>nb_streams||nb_coupled_streams<0)return 0; - coupled_size = opus_encoder_get_size(2); - mono_size = opus_encoder_get_size(1); - return align(sizeof(OpusMSEncoder)) - + nb_coupled_streams * align(coupled_size) - + (nb_streams-nb_coupled_streams) * align(mono_size); -} - - - -int opus_multistream_encoder_init( - OpusMSEncoder *st, - opus_int32 Fs, - int channels, - int streams, - int coupled_streams, - const unsigned char *mapping, - int application -) -{ - int coupled_size; - int mono_size; - int i, ret; - char *ptr; - - if ((channels>255) || (channels<1) || (coupled_streams>streams) || - (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0)) - return OPUS_BAD_ARG; - - st->layout.nb_channels = channels; - st->layout.nb_streams = streams; - st->layout.nb_coupled_streams = coupled_streams; - - for (i=0;ilayout.nb_channels;i++) - st->layout.mapping[i] = mapping[i]; - if (!validate_layout(&st->layout) || !validate_encoder_layout(&st->layout)) - return OPUS_BAD_ARG; - ptr = (char*)st + align(sizeof(OpusMSEncoder)); - coupled_size = opus_encoder_get_size(2); - mono_size = opus_encoder_get_size(1); - - for (i=0;ilayout.nb_coupled_streams;i++) - { - ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 2, application); - if(ret!=OPUS_OK)return ret; - ptr += align(coupled_size); - } - for (;ilayout.nb_streams;i++) - { - ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 1, application); - if(ret!=OPUS_OK)return ret; - ptr += align(mono_size); - } - return OPUS_OK; -} - -OpusMSEncoder *opus_multistream_encoder_create( - opus_int32 Fs, - int channels, - int streams, - int coupled_streams, - const unsigned char *mapping, - int application, - int *error -) -{ - int ret; - OpusMSEncoder *st; - if ((channels>255) || (channels<1) || (coupled_streams>streams) || - (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0)) - { - if (error) - *error = OPUS_BAD_ARG; - return NULL; - } - st = (OpusMSEncoder *)opus_alloc(opus_multistream_encoder_get_size(streams, coupled_streams)); - if (st==NULL) - { - if (error) - *error = OPUS_ALLOC_FAIL; - return NULL; - } - ret = opus_multistream_encoder_init(st, Fs, channels, streams, coupled_streams, mapping, application); - if (ret != OPUS_OK) - { - opus_free(st); - st = NULL; - } - if (error) - *error = ret; - return st; -} - -typedef void (*opus_copy_channel_in_func)( - opus_val16 *dst, - int dst_stride, - const void *src, - int src_stride, - int src_channel, - int frame_size -); - -/* Max size in case the encoder decides to return three frames */ -#define MS_FRAME_TMP (3*1275+7) -static int opus_multistream_encode_native -( - OpusMSEncoder *st, - opus_copy_channel_in_func copy_channel_in, - const void *pcm, - int frame_size, - unsigned char *data, - opus_int32 max_data_bytes -) -{ - opus_int32 Fs; - int coupled_size; - int mono_size; - int s; - char *ptr; - int tot_size; - VARDECL(opus_val16, buf); - unsigned char tmp_data[MS_FRAME_TMP]; - OpusRepacketizer rp; - ALLOC_STACK; - - ptr = (char*)st + align(sizeof(OpusMSEncoder)); - opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs)); - /* Validate frame_size before using it to allocate stack space. - This mirrors the checks in opus_encode[_float](). */ - if (400*frame_size != Fs && 200*frame_size != Fs && - 100*frame_size != Fs && 50*frame_size != Fs && - 25*frame_size != Fs && 50*frame_size != 3*Fs) - { - RESTORE_STACK; - return OPUS_BAD_ARG; - } - ALLOC(buf, 2*frame_size, opus_val16); - coupled_size = opus_encoder_get_size(2); - mono_size = opus_encoder_get_size(1); - - if (max_data_bytes < 4*st->layout.nb_streams-1) - { - RESTORE_STACK; - return OPUS_BUFFER_TOO_SMALL; - } - /* Counting ToC */ - tot_size = 0; - for (s=0;slayout.nb_streams;s++) - { - OpusEncoder *enc; - int len; - int curr_max; - - opus_repacketizer_init(&rp); - enc = (OpusEncoder*)ptr; - if (s < st->layout.nb_coupled_streams) - { - int left, right; - left = get_left_channel(&st->layout, s, -1); - right = get_right_channel(&st->layout, s, -1); - (*copy_channel_in)(buf, 2, - pcm, st->layout.nb_channels, left, frame_size); - (*copy_channel_in)(buf+1, 2, - pcm, st->layout.nb_channels, right, frame_size); - ptr += align(coupled_size); - } else { - int chan = get_mono_channel(&st->layout, s, -1); - (*copy_channel_in)(buf, 1, - pcm, st->layout.nb_channels, chan, frame_size); - ptr += align(mono_size); - } - /* number of bytes left (+Toc) */ - curr_max = max_data_bytes - tot_size; - /* Reserve three bytes for the last stream and four for the others */ - curr_max -= IMAX(0,4*(st->layout.nb_streams-s-1)-1); - curr_max = IMIN(curr_max,MS_FRAME_TMP); - len = opus_encode_native(enc, buf, frame_size, tmp_data, curr_max); - if (len<0) - { - RESTORE_STACK; - return len; - } - /* We need to use the repacketizer to add the self-delimiting lengths - while taking into account the fact that the encoder can now return - more than one frame at a time (e.g. 60 ms CELT-only) */ - opus_repacketizer_cat(&rp, tmp_data, len); - len = opus_repacketizer_out_range_impl(&rp, 0, opus_repacketizer_get_nb_frames(&rp), data, max_data_bytes-tot_size, s != st->layout.nb_streams-1); - data += len; - tot_size += len; - } - RESTORE_STACK; - return tot_size; - -} - -#if !defined(DISABLE_FLOAT_API) -static void opus_copy_channel_in_float( - opus_val16 *dst, - int dst_stride, - const void *src, - int src_stride, - int src_channel, - int frame_size -) -{ - const float *float_src; - int i; - float_src = (const float *)src; - for (i=0;ilayout.nb_streams + st->layout.nb_coupled_streams; - value /= chan; - for (s=0;slayout.nb_streams;s++) - { - OpusEncoder *enc; - enc = (OpusEncoder*)ptr; - if (s < st->layout.nb_coupled_streams) - ptr += align(coupled_size); - else - ptr += align(mono_size); - opus_encoder_ctl(enc, request, value * (s < st->layout.nb_coupled_streams ? 2 : 1)); - } - } - break; - case OPUS_GET_BITRATE_REQUEST: - { - int s; - opus_int32 *value = va_arg(ap, opus_int32*); - *value = 0; - for (s=0;slayout.nb_streams;s++) - { - opus_int32 rate; - OpusEncoder *enc; - enc = (OpusEncoder*)ptr; - if (s < st->layout.nb_coupled_streams) - ptr += align(coupled_size); - else - ptr += align(mono_size); - opus_encoder_ctl(enc, request, &rate); - *value += rate; - } - } - break; - case OPUS_GET_LSB_DEPTH_REQUEST: - case OPUS_GET_VBR_REQUEST: - case OPUS_GET_APPLICATION_REQUEST: - case OPUS_GET_BANDWIDTH_REQUEST: - case OPUS_GET_COMPLEXITY_REQUEST: - case OPUS_GET_PACKET_LOSS_PERC_REQUEST: - case OPUS_GET_DTX_REQUEST: - case OPUS_GET_VOICE_RATIO_REQUEST: - case OPUS_GET_VBR_CONSTRAINT_REQUEST: - case OPUS_GET_SIGNAL_REQUEST: - case OPUS_GET_LOOKAHEAD_REQUEST: - case OPUS_GET_SAMPLE_RATE_REQUEST: - case OPUS_GET_INBAND_FEC_REQUEST: - { - OpusEncoder *enc; - /* For int32* GET params, just query the first stream */ - opus_int32 *value = va_arg(ap, opus_int32*); - enc = (OpusEncoder*)ptr; - ret = opus_encoder_ctl(enc, request, value); - } - break; - case OPUS_GET_FINAL_RANGE_REQUEST: - { - int s; - opus_uint32 *value = va_arg(ap, opus_uint32*); - opus_uint32 tmp; - *value=0; - for (s=0;slayout.nb_streams;s++) - { - OpusEncoder *enc; - enc = (OpusEncoder*)ptr; - if (s < st->layout.nb_coupled_streams) - ptr += align(coupled_size); - else - ptr += align(mono_size); - ret = opus_encoder_ctl(enc, request, &tmp); - if (ret != OPUS_OK) break; - *value ^= tmp; - } - } - break; - case OPUS_SET_LSB_DEPTH_REQUEST: - case OPUS_SET_COMPLEXITY_REQUEST: - case OPUS_SET_VBR_REQUEST: - case OPUS_SET_VBR_CONSTRAINT_REQUEST: - case OPUS_SET_BANDWIDTH_REQUEST: - case OPUS_SET_SIGNAL_REQUEST: - case OPUS_SET_APPLICATION_REQUEST: - case OPUS_SET_INBAND_FEC_REQUEST: - case OPUS_SET_PACKET_LOSS_PERC_REQUEST: - case OPUS_SET_DTX_REQUEST: - case OPUS_SET_FORCE_MODE_REQUEST: - { - int s; - /* This works for int32 params */ - opus_int32 value = va_arg(ap, opus_int32); - for (s=0;slayout.nb_streams;s++) - { - OpusEncoder *enc; - - enc = (OpusEncoder*)ptr; - if (s < st->layout.nb_coupled_streams) - ptr += align(coupled_size); - else - ptr += align(mono_size); - ret = opus_encoder_ctl(enc, request, value); - if (ret != OPUS_OK) - break; - } - } - break; - case OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST: - { - int s; - opus_int32 stream_id; - OpusEncoder **value; - stream_id = va_arg(ap, opus_int32); - if (stream_id<0 || stream_id >= st->layout.nb_streams) - ret = OPUS_BAD_ARG; - value = va_arg(ap, OpusEncoder**); - for (s=0;slayout.nb_coupled_streams) - ptr += align(coupled_size); - else - ptr += align(mono_size); - } - *value = (OpusEncoder*)ptr; - } - break; - default: - ret = OPUS_UNIMPLEMENTED; - break; - } - - va_end(ap); - return ret; -} - -void opus_multistream_encoder_destroy(OpusMSEncoder *st) -{ - opus_free(st); -} - - -/* DECODER */ - -opus_int32 opus_multistream_decoder_get_size(int nb_streams, int nb_coupled_streams) -{ - int coupled_size; - int mono_size; - - if(nb_streams<1||nb_coupled_streams>nb_streams||nb_coupled_streams<0)return 0; - coupled_size = opus_decoder_get_size(2); - mono_size = opus_decoder_get_size(1); - return align(sizeof(OpusMSDecoder)) - + nb_coupled_streams * align(coupled_size) - + (nb_streams-nb_coupled_streams) * align(mono_size); -} - -int opus_multistream_decoder_init( - OpusMSDecoder *st, - opus_int32 Fs, - int channels, - int streams, - int coupled_streams, - const unsigned char *mapping -) -{ - int coupled_size; - int mono_size; - int i, ret; - char *ptr; - - if ((channels>255) || (channels<1) || (coupled_streams>streams) || - (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0)) - return OPUS_BAD_ARG; - - st->layout.nb_channels = channels; - st->layout.nb_streams = streams; - st->layout.nb_coupled_streams = coupled_streams; - - for (i=0;ilayout.nb_channels;i++) - st->layout.mapping[i] = mapping[i]; - if (!validate_layout(&st->layout)) - return OPUS_BAD_ARG; - - ptr = (char*)st + align(sizeof(OpusMSDecoder)); - coupled_size = opus_decoder_get_size(2); - mono_size = opus_decoder_get_size(1); - - for (i=0;ilayout.nb_coupled_streams;i++) - { - ret=opus_decoder_init((OpusDecoder*)ptr, Fs, 2); - if(ret!=OPUS_OK)return ret; - ptr += align(coupled_size); - } - for (;ilayout.nb_streams;i++) - { - ret=opus_decoder_init((OpusDecoder*)ptr, Fs, 1); - if(ret!=OPUS_OK)return ret; - ptr += align(mono_size); - } - return OPUS_OK; -} - - -OpusMSDecoder *opus_multistream_decoder_create( - opus_int32 Fs, - int channels, - int streams, - int coupled_streams, - const unsigned char *mapping, - int *error -) -{ - int ret; - OpusMSDecoder *st; - if ((channels>255) || (channels<1) || (coupled_streams>streams) || - (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0)) - { - if (error) - *error = OPUS_BAD_ARG; - return NULL; - } - st = (OpusMSDecoder *)opus_alloc(opus_multistream_decoder_get_size(streams, coupled_streams)); - if (st==NULL) - { - if (error) - *error = OPUS_ALLOC_FAIL; - return NULL; - } - ret = opus_multistream_decoder_init(st, Fs, channels, streams, coupled_streams, mapping); - if (error) - *error = ret; - if (ret != OPUS_OK) - { - opus_free(st); - st = NULL; - } - return st; -} - -typedef void (*opus_copy_channel_out_func)( - void *dst, - int dst_stride, - int dst_channel, - const opus_val16 *src, - int src_stride, - int frame_size -); - -static int opus_multistream_decode_native( - OpusMSDecoder *st, - const unsigned char *data, - opus_int32 len, - void *pcm, - opus_copy_channel_out_func copy_channel_out, - int frame_size, - int decode_fec -) -{ - opus_int32 Fs; - int coupled_size; - int mono_size; - int s, c; - char *ptr; - int do_plc=0; - VARDECL(opus_val16, buf); - ALLOC_STACK; - - /* Limit frame_size to avoid excessive stack allocations. */ - opus_multistream_decoder_ctl(st, OPUS_GET_SAMPLE_RATE(&Fs)); - frame_size = IMIN(frame_size, Fs/25*3); - ALLOC(buf, 2*frame_size, opus_val16); - ptr = (char*)st + align(sizeof(OpusMSDecoder)); - coupled_size = opus_decoder_get_size(2); - mono_size = opus_decoder_get_size(1); - - if (len==0) - do_plc = 1; - if (len < 0) - return OPUS_BAD_ARG; - if (!do_plc && len < 2*st->layout.nb_streams-1) - return OPUS_INVALID_PACKET; - for (s=0;slayout.nb_streams;s++) - { - OpusDecoder *dec; - int packet_offset, ret; - - dec = (OpusDecoder*)ptr; - ptr += (s < st->layout.nb_coupled_streams) ? align(coupled_size) : align(mono_size); - - if (!do_plc && len<=0) - { - RESTORE_STACK; - return OPUS_INVALID_PACKET; - } - packet_offset = 0; - ret = opus_decode_native(dec, data, len, buf, frame_size, decode_fec, s!=st->layout.nb_streams-1, &packet_offset); - data += packet_offset; - len -= packet_offset; - if (ret > frame_size) - { - RESTORE_STACK; - return OPUS_BUFFER_TOO_SMALL; - } - if (s>0 && ret != frame_size) - { - RESTORE_STACK; - return OPUS_INVALID_PACKET; - } - if (ret <= 0) - { - RESTORE_STACK; - return ret; - } - frame_size = ret; - if (s < st->layout.nb_coupled_streams) - { - int chan, prev; - prev = -1; - /* Copy "left" audio to the channel(s) where it belongs */ - while ( (chan = get_left_channel(&st->layout, s, prev)) != -1) - { - (*copy_channel_out)(pcm, st->layout.nb_channels, chan, - buf, 2, frame_size); - prev = chan; - } - prev = -1; - /* Copy "right" audio to the channel(s) where it belongs */ - while ( (chan = get_right_channel(&st->layout, s, prev)) != -1) - { - (*copy_channel_out)(pcm, st->layout.nb_channels, chan, - buf+1, 2, frame_size); - prev = chan; - } - } else { - int chan, prev; - prev = -1; - /* Copy audio to the channel(s) where it belongs */ - while ( (chan = get_mono_channel(&st->layout, s, prev)) != -1) - { - (*copy_channel_out)(pcm, st->layout.nb_channels, chan, - buf, 1, frame_size); - prev = chan; - } - } - } - /* Handle muted channels */ - for (c=0;clayout.nb_channels;c++) - { - if (st->layout.mapping[c] == 255) - { - (*copy_channel_out)(pcm, st->layout.nb_channels, c, - NULL, 0, frame_size); - } - } - RESTORE_STACK; - return frame_size; -} - -#if !defined(DISABLE_FLOAT_API) -static void opus_copy_channel_out_float( - void *dst, - int dst_stride, - int dst_channel, - const opus_val16 *src, - int src_stride, - int frame_size -) -{ - float *float_dst; - int i; - float_dst = (float*)dst; - if (src != NULL) - { - for (i=0;ilayout.nb_streams;s++) - { - OpusDecoder *dec; - dec = (OpusDecoder*)ptr; - if (s < st->layout.nb_coupled_streams) - ptr += align(coupled_size); - else - ptr += align(mono_size); - ret = opus_decoder_ctl(dec, request, &tmp); - if (ret != OPUS_OK) break; - *value ^= tmp; - } - } - break; - case OPUS_RESET_STATE: - { - int s; - for (s=0;slayout.nb_streams;s++) - { - OpusDecoder *dec; - - dec = (OpusDecoder*)ptr; - if (s < st->layout.nb_coupled_streams) - ptr += align(coupled_size); - else - ptr += align(mono_size); - ret = opus_decoder_ctl(dec, OPUS_RESET_STATE); - if (ret != OPUS_OK) - break; - } - } - break; - case OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST: - { - int s; - opus_int32 stream_id; - OpusDecoder **value; - stream_id = va_arg(ap, opus_int32); - if (stream_id<0 || stream_id >= st->layout.nb_streams) - ret = OPUS_BAD_ARG; - value = va_arg(ap, OpusDecoder**); - for (s=0;slayout.nb_coupled_streams) - ptr += align(coupled_size); - else - ptr += align(mono_size); - } - *value = (OpusDecoder*)ptr; - } - break; - case OPUS_SET_GAIN_REQUEST: - { - int s; - /* This works for int32 params */ - opus_int32 value = va_arg(ap, opus_int32); - for (s=0;slayout.nb_streams;s++) - { - OpusDecoder *dec; - - dec = (OpusDecoder*)ptr; - if (s < st->layout.nb_coupled_streams) - ptr += align(coupled_size); - else - ptr += align(mono_size); - ret = opus_decoder_ctl(dec, request, value); - if (ret != OPUS_OK) - break; - } - } - break; - default: - ret = OPUS_UNIMPLEMENTED; - break; - } - - va_end(ap); - return ret; -} - - -void opus_multistream_decoder_destroy(OpusMSDecoder *st) -{ - opus_free(st); -} diff --git a/src/opus-1.0.2/src/opus_private.h b/src/opus-1.0.2/src/opus_private.h deleted file mode 100644 index 52482bc1..00000000 --- a/src/opus-1.0.2/src/opus_private.h +++ /dev/null @@ -1,85 +0,0 @@ -/* Copyright (c) 2012 Xiph.Org Foundation - Written by Jean-Marc Valin */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - - -#ifndef OPUS_PRIVATE_H -#define OPUS_PRIVATE_H - -#include "arch.h" -#include "opus.h" - -struct OpusRepacketizer { - unsigned char toc; - int nb_frames; - const unsigned char *frames[48]; - short len[48]; - int framesize; -}; - - -#define MODE_SILK_ONLY 1000 -#define MODE_HYBRID 1001 -#define MODE_CELT_ONLY 1002 - -#define OPUS_SET_VOICE_RATIO_REQUEST 11018 -#define OPUS_GET_VOICE_RATIO_REQUEST 11019 - -/** Configures the encoder's expected percentage of voice - * opposed to music or other signals. - * - * @note This interface is currently more aspiration than actuality. It's - * ultimately expected to bias an automatic signal classifier, but it currently - * just shifts the static bitrate to mode mapping around a little bit. - * - * @param[in] x int: Voice percentage in the range 0-100, inclusive. - * @hideinitializer */ -#define OPUS_SET_VOICE_RATIO(x) OPUS_SET_VOICE_RATIO_REQUEST, __opus_check_int(x) -/** Gets the encoder's configured voice ratio value, @see OPUS_SET_VOICE_RATIO - * - * @param[out] x int*: Voice percentage in the range 0-100, inclusive. - * @hideinitializer */ -#define OPUS_GET_VOICE_RATIO(x) OPUS_GET_VOICE_RATIO_REQUEST, __opus_check_int_ptr(x) - - -#define OPUS_SET_FORCE_MODE_REQUEST 11002 -#define OPUS_SET_FORCE_MODE(x) OPUS_SET_FORCE_MODE_REQUEST, __opus_check_int(x) - - -int encode_size(int size, unsigned char *data); - -int opus_decode_native(OpusDecoder *st, const unsigned char *data, opus_int32 len, - opus_val16 *pcm, int frame_size, int decode_fec, int self_delimited, int *packet_offset); - -/* Make sure everything's aligned to sizeof(void *) bytes */ -static inline int align(int i) -{ - return (i+sizeof(void *)-1)&-((int)sizeof(void *)); -} - -opus_int32 opus_repacketizer_out_range_impl(OpusRepacketizer *rp, int begin, int end, unsigned char *data, opus_int32 maxlen, int self_delimited); - -#endif /* OPUS_PRIVATE_H */ diff --git a/src/opus-1.0.2/src/repacketizer.c b/src/opus-1.0.2/src/repacketizer.c deleted file mode 100644 index 26315b62..00000000 --- a/src/opus-1.0.2/src/repacketizer.c +++ /dev/null @@ -1,208 +0,0 @@ -/* Copyright (c) 2011 Xiph.Org Foundation - Written by Jean-Marc Valin */ -/* - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - - Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER - OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "opus.h" -#include "opus_private.h" -#include "os_support.h" - - -int opus_repacketizer_get_size(void) -{ - return sizeof(OpusRepacketizer); -} - -OpusRepacketizer *opus_repacketizer_init(OpusRepacketizer *rp) -{ - rp->nb_frames = 0; - return rp; -} - -OpusRepacketizer *opus_repacketizer_create(void) -{ - OpusRepacketizer *rp; - rp=(OpusRepacketizer *)opus_alloc(opus_repacketizer_get_size()); - if(rp==NULL)return NULL; - return opus_repacketizer_init(rp); -} - -void opus_repacketizer_destroy(OpusRepacketizer *rp) -{ - opus_free(rp); -} - -int opus_repacketizer_cat(OpusRepacketizer *rp, const unsigned char *data, opus_int32 len) -{ - unsigned char tmp_toc; - int curr_nb_frames,ret; - /* Set of check ToC */ - if (len<1) return OPUS_INVALID_PACKET; - if (rp->nb_frames == 0) - { - rp->toc = data[0]; - rp->framesize = opus_packet_get_samples_per_frame(data, 8000); - } else if ((rp->toc&0xFC) != (data[0]&0xFC)) - { - /*fprintf(stderr, "toc mismatch: 0x%x vs 0x%x\n", rp->toc, data[0]);*/ - return OPUS_INVALID_PACKET; - } - curr_nb_frames = opus_packet_get_nb_frames(data, len); - if(curr_nb_frames<1) return OPUS_INVALID_PACKET; - - /* Check the 120 ms maximum packet size */ - if ((curr_nb_frames+rp->nb_frames)*rp->framesize > 960) - { - return OPUS_INVALID_PACKET; - } - - ret=opus_packet_parse(data, len, &tmp_toc, &rp->frames[rp->nb_frames], &rp->len[rp->nb_frames], NULL); - if(ret<1)return ret; - - rp->nb_frames += curr_nb_frames; - return OPUS_OK; -} - -int opus_repacketizer_get_nb_frames(OpusRepacketizer *rp) -{ - return rp->nb_frames; -} - -opus_int32 opus_repacketizer_out_range_impl(OpusRepacketizer *rp, int begin, int end, unsigned char *data, opus_int32 maxlen, int self_delimited) -{ - int i, count; - opus_int32 tot_size; - short *len; - const unsigned char **frames; - - if (begin<0 || begin>=end || end>rp->nb_frames) - { - /*fprintf(stderr, "%d %d %d\n", begin, end, rp->nb_frames);*/ - return OPUS_BAD_ARG; - } - count = end-begin; - - len = rp->len+begin; - frames = rp->frames+begin; - if (self_delimited) - tot_size = 1 + (len[count-1]>=252); - else - tot_size = 0; - - switch (count) - { - case 1: - { - /* Code 0 */ - tot_size += len[0]+1; - if (tot_size > maxlen) - return OPUS_BUFFER_TOO_SMALL; - *data++ = rp->toc&0xFC; - } - break; - case 2: - { - if (len[1] == len[0]) - { - /* Code 1 */ - tot_size += 2*len[0]+1; - if (tot_size > maxlen) - return OPUS_BUFFER_TOO_SMALL; - *data++ = (rp->toc&0xFC) | 0x1; - } else { - /* Code 2 */ - tot_size += len[0]+len[1]+2+(len[0]>=252); - if (tot_size > maxlen) - return OPUS_BUFFER_TOO_SMALL; - *data++ = (rp->toc&0xFC) | 0x2; - data += encode_size(len[0], data); - } - } - break; - default: - { - /* Code 3 */ - int vbr; - - vbr = 0; - for (i=1;i=252) + len[i]; - tot_size += len[count-1]; - - if (tot_size > maxlen) - return OPUS_BUFFER_TOO_SMALL; - *data++ = (rp->toc&0xFC) | 0x3; - *data++ = count | 0x80; - for (i=0;i maxlen) - return OPUS_BUFFER_TOO_SMALL; - *data++ = (rp->toc&0xFC) | 0x3; - *data++ = count; - } - } - break; - } - if (self_delimited) { - int sdlen = encode_size(len[count-1], data); - data += sdlen; - } - /* Copy the actual data */ - for (i=0;inb_frames, data, maxlen, 0); -} - - diff --git a/src/opus-1.1/celt/_kiss_fft_guts.h b/src/opus-1.1/celt/_kiss_fft_guts.h new file mode 100644 index 00000000..aefe490e --- /dev/null +++ b/src/opus-1.1/celt/_kiss_fft_guts.h @@ -0,0 +1,183 @@ +/*Copyright (c) 2003-2004, Mark Borgerding + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.*/ + +#ifndef KISS_FFT_GUTS_H +#define KISS_FFT_GUTS_H + +#define MIN(a,b) ((a)<(b) ? (a):(b)) +#define MAX(a,b) ((a)>(b) ? (a):(b)) + +/* kiss_fft.h + defines kiss_fft_scalar as either short or a float type + and defines + typedef struct { kiss_fft_scalar r; kiss_fft_scalar i; }kiss_fft_cpx; */ +#include "kiss_fft.h" + +/* + Explanation of macros dealing with complex math: + + C_MUL(m,a,b) : m = a*b + C_FIXDIV( c , div ) : if a fixed point impl., c /= div. noop otherwise + C_SUB( res, a,b) : res = a - b + C_SUBFROM( res , a) : res -= a + C_ADDTO( res , a) : res += a + * */ +#ifdef FIXED_POINT +#include "arch.h" + + +#define SAMP_MAX 2147483647 +#define TWID_MAX 32767 +#define TRIG_UPSCALE 1 + +#define SAMP_MIN -SAMP_MAX + + +# define S_MUL(a,b) MULT16_32_Q15(b, a) + +# define C_MUL(m,a,b) \ + do{ (m).r = SUB32(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)); \ + (m).i = ADD32(S_MUL((a).r,(b).i) , S_MUL((a).i,(b).r)); }while(0) + +# define C_MULC(m,a,b) \ + do{ (m).r = ADD32(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)); \ + (m).i = SUB32(S_MUL((a).i,(b).r) , S_MUL((a).r,(b).i)); }while(0) + +# define C_MUL4(m,a,b) \ + do{ (m).r = SHR32(SUB32(S_MUL((a).r,(b).r) , S_MUL((a).i,(b).i)),2); \ + (m).i = SHR32(ADD32(S_MUL((a).r,(b).i) , S_MUL((a).i,(b).r)),2); }while(0) + +# define C_MULBYSCALAR( c, s ) \ + do{ (c).r = S_MUL( (c).r , s ) ;\ + (c).i = S_MUL( (c).i , s ) ; }while(0) + +# define DIVSCALAR(x,k) \ + (x) = S_MUL( x, (TWID_MAX-((k)>>1))/(k)+1 ) + +# define C_FIXDIV(c,div) \ + do { DIVSCALAR( (c).r , div); \ + DIVSCALAR( (c).i , div); }while (0) + +#define C_ADD( res, a,b)\ + do {(res).r=ADD32((a).r,(b).r); (res).i=ADD32((a).i,(b).i); \ + }while(0) +#define C_SUB( res, a,b)\ + do {(res).r=SUB32((a).r,(b).r); (res).i=SUB32((a).i,(b).i); \ + }while(0) +#define C_ADDTO( res , a)\ + do {(res).r = ADD32((res).r, (a).r); (res).i = ADD32((res).i,(a).i);\ + }while(0) + +#define C_SUBFROM( res , a)\ + do {(res).r = ADD32((res).r,(a).r); (res).i = SUB32((res).i,(a).i); \ + }while(0) + +#if defined(OPUS_ARM_INLINE_ASM) +#include "arm/kiss_fft_armv4.h" +#endif + +#if defined(OPUS_ARM_INLINE_EDSP) +#include "arm/kiss_fft_armv5e.h" +#endif + +#else /* not FIXED_POINT*/ + +# define S_MUL(a,b) ( (a)*(b) ) +#define C_MUL(m,a,b) \ + do{ (m).r = (a).r*(b).r - (a).i*(b).i;\ + (m).i = (a).r*(b).i + (a).i*(b).r; }while(0) +#define C_MULC(m,a,b) \ + do{ (m).r = (a).r*(b).r + (a).i*(b).i;\ + (m).i = (a).i*(b).r - (a).r*(b).i; }while(0) + +#define C_MUL4(m,a,b) C_MUL(m,a,b) + +# define C_FIXDIV(c,div) /* NOOP */ +# define C_MULBYSCALAR( c, s ) \ + do{ (c).r *= (s);\ + (c).i *= (s); }while(0) +#endif + +#ifndef CHECK_OVERFLOW_OP +# define CHECK_OVERFLOW_OP(a,op,b) /* noop */ +#endif + +#ifndef C_ADD +#define C_ADD( res, a,b)\ + do { \ + CHECK_OVERFLOW_OP((a).r,+,(b).r)\ + CHECK_OVERFLOW_OP((a).i,+,(b).i)\ + (res).r=(a).r+(b).r; (res).i=(a).i+(b).i; \ + }while(0) +#define C_SUB( res, a,b)\ + do { \ + CHECK_OVERFLOW_OP((a).r,-,(b).r)\ + CHECK_OVERFLOW_OP((a).i,-,(b).i)\ + (res).r=(a).r-(b).r; (res).i=(a).i-(b).i; \ + }while(0) +#define C_ADDTO( res , a)\ + do { \ + CHECK_OVERFLOW_OP((res).r,+,(a).r)\ + CHECK_OVERFLOW_OP((res).i,+,(a).i)\ + (res).r += (a).r; (res).i += (a).i;\ + }while(0) + +#define C_SUBFROM( res , a)\ + do {\ + CHECK_OVERFLOW_OP((res).r,-,(a).r)\ + CHECK_OVERFLOW_OP((res).i,-,(a).i)\ + (res).r -= (a).r; (res).i -= (a).i; \ + }while(0) +#endif /* C_ADD defined */ + +#ifdef FIXED_POINT +/*# define KISS_FFT_COS(phase) TRIG_UPSCALE*floor(MIN(32767,MAX(-32767,.5+32768 * cos (phase)))) +# define KISS_FFT_SIN(phase) TRIG_UPSCALE*floor(MIN(32767,MAX(-32767,.5+32768 * sin (phase))))*/ +# define KISS_FFT_COS(phase) floor(.5+TWID_MAX*cos (phase)) +# define KISS_FFT_SIN(phase) floor(.5+TWID_MAX*sin (phase)) +# define HALF_OF(x) ((x)>>1) +#elif defined(USE_SIMD) +# define KISS_FFT_COS(phase) _mm_set1_ps( cos(phase) ) +# define KISS_FFT_SIN(phase) _mm_set1_ps( sin(phase) ) +# define HALF_OF(x) ((x)*_mm_set1_ps(.5f)) +#else +# define KISS_FFT_COS(phase) (kiss_fft_scalar) cos(phase) +# define KISS_FFT_SIN(phase) (kiss_fft_scalar) sin(phase) +# define HALF_OF(x) ((x)*.5f) +#endif + +#define kf_cexp(x,phase) \ + do{ \ + (x)->r = KISS_FFT_COS(phase);\ + (x)->i = KISS_FFT_SIN(phase);\ + }while(0) + +#define kf_cexp2(x,phase) \ + do{ \ + (x)->r = TRIG_UPSCALE*celt_cos_norm((phase));\ + (x)->i = TRIG_UPSCALE*celt_cos_norm((phase)-32768);\ +}while(0) + +#endif /* KISS_FFT_GUTS_H */ diff --git a/src/opus-1.1/celt/arch.h b/src/opus-1.1/celt/arch.h new file mode 100644 index 00000000..3bbcd366 --- /dev/null +++ b/src/opus-1.1/celt/arch.h @@ -0,0 +1,214 @@ +/* Copyright (c) 2003-2008 Jean-Marc Valin + Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation + Written by Jean-Marc Valin */ +/** + @file arch.h + @brief Various architecture definitions for CELT +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef ARCH_H +#define ARCH_H + +#include "opus_types.h" +#include "opus_defines.h" + +# if !defined(__GNUC_PREREQ) +# if defined(__GNUC__)&&defined(__GNUC_MINOR__) +# define __GNUC_PREREQ(_maj,_min) \ + ((__GNUC__<<16)+__GNUC_MINOR__>=((_maj)<<16)+(_min)) +# else +# define __GNUC_PREREQ(_maj,_min) 0 +# endif +# endif + +#define CELT_SIG_SCALE 32768.f + +#define celt_fatal(str) _celt_fatal(str, __FILE__, __LINE__); +#ifdef ENABLE_ASSERTIONS +#include +#include +#ifdef __GNUC__ +__attribute__((noreturn)) +#endif +static OPUS_INLINE void _celt_fatal(const char *str, const char *file, int line) +{ + fprintf (stderr, "Fatal (internal) error in %s, line %d: %s\n", file, line, str); + abort(); +} +#define celt_assert(cond) {if (!(cond)) {celt_fatal("assertion failed: " #cond);}} +#define celt_assert2(cond, message) {if (!(cond)) {celt_fatal("assertion failed: " #cond "\n" message);}} +#else +#define celt_assert(cond) +#define celt_assert2(cond, message) +#endif + +#define IMUL32(a,b) ((a)*(b)) + +#define ABS(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute integer value. */ +#define ABS16(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 16-bit value. */ +#define MIN16(a,b) ((a) < (b) ? (a) : (b)) /**< Minimum 16-bit value. */ +#define MAX16(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 16-bit value. */ +#define ABS32(x) ((x) < 0 ? (-(x)) : (x)) /**< Absolute 32-bit value. */ +#define MIN32(a,b) ((a) < (b) ? (a) : (b)) /**< Minimum 32-bit value. */ +#define MAX32(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum 32-bit value. */ +#define IMIN(a,b) ((a) < (b) ? (a) : (b)) /**< Minimum int value. */ +#define IMAX(a,b) ((a) > (b) ? (a) : (b)) /**< Maximum int value. */ +#define UADD32(a,b) ((a)+(b)) +#define USUB32(a,b) ((a)-(b)) + +#define PRINT_MIPS(file) + +#ifdef FIXED_POINT + +typedef opus_int16 opus_val16; +typedef opus_int32 opus_val32; + +typedef opus_val32 celt_sig; +typedef opus_val16 celt_norm; +typedef opus_val32 celt_ener; + +#define Q15ONE 32767 + +#define SIG_SHIFT 12 + +#define NORM_SCALING 16384 + +#define DB_SHIFT 10 + +#define EPSILON 1 +#define VERY_SMALL 0 +#define VERY_LARGE16 ((opus_val16)32767) +#define Q15_ONE ((opus_val16)32767) + +#define SCALEIN(a) (a) +#define SCALEOUT(a) (a) + +#ifdef FIXED_DEBUG +#include "fixed_debug.h" +#else + +#include "fixed_generic.h" + +#ifdef OPUS_ARM_INLINE_EDSP +#include "arm/fixed_armv5e.h" +#elif defined (OPUS_ARM_INLINE_ASM) +#include "arm/fixed_armv4.h" +#elif defined (BFIN_ASM) +#include "fixed_bfin.h" +#elif defined (TI_C5X_ASM) +#include "fixed_c5x.h" +#elif defined (TI_C6X_ASM) +#include "fixed_c6x.h" +#endif + +#endif + +#else /* FIXED_POINT */ + +typedef float opus_val16; +typedef float opus_val32; + +typedef float celt_sig; +typedef float celt_norm; +typedef float celt_ener; + +#define Q15ONE 1.0f + +#define NORM_SCALING 1.f + +#define EPSILON 1e-15f +#define VERY_SMALL 1e-30f +#define VERY_LARGE16 1e15f +#define Q15_ONE ((opus_val16)1.f) + +#define QCONST16(x,bits) (x) +#define QCONST32(x,bits) (x) + +#define NEG16(x) (-(x)) +#define NEG32(x) (-(x)) +#define EXTRACT16(x) (x) +#define EXTEND32(x) (x) +#define SHR16(a,shift) (a) +#define SHL16(a,shift) (a) +#define SHR32(a,shift) (a) +#define SHL32(a,shift) (a) +#define PSHR32(a,shift) (a) +#define VSHR32(a,shift) (a) + +#define PSHR(a,shift) (a) +#define SHR(a,shift) (a) +#define SHL(a,shift) (a) +#define SATURATE(x,a) (x) +#define SATURATE16(x) (x) + +#define ROUND16(a,shift) (a) +#define HALF16(x) (.5f*(x)) +#define HALF32(x) (.5f*(x)) + +#define ADD16(a,b) ((a)+(b)) +#define SUB16(a,b) ((a)-(b)) +#define ADD32(a,b) ((a)+(b)) +#define SUB32(a,b) ((a)-(b)) +#define MULT16_16_16(a,b) ((a)*(b)) +#define MULT16_16(a,b) ((opus_val32)(a)*(opus_val32)(b)) +#define MAC16_16(c,a,b) ((c)+(opus_val32)(a)*(opus_val32)(b)) + +#define MULT16_32_Q15(a,b) ((a)*(b)) +#define MULT16_32_Q16(a,b) ((a)*(b)) + +#define MULT32_32_Q31(a,b) ((a)*(b)) + +#define MAC16_32_Q15(c,a,b) ((c)+(a)*(b)) + +#define MULT16_16_Q11_32(a,b) ((a)*(b)) +#define MULT16_16_Q11(a,b) ((a)*(b)) +#define MULT16_16_Q13(a,b) ((a)*(b)) +#define MULT16_16_Q14(a,b) ((a)*(b)) +#define MULT16_16_Q15(a,b) ((a)*(b)) +#define MULT16_16_P15(a,b) ((a)*(b)) +#define MULT16_16_P13(a,b) ((a)*(b)) +#define MULT16_16_P14(a,b) ((a)*(b)) +#define MULT16_32_P16(a,b) ((a)*(b)) + +#define DIV32_16(a,b) (((opus_val32)(a))/(opus_val16)(b)) +#define DIV32(a,b) (((opus_val32)(a))/(opus_val32)(b)) + +#define SCALEIN(a) ((a)*CELT_SIG_SCALE) +#define SCALEOUT(a) ((a)*(1/CELT_SIG_SCALE)) + +#endif /* !FIXED_POINT */ + +#ifndef GLOBAL_STACK_SIZE +#ifdef FIXED_POINT +#define GLOBAL_STACK_SIZE 100000 +#else +#define GLOBAL_STACK_SIZE 100000 +#endif +#endif + +#endif /* ARCH_H */ diff --git a/src/opus-1.1/celt/arm/arm2gnu.pl b/src/opus-1.1/celt/arm/arm2gnu.pl new file mode 100755 index 00000000..eab42efa --- /dev/null +++ b/src/opus-1.1/celt/arm/arm2gnu.pl @@ -0,0 +1,316 @@ +#!/usr/bin/perl + +my $bigend; # little/big endian +my $nxstack; + +$nxstack = 0; + +eval 'exec /usr/local/bin/perl -S $0 ${1+"$@"}' + if $running_under_some_shell; + +while ($ARGV[0] =~ /^-/) { + $_ = shift; + last if /^--/; + if (/^-n/) { + $nflag++; + next; + } + die "I don't recognize this switch: $_\\n"; +} +$printit++ unless $nflag; + +$\ = "\n"; # automatically add newline on print +$n=0; + +$thumb = 0; # ARM mode by default, not Thumb. +@proc_stack = (); + +LINE: +while (<>) { + + # For ADRLs we need to add a new line after the substituted one. + $addPadding = 0; + + # First, we do not dare to touch *anything* inside double quotes, do we? + # Second, if you want a dollar character in the string, + # insert two of them -- that's how ARM C and assembler treat strings. + s/^([A-Za-z_]\w*)[ \t]+DCB[ \t]*\"/$1: .ascii \"/ && do { s/\$\$/\$/g; next }; + s/\bDCB\b[ \t]*\"/.ascii \"/ && do { s/\$\$/\$/g; next }; + s/^(\S+)\s+RN\s+(\S+)/$1 .req r$2/ && do { s/\$\$/\$/g; next }; + # If there's nothing on a line but a comment, don't try to apply any further + # substitutions (this is a cheap hack to avoid mucking up the license header) + s/^([ \t]*);/$1@/ && do { s/\$\$/\$/g; next }; + # If substituted -- leave immediately ! + + s/@/,:/; + s/;/@/; + while ( /@.*'/ ) { + s/(@.*)'/$1/g; + } + s/\{FALSE\}/0/g; + s/\{TRUE\}/1/g; + s/\{(\w\w\w\w+)\}/$1/g; + s/\bINCLUDE[ \t]*([^ \t\n]+)/.include \"$1\"/; + s/\bGET[ \t]*([^ \t\n]+)/.include \"${ my $x=$1; $x =~ s|\.s|-gnu.S|; \$x }\"/; + s/\bIMPORT\b/.extern/; + s/\bEXPORT\b/.global/; + s/^(\s+)\[/$1IF/; + s/^(\s+)\|/$1ELSE/; + s/^(\s+)\]/$1ENDIF/; + s/IF *:DEF:/ .ifdef/; + s/IF *:LNOT: *:DEF:/ .ifndef/; + s/ELSE/ .else/; + s/ENDIF/ .endif/; + + if( /\bIF\b/ ) { + s/\bIF\b/ .if/; + s/=/==/; + } + if ( $n == 2) { + s/\$/\\/g; + } + if ($n == 1) { + s/\$//g; + s/label//g; + $n = 2; + } + if ( /MACRO/ ) { + s/MACRO *\n/.macro/; + $n=1; + } + if ( /\bMEND\b/ ) { + s/\bMEND\b/.endm/; + $n=0; + } + + # ".rdata" doesn't work in 'as' version 2.13.2, as it is ".rodata" there. + # + if ( /\bAREA\b/ ) { + my $align; + $align = "2"; + if ( /ALIGN=(\d+)/ ) { + $align = $1; + } + if ( /CODE/ ) { + $nxstack = 1; + } + s/^(.+)CODE(.+)READONLY(.*)/ .text/; + s/^(.+)DATA(.+)READONLY(.*)/ .section .rdata/; + s/^(.+)\|\|\.data\|\|(.+)/ .data/; + s/^(.+)\|\|\.bss\|\|(.+)/ .bss/; + s/$/; .p2align $align/; + # Enable NEON instructions but don't produce a binary that requires + # ARMv7. RVCT does not have equivalent directives, so we just do this + # for all CODE areas. + if ( /.text/ ) { + # Separating .arch, .fpu, etc., by semicolons does not work (gas + # thinks the semicolon is part of the arch name, even when there's + # whitespace separating them). Sadly this means our line numbers + # won't match the original source file (we could use the .line + # directive, which is documented to be obsolete, but then gdb will + # show the wrong line in the translated source file). + s/$/; .arch armv7-a\n .fpu neon\n .object_arch armv4t/; + } + } + + s/\|\|\.constdata\$(\d+)\|\|/.L_CONST$1/; # ||.constdata$3|| + s/\|\|\.bss\$(\d+)\|\|/.L_BSS$1/; # ||.bss$2|| + s/\|\|\.data\$(\d+)\|\|/.L_DATA$1/; # ||.data$2|| + s/\|\|([a-zA-Z0-9_]+)\@([a-zA-Z0-9_]+)\|\|/@ $&/; + s/^(\s+)\%(\s)/ .space $1/; + + s/\|(.+)\.(\d+)\|/\.$1_$2/; # |L80.123| -> .L80_123 + s/\bCODE32\b/.code 32/ && do {$thumb = 0}; + s/\bCODE16\b/.code 16/ && do {$thumb = 1}; + if (/\bPROC\b/) + { + my $prefix; + my $proc; + /^([A-Za-z_\.]\w+)\b/; + $proc = $1; + $prefix = ""; + if ($proc) + { + $prefix = $prefix.sprintf("\t.type\t%s, %%function; ",$proc); + push(@proc_stack, $proc); + s/^[A-Za-z_\.]\w+/$&:/; + } + $prefix = $prefix."\t.thumb_func; " if ($thumb); + s/\bPROC\b/@ $&/; + $_ = $prefix.$_; + } + s/^(\s*)(S|Q|SH|U|UQ|UH)ASX\b/$1$2ADDSUBX/; + s/^(\s*)(S|Q|SH|U|UQ|UH)SAX\b/$1$2SUBADDX/; + if (/\bENDP\b/) + { + my $proc; + s/\bENDP\b/@ $&/; + $proc = pop(@proc_stack); + $_ = "\t.size $proc, .-$proc".$_ if ($proc); + } + s/\bSUBT\b/@ $&/; + s/\bDATA\b/@ $&/; # DATA directive is deprecated -- Asm guide, p.7-25 + s/\bKEEP\b/@ $&/; + s/\bEXPORTAS\b/@ $&/; + s/\|\|(.)+\bEQU\b/@ $&/; + s/\|\|([\w\$]+)\|\|/$1/; + s/\bENTRY\b/@ $&/; + s/\bASSERT\b/@ $&/; + s/\bGBLL\b/@ $&/; + s/\bGBLA\b/@ $&/; + s/^\W+OPT\b/@ $&/; + s/:OR:/|/g; + s/:SHL:/<>/g; + s/:AND:/&/g; + s/:LAND:/&&/g; + s/CPSR/cpsr/; + s/SPSR/spsr/; + s/ALIGN$/.balign 4/; + s/ALIGN\s+([0-9x]+)$/.balign $1/; + s/psr_cxsf/psr_all/; + s/LTORG/.ltorg/; + s/^([A-Za-z_]\w*)[ \t]+EQU/ .set $1,/; + s/^([A-Za-z_]\w*)[ \t]+SETL/ .set $1,/; + s/^([A-Za-z_]\w*)[ \t]+SETA/ .set $1,/; + s/^([A-Za-z_]\w*)[ \t]+\*/ .set $1,/; + + # {PC} + 0xdeadfeed --> . + 0xdeadfeed + s/\{PC\} \+/ \. +/; + + # Single hex constant on the line ! + # + # >>> NOTE <<< + # Double-precision floats in gcc are always mixed-endian, which means + # bytes in two words are little-endian, but words are big-endian. + # So, 0x0000deadfeed0000 would be stored as 0x0000dead at low address + # and 0xfeed0000 at high address. + # + s/\bDCFD\b[ \t]+0x([a-fA-F0-9]{8})([a-fA-F0-9]{8})/.long 0x$1, 0x$2/; + # Only decimal constants on the line, no hex ! + s/\bDCFD\b[ \t]+([0-9\.\-]+)/.double $1/; + + # Single hex constant on the line ! +# s/\bDCFS\b[ \t]+0x([a-f0-9]{8})([a-f0-9]{8})/.long 0x$1, 0x$2/; + # Only decimal constants on the line, no hex ! +# s/\bDCFS\b[ \t]+([0-9\.\-]+)/.double $1/; + s/\bDCFS[ \t]+0x/.word 0x/; + s/\bDCFS\b/.float/; + + s/^([A-Za-z_]\w*)[ \t]+DCD/$1 .word/; + s/\bDCD\b/.word/; + s/^([A-Za-z_]\w*)[ \t]+DCW/$1 .short/; + s/\bDCW\b/.short/; + s/^([A-Za-z_]\w*)[ \t]+DCB/$1 .byte/; + s/\bDCB\b/.byte/; + s/^([A-Za-z_]\w*)[ \t]+\%/.comm $1,/; + s/^[A-Za-z_\.]\w+/$&:/; + s/^(\d+)/$1:/; + s/\%(\d+)/$1b_or_f/; + s/\%[Bb](\d+)/$1b/; + s/\%[Ff](\d+)/$1f/; + s/\%[Ff][Tt](\d+)/$1f/; + s/&([\dA-Fa-f]+)/0x$1/; + if ( /\b2_[01]+\b/ ) { + s/\b2_([01]+)\b/conv$1&&&&/g; + while ( /[01][01][01][01]&&&&/ ) { + s/0000&&&&/&&&&0/g; + s/0001&&&&/&&&&1/g; + s/0010&&&&/&&&&2/g; + s/0011&&&&/&&&&3/g; + s/0100&&&&/&&&&4/g; + s/0101&&&&/&&&&5/g; + s/0110&&&&/&&&&6/g; + s/0111&&&&/&&&&7/g; + s/1000&&&&/&&&&8/g; + s/1001&&&&/&&&&9/g; + s/1010&&&&/&&&&A/g; + s/1011&&&&/&&&&B/g; + s/1100&&&&/&&&&C/g; + s/1101&&&&/&&&&D/g; + s/1110&&&&/&&&&E/g; + s/1111&&&&/&&&&F/g; + } + s/000&&&&/&&&&0/g; + s/001&&&&/&&&&1/g; + s/010&&&&/&&&&2/g; + s/011&&&&/&&&&3/g; + s/100&&&&/&&&&4/g; + s/101&&&&/&&&&5/g; + s/110&&&&/&&&&6/g; + s/111&&&&/&&&&7/g; + s/00&&&&/&&&&0/g; + s/01&&&&/&&&&1/g; + s/10&&&&/&&&&2/g; + s/11&&&&/&&&&3/g; + s/0&&&&/&&&&0/g; + s/1&&&&/&&&&1/g; + s/conv&&&&/0x/g; + } + + if ( /commandline/) + { + if( /-bigend/) + { + $bigend=1; + } + } + + if ( /\bDCDU\b/ ) + { + my $cmd=$_; + my $value; + my $prefix; + my $w1; + my $w2; + my $w3; + my $w4; + + s/\s+DCDU\b/@ $&/; + + $cmd =~ /\bDCDU\b\s+0x(\d+)/; + $value = $1; + $value =~ /(\w\w)(\w\w)(\w\w)(\w\w)/; + $w1 = $1; + $w2 = $2; + $w3 = $3; + $w4 = $4; + + if( $bigend ne "") + { + # big endian + $prefix = "\t.byte\t0x".$w1.";". + "\t.byte\t0x".$w2.";". + "\t.byte\t0x".$w3.";". + "\t.byte\t0x".$w4."; "; + } + else + { + # little endian + $prefix = "\t.byte\t0x".$w4.";". + "\t.byte\t0x".$w3.";". + "\t.byte\t0x".$w2.";". + "\t.byte\t0x".$w1."; "; + } + $_=$prefix.$_; + } + + if ( /\badrl\b/i ) + { + s/\badrl\s+(\w+)\s*,\s*(\w+)/ldr $1,=$2/i; + $addPadding = 1; + } + s/\bEND\b/@ END/; +} continue { + printf ("%s", $_) if $printit; + if ($addPadding != 0) + { + printf (" mov r0,r0\n"); + $addPadding = 0; + } +} +#If we had a code section, mark that this object doesn't need an executable +# stack. +if ($nxstack) { + printf (" .section\t.note.GNU-stack,\"\",\%\%progbits\n"); +} diff --git a/src/opus-1.1/celt/arm/arm_celt_map.c b/src/opus-1.1/celt/arm/arm_celt_map.c new file mode 100644 index 00000000..547a84d1 --- /dev/null +++ b/src/opus-1.1/celt/arm/arm_celt_map.c @@ -0,0 +1,49 @@ +/* Copyright (c) 2010 Xiph.Org Foundation + * Copyright (c) 2013 Parrot */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pitch.h" + +#if defined(OPUS_HAVE_RTCD) + +# if defined(FIXED_POINT) +opus_val32 (*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *, + const opus_val16 *, opus_val32 *, int , int) = { + celt_pitch_xcorr_c, /* ARMv4 */ + MAY_HAVE_EDSP(celt_pitch_xcorr), /* EDSP */ + MAY_HAVE_MEDIA(celt_pitch_xcorr), /* Media */ + MAY_HAVE_NEON(celt_pitch_xcorr) /* NEON */ +}; +# else +# error "Floating-point implementation is not supported by ARM asm yet." \ + "Reconfigure with --disable-rtcd or send patches." +# endif + +#endif diff --git a/src/opus-1.1/celt/arm/armcpu.c b/src/opus-1.1/celt/arm/armcpu.c new file mode 100644 index 00000000..17685258 --- /dev/null +++ b/src/opus-1.1/celt/arm/armcpu.c @@ -0,0 +1,174 @@ +/* Copyright (c) 2010 Xiph.Org Foundation + * Copyright (c) 2013 Parrot */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* Original code from libtheora modified to suit to Opus */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifdef OPUS_HAVE_RTCD + +#include "armcpu.h" +#include "cpu_support.h" +#include "os_support.h" +#include "opus_types.h" + +#define OPUS_CPU_ARM_V4 (1) +#define OPUS_CPU_ARM_EDSP (1<<1) +#define OPUS_CPU_ARM_MEDIA (1<<2) +#define OPUS_CPU_ARM_NEON (1<<3) + +#if defined(_MSC_VER) +/*For GetExceptionCode() and EXCEPTION_ILLEGAL_INSTRUCTION.*/ +# define WIN32_LEAN_AND_MEAN +# define WIN32_EXTRA_LEAN +# include + +static OPUS_INLINE opus_uint32 opus_cpu_capabilities(void){ + opus_uint32 flags; + flags=0; + /* MSVC has no OPUS_INLINE __asm support for ARM, but it does let you __emit + * instructions via their assembled hex code. + * All of these instructions should be essentially nops. */ +# if defined(OPUS_ARM_MAY_HAVE_EDSP) + __try{ + /*PLD [r13]*/ + __emit(0xF5DDF000); + flags|=OPUS_CPU_ARM_EDSP; + } + __except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION){ + /*Ignore exception.*/ + } +# if defined(OPUS_ARM_MAY_HAVE_MEDIA) + __try{ + /*SHADD8 r3,r3,r3*/ + __emit(0xE6333F93); + flags|=OPUS_CPU_ARM_MEDIA; + } + __except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION){ + /*Ignore exception.*/ + } +# if defined(OPUS_ARM_MAY_HAVE_NEON) + __try{ + /*VORR q0,q0,q0*/ + __emit(0xF2200150); + flags|=OPUS_CPU_ARM_NEON; + } + __except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION){ + /*Ignore exception.*/ + } +# endif +# endif +# endif + return flags; +} + +#elif defined(__linux__) +/* Linux based */ +opus_uint32 opus_cpu_capabilities(void) +{ + opus_uint32 flags = 0; + FILE *cpuinfo; + + /* Reading /proc/self/auxv would be easier, but that doesn't work reliably on + * Android */ + cpuinfo = fopen("/proc/cpuinfo", "r"); + + if(cpuinfo != NULL) + { + /* 512 should be enough for anybody (it's even enough for all the flags that + * x86 has accumulated... so far). */ + char buf[512]; + + while(fgets(buf, 512, cpuinfo) != NULL) + { +# if defined(OPUS_ARM_MAY_HAVE_EDSP) || defined(OPUS_ARM_MAY_HAVE_NEON) + /* Search for edsp and neon flag */ + if(memcmp(buf, "Features", 8) == 0) + { + char *p; +# if defined(OPUS_ARM_MAY_HAVE_EDSP) + p = strstr(buf, " edsp"); + if(p != NULL && (p[5] == ' ' || p[5] == '\n')) + flags |= OPUS_CPU_ARM_EDSP; +# endif + +# if defined(OPUS_ARM_MAY_HAVE_NEON) + p = strstr(buf, " neon"); + if(p != NULL && (p[5] == ' ' || p[5] == '\n')) + flags |= OPUS_CPU_ARM_NEON; +# endif + } +# endif + +# if defined(OPUS_ARM_MAY_HAVE_MEDIA) + /* Search for media capabilities (>= ARMv6) */ + if(memcmp(buf, "CPU architecture:", 17) == 0) + { + int version; + version = atoi(buf+17); + + if(version >= 6) + flags |= OPUS_CPU_ARM_MEDIA; + } +# endif + } + + fclose(cpuinfo); + } + return flags; +} +#else +/* The feature registers which can tell us what the processor supports are + * accessible in priveleged modes only, so we can't have a general user-space + * detection method like on x86.*/ +# error "Configured to use ARM asm but no CPU detection method available for " \ + "your platform. Reconfigure with --disable-rtcd (or send patches)." +#endif + +int opus_select_arch(void) +{ + opus_uint32 flags = opus_cpu_capabilities(); + int arch = 0; + + if(!(flags & OPUS_CPU_ARM_EDSP)) + return arch; + arch++; + + if(!(flags & OPUS_CPU_ARM_MEDIA)) + return arch; + arch++; + + if(!(flags & OPUS_CPU_ARM_NEON)) + return arch; + arch++; + + return arch; +} + +#endif diff --git a/src/opus-1.1/celt/arm/armcpu.h b/src/opus-1.1/celt/arm/armcpu.h new file mode 100644 index 00000000..ac574460 --- /dev/null +++ b/src/opus-1.1/celt/arm/armcpu.h @@ -0,0 +1,71 @@ +/* Copyright (c) 2010 Xiph.Org Foundation + * Copyright (c) 2013 Parrot */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#if !defined(ARMCPU_H) +# define ARMCPU_H + +# if defined(OPUS_ARM_MAY_HAVE_EDSP) +# define MAY_HAVE_EDSP(name) name ## _edsp +# else +# define MAY_HAVE_EDSP(name) name ## _c +# endif + +# if defined(OPUS_ARM_MAY_HAVE_MEDIA) +# define MAY_HAVE_MEDIA(name) name ## _media +# else +# define MAY_HAVE_MEDIA(name) MAY_HAVE_EDSP(name) +# endif + +# if defined(OPUS_ARM_MAY_HAVE_NEON) +# define MAY_HAVE_NEON(name) name ## _neon +# else +# define MAY_HAVE_NEON(name) MAY_HAVE_MEDIA(name) +# endif + +# if defined(OPUS_ARM_PRESUME_EDSP) +# define PRESUME_EDSP(name) name ## _edsp +# else +# define PRESUME_EDSP(name) name ## _c +# endif + +# if defined(OPUS_ARM_PRESUME_MEDIA) +# define PRESUME_MEDIA(name) name ## _media +# else +# define PRESUME_MEDIA(name) PRESUME_EDSP(name) +# endif + +# if defined(OPUS_ARM_PRESUME_NEON) +# define PRESUME_NEON(name) name ## _neon +# else +# define PRESUME_NEON(name) PRESUME_MEDIA(name) +# endif + +# if defined(OPUS_HAVE_RTCD) +int opus_select_arch(void); +# endif + +#endif diff --git a/src/opus-1.1/celt/arm/armopts.s.in b/src/opus-1.1/celt/arm/armopts.s.in new file mode 100644 index 00000000..3d8aaf27 --- /dev/null +++ b/src/opus-1.1/celt/arm/armopts.s.in @@ -0,0 +1,37 @@ +/* Copyright (C) 2013 Mozilla Corporation */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +; Set the following to 1 if we have EDSP instructions +; (LDRD/STRD, etc., ARMv5E and later). +OPUS_ARM_MAY_HAVE_EDSP * @OPUS_ARM_MAY_HAVE_EDSP@ + +; Set the following to 1 if we have ARMv6 media instructions. +OPUS_ARM_MAY_HAVE_MEDIA * @OPUS_ARM_MAY_HAVE_MEDIA@ + +; Set the following to 1 if we have NEON (some ARMv7) +OPUS_ARM_MAY_HAVE_NEON * @OPUS_ARM_MAY_HAVE_NEON@ + +END diff --git a/src/opus-1.1/celt/arm/celt_pitch_xcorr_arm.s b/src/opus-1.1/celt/arm/celt_pitch_xcorr_arm.s new file mode 100644 index 00000000..09917b16 --- /dev/null +++ b/src/opus-1.1/celt/arm/celt_pitch_xcorr_arm.s @@ -0,0 +1,545 @@ +; Copyright (c) 2007-2008 CSIRO +; Copyright (c) 2007-2009 Xiph.Org Foundation +; Copyright (c) 2013 Parrot +; Written by Aurélien Zanelli +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions +; are met: +; +; - Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; +; - Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; +; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +; ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +; OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + AREA |.text|, CODE, READONLY + + GET celt/arm/armopts.s + +IF OPUS_ARM_MAY_HAVE_EDSP + EXPORT celt_pitch_xcorr_edsp +ENDIF + +IF OPUS_ARM_MAY_HAVE_NEON + EXPORT celt_pitch_xcorr_neon +ENDIF + +IF OPUS_ARM_MAY_HAVE_NEON + +; Compute sum[k]=sum(x[j]*y[j+k],j=0...len-1), k=0...3 +xcorr_kernel_neon PROC + ; input: + ; r3 = int len + ; r4 = opus_val16 *x + ; r5 = opus_val16 *y + ; q0 = opus_val32 sum[4] + ; output: + ; q0 = opus_val32 sum[4] + ; preserved: r0-r3, r6-r11, d2, q4-q7, q9-q15 + ; internal usage: + ; r12 = int j + ; d3 = y_3|y_2|y_1|y_0 + ; q2 = y_B|y_A|y_9|y_8|y_7|y_6|y_5|y_4 + ; q3 = x_7|x_6|x_5|x_4|x_3|x_2|x_1|x_0 + ; q8 = scratch + ; + ; Load y[0...3] + ; This requires len>0 to always be valid (which we assert in the C code). + VLD1.16 {d5}, [r5]! + SUBS r12, r3, #8 + BLE xcorr_kernel_neon_process4 +; Process 8 samples at a time. +; This loop loads one y value more than we actually need. Therefore we have to +; stop as soon as there are 8 or fewer samples left (instead of 7), to avoid +; reading past the end of the array. +xcorr_kernel_neon_process8 + ; This loop has 19 total instructions (10 cycles to issue, minimum), with + ; - 2 cycles of ARM insrtuctions, + ; - 10 cycles of load/store/byte permute instructions, and + ; - 9 cycles of data processing instructions. + ; On a Cortex A8, we dual-issue the maximum amount (9 cycles) between the + ; latter two categories, meaning the whole loop should run in 10 cycles per + ; iteration, barring cache misses. + ; + ; Load x[0...7] + VLD1.16 {d6, d7}, [r4]! + ; Unlike VMOV, VAND is a data processsing instruction (and doesn't get + ; assembled to VMOV, like VORR would), so it dual-issues with the prior VLD1. + VAND d3, d5, d5 + SUBS r12, r12, #8 + ; Load y[4...11] + VLD1.16 {d4, d5}, [r5]! + VMLAL.S16 q0, d3, d6[0] + VEXT.16 d16, d3, d4, #1 + VMLAL.S16 q0, d4, d7[0] + VEXT.16 d17, d4, d5, #1 + VMLAL.S16 q0, d16, d6[1] + VEXT.16 d16, d3, d4, #2 + VMLAL.S16 q0, d17, d7[1] + VEXT.16 d17, d4, d5, #2 + VMLAL.S16 q0, d16, d6[2] + VEXT.16 d16, d3, d4, #3 + VMLAL.S16 q0, d17, d7[2] + VEXT.16 d17, d4, d5, #3 + VMLAL.S16 q0, d16, d6[3] + VMLAL.S16 q0, d17, d7[3] + BGT xcorr_kernel_neon_process8 +; Process 4 samples here if we have > 4 left (still reading one extra y value). +xcorr_kernel_neon_process4 + ADDS r12, r12, #4 + BLE xcorr_kernel_neon_process2 + ; Load x[0...3] + VLD1.16 d6, [r4]! + ; Use VAND since it's a data processing instruction again. + VAND d4, d5, d5 + SUB r12, r12, #4 + ; Load y[4...7] + VLD1.16 d5, [r5]! + VMLAL.S16 q0, d4, d6[0] + VEXT.16 d16, d4, d5, #1 + VMLAL.S16 q0, d16, d6[1] + VEXT.16 d16, d4, d5, #2 + VMLAL.S16 q0, d16, d6[2] + VEXT.16 d16, d4, d5, #3 + VMLAL.S16 q0, d16, d6[3] +; Process 2 samples here if we have > 2 left (still reading one extra y value). +xcorr_kernel_neon_process2 + ADDS r12, r12, #2 + BLE xcorr_kernel_neon_process1 + ; Load x[0...1] + VLD2.16 {d6[],d7[]}, [r4]! + ; Use VAND since it's a data processing instruction again. + VAND d4, d5, d5 + SUB r12, r12, #2 + ; Load y[4...5] + VLD1.32 {d5[]}, [r5]! + VMLAL.S16 q0, d4, d6 + VEXT.16 d16, d4, d5, #1 + ; Replace bottom copy of {y5,y4} in d5 with {y3,y2} from d4, using VSRI + ; instead of VEXT, since it's a data-processing instruction. + VSRI.64 d5, d4, #32 + VMLAL.S16 q0, d16, d7 +; Process 1 sample using the extra y value we loaded above. +xcorr_kernel_neon_process1 + ; Load next *x + VLD1.16 {d6[]}, [r4]! + ADDS r12, r12, #1 + ; y[0...3] are left in d5 from prior iteration(s) (if any) + VMLAL.S16 q0, d5, d6 + MOVLE pc, lr +; Now process 1 last sample, not reading ahead. + ; Load last *y + VLD1.16 {d4[]}, [r5]! + VSRI.64 d4, d5, #16 + ; Load last *x + VLD1.16 {d6[]}, [r4]! + VMLAL.S16 q0, d4, d6 + MOV pc, lr + ENDP + +; opus_val32 celt_pitch_xcorr_neon(opus_val16 *_x, opus_val16 *_y, +; opus_val32 *xcorr, int len, int max_pitch) +celt_pitch_xcorr_neon PROC + ; input: + ; r0 = opus_val16 *_x + ; r1 = opus_val16 *_y + ; r2 = opus_val32 *xcorr + ; r3 = int len + ; output: + ; r0 = int maxcorr + ; internal usage: + ; r4 = opus_val16 *x (for xcorr_kernel_neon()) + ; r5 = opus_val16 *y (for xcorr_kernel_neon()) + ; r6 = int max_pitch + ; r12 = int j + ; q15 = int maxcorr[4] (q15 is not used by xcorr_kernel_neon()) + STMFD sp!, {r4-r6, lr} + LDR r6, [sp, #16] + VMOV.S32 q15, #1 + ; if (max_pitch < 4) goto celt_pitch_xcorr_neon_process4_done + SUBS r6, r6, #4 + BLT celt_pitch_xcorr_neon_process4_done +celt_pitch_xcorr_neon_process4 + ; xcorr_kernel_neon parameters: + ; r3 = len, r4 = _x, r5 = _y, q0 = {0, 0, 0, 0} + MOV r4, r0 + MOV r5, r1 + VEOR q0, q0, q0 + ; xcorr_kernel_neon only modifies r4, r5, r12, and q0...q3. + ; So we don't save/restore any other registers. + BL xcorr_kernel_neon + SUBS r6, r6, #4 + VST1.32 {q0}, [r2]! + ; _y += 4 + ADD r1, r1, #8 + VMAX.S32 q15, q15, q0 + ; if (max_pitch < 4) goto celt_pitch_xcorr_neon_process4_done + BGE celt_pitch_xcorr_neon_process4 +; We have less than 4 sums left to compute. +celt_pitch_xcorr_neon_process4_done + ADDS r6, r6, #4 + ; Reduce maxcorr to a single value + VMAX.S32 d30, d30, d31 + VPMAX.S32 d30, d30, d30 + ; if (max_pitch <= 0) goto celt_pitch_xcorr_neon_done + BLE celt_pitch_xcorr_neon_done +; Now compute each remaining sum one at a time. +celt_pitch_xcorr_neon_process_remaining + MOV r4, r0 + MOV r5, r1 + VMOV.I32 q0, #0 + SUBS r12, r3, #8 + BLT celt_pitch_xcorr_neon_process_remaining4 +; Sum terms 8 at a time. +celt_pitch_xcorr_neon_process_remaining_loop8 + ; Load x[0...7] + VLD1.16 {q1}, [r4]! + ; Load y[0...7] + VLD1.16 {q2}, [r5]! + SUBS r12, r12, #8 + VMLAL.S16 q0, d4, d2 + VMLAL.S16 q0, d5, d3 + BGE celt_pitch_xcorr_neon_process_remaining_loop8 +; Sum terms 4 at a time. +celt_pitch_xcorr_neon_process_remaining4 + ADDS r12, r12, #4 + BLT celt_pitch_xcorr_neon_process_remaining4_done + ; Load x[0...3] + VLD1.16 {d2}, [r4]! + ; Load y[0...3] + VLD1.16 {d3}, [r5]! + SUB r12, r12, #4 + VMLAL.S16 q0, d3, d2 +celt_pitch_xcorr_neon_process_remaining4_done + ; Reduce the sum to a single value. + VADD.S32 d0, d0, d1 + VPADDL.S32 d0, d0 + ADDS r12, r12, #4 + BLE celt_pitch_xcorr_neon_process_remaining_loop_done +; Sum terms 1 at a time. +celt_pitch_xcorr_neon_process_remaining_loop1 + VLD1.16 {d2[]}, [r4]! + VLD1.16 {d3[]}, [r5]! + SUBS r12, r12, #1 + VMLAL.S16 q0, d2, d3 + BGT celt_pitch_xcorr_neon_process_remaining_loop1 +celt_pitch_xcorr_neon_process_remaining_loop_done + VST1.32 {d0[0]}, [r2]! + VMAX.S32 d30, d30, d0 + SUBS r6, r6, #1 + ; _y++ + ADD r1, r1, #2 + ; if (--max_pitch > 0) goto celt_pitch_xcorr_neon_process_remaining + BGT celt_pitch_xcorr_neon_process_remaining +celt_pitch_xcorr_neon_done + VMOV.32 r0, d30[0] + LDMFD sp!, {r4-r6, pc} + ENDP + +ENDIF + +IF OPUS_ARM_MAY_HAVE_EDSP + +; This will get used on ARMv7 devices without NEON, so it has been optimized +; to take advantage of dual-issuing where possible. +xcorr_kernel_edsp PROC + ; input: + ; r3 = int len + ; r4 = opus_val16 *_x (must be 32-bit aligned) + ; r5 = opus_val16 *_y (must be 32-bit aligned) + ; r6...r9 = opus_val32 sum[4] + ; output: + ; r6...r9 = opus_val32 sum[4] + ; preserved: r0-r5 + ; internal usage + ; r2 = int j + ; r12,r14 = opus_val16 x[4] + ; r10,r11 = opus_val16 y[4] + STMFD sp!, {r2,r4,r5,lr} + LDR r10, [r5], #4 ; Load y[0...1] + SUBS r2, r3, #4 ; j = len-4 + LDR r11, [r5], #4 ; Load y[2...3] + BLE xcorr_kernel_edsp_process4_done + LDR r12, [r4], #4 ; Load x[0...1] + ; Stall +xcorr_kernel_edsp_process4 + ; The multiplies must issue from pipeline 0, and can't dual-issue with each + ; other. Every other instruction here dual-issues with a multiply, and is + ; thus "free". There should be no stalls in the body of the loop. + SMLABB r6, r12, r10, r6 ; sum[0] = MAC16_16(sum[0],x_0,y_0) + LDR r14, [r4], #4 ; Load x[2...3] + SMLABT r7, r12, r10, r7 ; sum[1] = MAC16_16(sum[1],x_0,y_1) + SUBS r2, r2, #4 ; j-=4 + SMLABB r8, r12, r11, r8 ; sum[2] = MAC16_16(sum[2],x_0,y_2) + SMLABT r9, r12, r11, r9 ; sum[3] = MAC16_16(sum[3],x_0,y_3) + SMLATT r6, r12, r10, r6 ; sum[0] = MAC16_16(sum[0],x_1,y_1) + LDR r10, [r5], #4 ; Load y[4...5] + SMLATB r7, r12, r11, r7 ; sum[1] = MAC16_16(sum[1],x_1,y_2) + SMLATT r8, r12, r11, r8 ; sum[2] = MAC16_16(sum[2],x_1,y_3) + SMLATB r9, r12, r10, r9 ; sum[3] = MAC16_16(sum[3],x_1,y_4) + LDRGT r12, [r4], #4 ; Load x[0...1] + SMLABB r6, r14, r11, r6 ; sum[0] = MAC16_16(sum[0],x_2,y_2) + SMLABT r7, r14, r11, r7 ; sum[1] = MAC16_16(sum[1],x_2,y_3) + SMLABB r8, r14, r10, r8 ; sum[2] = MAC16_16(sum[2],x_2,y_4) + SMLABT r9, r14, r10, r9 ; sum[3] = MAC16_16(sum[3],x_2,y_5) + SMLATT r6, r14, r11, r6 ; sum[0] = MAC16_16(sum[0],x_3,y_3) + LDR r11, [r5], #4 ; Load y[6...7] + SMLATB r7, r14, r10, r7 ; sum[1] = MAC16_16(sum[1],x_3,y_4) + SMLATT r8, r14, r10, r8 ; sum[2] = MAC16_16(sum[2],x_3,y_5) + SMLATB r9, r14, r11, r9 ; sum[3] = MAC16_16(sum[3],x_3,y_6) + BGT xcorr_kernel_edsp_process4 +xcorr_kernel_edsp_process4_done + ADDS r2, r2, #4 + BLE xcorr_kernel_edsp_done + LDRH r12, [r4], #2 ; r12 = *x++ + SUBS r2, r2, #1 ; j-- + ; Stall + SMLABB r6, r12, r10, r6 ; sum[0] = MAC16_16(sum[0],x,y_0) + LDRGTH r14, [r4], #2 ; r14 = *x++ + SMLABT r7, r12, r10, r7 ; sum[1] = MAC16_16(sum[1],x,y_1) + SMLABB r8, r12, r11, r8 ; sum[2] = MAC16_16(sum[2],x,y_2) + SMLABT r9, r12, r11, r9 ; sum[3] = MAC16_16(sum[3],x,y_3) + BLE xcorr_kernel_edsp_done + SMLABT r6, r14, r10, r6 ; sum[0] = MAC16_16(sum[0],x,y_1) + SUBS r2, r2, #1 ; j-- + SMLABB r7, r14, r11, r7 ; sum[1] = MAC16_16(sum[1],x,y_2) + LDRH r10, [r5], #2 ; r10 = y_4 = *y++ + SMLABT r8, r14, r11, r8 ; sum[2] = MAC16_16(sum[2],x,y_3) + LDRGTH r12, [r4], #2 ; r12 = *x++ + SMLABB r9, r14, r10, r9 ; sum[3] = MAC16_16(sum[3],x,y_4) + BLE xcorr_kernel_edsp_done + SMLABB r6, r12, r11, r6 ; sum[0] = MAC16_16(sum[0],tmp,y_2) + CMP r2, #1 ; j-- + SMLABT r7, r12, r11, r7 ; sum[1] = MAC16_16(sum[1],tmp,y_3) + LDRH r2, [r5], #2 ; r2 = y_5 = *y++ + SMLABB r8, r12, r10, r8 ; sum[2] = MAC16_16(sum[2],tmp,y_4) + LDRGTH r14, [r4] ; r14 = *x + SMLABB r9, r12, r2, r9 ; sum[3] = MAC16_16(sum[3],tmp,y_5) + BLE xcorr_kernel_edsp_done + SMLABT r6, r14, r11, r6 ; sum[0] = MAC16_16(sum[0],tmp,y_3) + LDRH r11, [r5] ; r11 = y_6 = *y + SMLABB r7, r14, r10, r7 ; sum[1] = MAC16_16(sum[1],tmp,y_4) + SMLABB r8, r14, r2, r8 ; sum[2] = MAC16_16(sum[2],tmp,y_5) + SMLABB r9, r14, r11, r9 ; sum[3] = MAC16_16(sum[3],tmp,y_6) +xcorr_kernel_edsp_done + LDMFD sp!, {r2,r4,r5,pc} + ENDP + +celt_pitch_xcorr_edsp PROC + ; input: + ; r0 = opus_val16 *_x (must be 32-bit aligned) + ; r1 = opus_val16 *_y (only needs to be 16-bit aligned) + ; r2 = opus_val32 *xcorr + ; r3 = int len + ; output: + ; r0 = maxcorr + ; internal usage + ; r4 = opus_val16 *x + ; r5 = opus_val16 *y + ; r6 = opus_val32 sum0 + ; r7 = opus_val32 sum1 + ; r8 = opus_val32 sum2 + ; r9 = opus_val32 sum3 + ; r1 = int max_pitch + ; r12 = int j + STMFD sp!, {r4-r11, lr} + MOV r5, r1 + LDR r1, [sp, #36] + MOV r4, r0 + TST r5, #3 + ; maxcorr = 1 + MOV r0, #1 + BEQ celt_pitch_xcorr_edsp_process1u_done +; Compute one sum at the start to make y 32-bit aligned. + SUBS r12, r3, #4 + ; r14 = sum = 0 + MOV r14, #0 + LDRH r8, [r5], #2 + BLE celt_pitch_xcorr_edsp_process1u_loop4_done + LDR r6, [r4], #4 + MOV r8, r8, LSL #16 +celt_pitch_xcorr_edsp_process1u_loop4 + LDR r9, [r5], #4 + SMLABT r14, r6, r8, r14 ; sum = MAC16_16(sum, x_0, y_0) + LDR r7, [r4], #4 + SMLATB r14, r6, r9, r14 ; sum = MAC16_16(sum, x_1, y_1) + LDR r8, [r5], #4 + SMLABT r14, r7, r9, r14 ; sum = MAC16_16(sum, x_2, y_2) + SUBS r12, r12, #4 ; j-=4 + SMLATB r14, r7, r8, r14 ; sum = MAC16_16(sum, x_3, y_3) + LDRGT r6, [r4], #4 + BGT celt_pitch_xcorr_edsp_process1u_loop4 + MOV r8, r8, LSR #16 +celt_pitch_xcorr_edsp_process1u_loop4_done + ADDS r12, r12, #4 +celt_pitch_xcorr_edsp_process1u_loop1 + LDRGEH r6, [r4], #2 + ; Stall + SMLABBGE r14, r6, r8, r14 ; sum = MAC16_16(sum, *x, *y) + SUBGES r12, r12, #1 + LDRGTH r8, [r5], #2 + BGT celt_pitch_xcorr_edsp_process1u_loop1 + ; Restore _x + SUB r4, r4, r3, LSL #1 + ; Restore and advance _y + SUB r5, r5, r3, LSL #1 + ; maxcorr = max(maxcorr, sum) + CMP r0, r14 + ADD r5, r5, #2 + MOVLT r0, r14 + SUBS r1, r1, #1 + ; xcorr[i] = sum + STR r14, [r2], #4 + BLE celt_pitch_xcorr_edsp_done +celt_pitch_xcorr_edsp_process1u_done + ; if (max_pitch < 4) goto celt_pitch_xcorr_edsp_process2 + SUBS r1, r1, #4 + BLT celt_pitch_xcorr_edsp_process2 +celt_pitch_xcorr_edsp_process4 + ; xcorr_kernel_edsp parameters: + ; r3 = len, r4 = _x, r5 = _y, r6...r9 = sum[4] = {0, 0, 0, 0} + MOV r6, #0 + MOV r7, #0 + MOV r8, #0 + MOV r9, #0 + BL xcorr_kernel_edsp ; xcorr_kernel_edsp(_x, _y+i, xcorr+i, len) + ; maxcorr = max(maxcorr, sum0, sum1, sum2, sum3) + CMP r0, r6 + ; _y+=4 + ADD r5, r5, #8 + MOVLT r0, r6 + CMP r0, r7 + MOVLT r0, r7 + CMP r0, r8 + MOVLT r0, r8 + CMP r0, r9 + MOVLT r0, r9 + STMIA r2!, {r6-r9} + SUBS r1, r1, #4 + BGE celt_pitch_xcorr_edsp_process4 +celt_pitch_xcorr_edsp_process2 + ADDS r1, r1, #2 + BLT celt_pitch_xcorr_edsp_process1a + SUBS r12, r3, #4 + ; {r10, r11} = {sum0, sum1} = {0, 0} + MOV r10, #0 + MOV r11, #0 + LDR r8, [r5], #4 + BLE celt_pitch_xcorr_edsp_process2_loop_done + LDR r6, [r4], #4 + LDR r9, [r5], #4 +celt_pitch_xcorr_edsp_process2_loop4 + SMLABB r10, r6, r8, r10 ; sum0 = MAC16_16(sum0, x_0, y_0) + LDR r7, [r4], #4 + SMLABT r11, r6, r8, r11 ; sum1 = MAC16_16(sum1, x_0, y_1) + SUBS r12, r12, #4 ; j-=4 + SMLATT r10, r6, r8, r10 ; sum0 = MAC16_16(sum0, x_1, y_1) + LDR r8, [r5], #4 + SMLATB r11, r6, r9, r11 ; sum1 = MAC16_16(sum1, x_1, y_2) + LDRGT r6, [r4], #4 + SMLABB r10, r7, r9, r10 ; sum0 = MAC16_16(sum0, x_2, y_2) + SMLABT r11, r7, r9, r11 ; sum1 = MAC16_16(sum1, x_2, y_3) + SMLATT r10, r7, r9, r10 ; sum0 = MAC16_16(sum0, x_3, y_3) + LDRGT r9, [r5], #4 + SMLATB r11, r7, r8, r11 ; sum1 = MAC16_16(sum1, x_3, y_4) + BGT celt_pitch_xcorr_edsp_process2_loop4 +celt_pitch_xcorr_edsp_process2_loop_done + ADDS r12, r12, #2 + BLE celt_pitch_xcorr_edsp_process2_1 + LDR r6, [r4], #4 + ; Stall + SMLABB r10, r6, r8, r10 ; sum0 = MAC16_16(sum0, x_0, y_0) + LDR r9, [r5], #4 + SMLABT r11, r6, r8, r11 ; sum1 = MAC16_16(sum1, x_0, y_1) + SUB r12, r12, #2 + SMLATT r10, r6, r8, r10 ; sum0 = MAC16_16(sum0, x_1, y_1) + MOV r8, r9 + SMLATB r11, r6, r9, r11 ; sum1 = MAC16_16(sum1, x_1, y_2) +celt_pitch_xcorr_edsp_process2_1 + LDRH r6, [r4], #2 + ADDS r12, r12, #1 + ; Stall + SMLABB r10, r6, r8, r10 ; sum0 = MAC16_16(sum0, x_0, y_0) + LDRGTH r7, [r4], #2 + SMLABT r11, r6, r8, r11 ; sum1 = MAC16_16(sum1, x_0, y_1) + BLE celt_pitch_xcorr_edsp_process2_done + LDRH r9, [r5], #2 + SMLABT r10, r7, r8, r10 ; sum0 = MAC16_16(sum0, x_0, y_1) + SMLABB r11, r7, r9, r11 ; sum1 = MAC16_16(sum1, x_0, y_2) +celt_pitch_xcorr_edsp_process2_done + ; Restore _x + SUB r4, r4, r3, LSL #1 + ; Restore and advance _y + SUB r5, r5, r3, LSL #1 + ; maxcorr = max(maxcorr, sum0) + CMP r0, r10 + ADD r5, r5, #2 + MOVLT r0, r10 + SUB r1, r1, #2 + ; maxcorr = max(maxcorr, sum1) + CMP r0, r11 + ; xcorr[i] = sum + STR r10, [r2], #4 + MOVLT r0, r11 + STR r11, [r2], #4 +celt_pitch_xcorr_edsp_process1a + ADDS r1, r1, #1 + BLT celt_pitch_xcorr_edsp_done + SUBS r12, r3, #4 + ; r14 = sum = 0 + MOV r14, #0 + BLT celt_pitch_xcorr_edsp_process1a_loop_done + LDR r6, [r4], #4 + LDR r8, [r5], #4 + LDR r7, [r4], #4 + LDR r9, [r5], #4 +celt_pitch_xcorr_edsp_process1a_loop4 + SMLABB r14, r6, r8, r14 ; sum = MAC16_16(sum, x_0, y_0) + SUBS r12, r12, #4 ; j-=4 + SMLATT r14, r6, r8, r14 ; sum = MAC16_16(sum, x_1, y_1) + LDRGE r6, [r4], #4 + SMLABB r14, r7, r9, r14 ; sum = MAC16_16(sum, x_2, y_2) + LDRGE r8, [r5], #4 + SMLATT r14, r7, r9, r14 ; sum = MAC16_16(sum, x_3, y_3) + LDRGE r7, [r4], #4 + LDRGE r9, [r5], #4 + BGE celt_pitch_xcorr_edsp_process1a_loop4 +celt_pitch_xcorr_edsp_process1a_loop_done + ADDS r12, r12, #2 + LDRGE r6, [r4], #4 + LDRGE r8, [r5], #4 + ; Stall + SMLABBGE r14, r6, r8, r14 ; sum = MAC16_16(sum, x_0, y_0) + SUBGE r12, r12, #2 + SMLATTGE r14, r6, r8, r14 ; sum = MAC16_16(sum, x_1, y_1) + ADDS r12, r12, #1 + LDRGEH r6, [r4], #2 + LDRGEH r8, [r5], #2 + ; Stall + SMLABBGE r14, r6, r8, r14 ; sum = MAC16_16(sum, *x, *y) + ; maxcorr = max(maxcorr, sum) + CMP r0, r14 + ; xcorr[i] = sum + STR r14, [r2], #4 + MOVLT r0, r14 +celt_pitch_xcorr_edsp_done + LDMFD sp!, {r4-r11, pc} + ENDP + +ENDIF + +END diff --git a/src/opus-1.1/celt/arm/fixed_armv4.h b/src/opus-1.1/celt/arm/fixed_armv4.h new file mode 100644 index 00000000..b690bc8c --- /dev/null +++ b/src/opus-1.1/celt/arm/fixed_armv4.h @@ -0,0 +1,76 @@ +/* Copyright (C) 2013 Xiph.Org Foundation and contributors */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FIXED_ARMv4_H +#define FIXED_ARMv4_H + +/** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */ +#undef MULT16_32_Q16 +static OPUS_INLINE opus_val32 MULT16_32_Q16_armv4(opus_val16 a, opus_val32 b) +{ + unsigned rd_lo; + int rd_hi; + __asm__( + "#MULT16_32_Q16\n\t" + "smull %0, %1, %2, %3\n\t" + : "=&r"(rd_lo), "=&r"(rd_hi) + : "%r"(b),"r"(a<<16) + ); + return rd_hi; +} +#define MULT16_32_Q16(a, b) (MULT16_32_Q16_armv4(a, b)) + + +/** 16x32 multiplication, followed by a 15-bit shift right. Results fits in 32 bits */ +#undef MULT16_32_Q15 +static OPUS_INLINE opus_val32 MULT16_32_Q15_armv4(opus_val16 a, opus_val32 b) +{ + unsigned rd_lo; + int rd_hi; + __asm__( + "#MULT16_32_Q15\n\t" + "smull %0, %1, %2, %3\n\t" + : "=&r"(rd_lo), "=&r"(rd_hi) + : "%r"(b), "r"(a<<16) + ); + /*We intentionally don't OR in the high bit of rd_lo for speed.*/ + return rd_hi<<1; +} +#define MULT16_32_Q15(a, b) (MULT16_32_Q15_armv4(a, b)) + + +/** 16x32 multiply, followed by a 15-bit shift right and 32-bit add. + b must fit in 31 bits. + Result fits in 32 bits. */ +#undef MAC16_32_Q15 +#define MAC16_32_Q15(c, a, b) ADD32(c, MULT16_32_Q15(a, b)) + + +/** 32x32 multiplication, followed by a 31-bit shift right. Results fits in 32 bits */ +#undef MULT32_32_Q31 +#define MULT32_32_Q31(a,b) (opus_val32)((((opus_int64)(a)) * ((opus_int64)(b)))>>31) + +#endif diff --git a/src/opus-1.1/celt/arm/fixed_armv5e.h b/src/opus-1.1/celt/arm/fixed_armv5e.h new file mode 100644 index 00000000..1194a7d3 --- /dev/null +++ b/src/opus-1.1/celt/arm/fixed_armv5e.h @@ -0,0 +1,116 @@ +/* Copyright (C) 2007-2009 Xiph.Org Foundation + Copyright (C) 2003-2008 Jean-Marc Valin + Copyright (C) 2007-2008 CSIRO + Copyright (C) 2013 Parrot */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FIXED_ARMv5E_H +#define FIXED_ARMv5E_H + +#include "fixed_armv4.h" + +/** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */ +#undef MULT16_32_Q16 +static OPUS_INLINE opus_val32 MULT16_32_Q16_armv5e(opus_val16 a, opus_val32 b) +{ + int res; + __asm__( + "#MULT16_32_Q16\n\t" + "smulwb %0, %1, %2\n\t" + : "=r"(res) + : "r"(b),"r"(a) + ); + return res; +} +#define MULT16_32_Q16(a, b) (MULT16_32_Q16_armv5e(a, b)) + + +/** 16x32 multiplication, followed by a 15-bit shift right. Results fits in 32 bits */ +#undef MULT16_32_Q15 +static OPUS_INLINE opus_val32 MULT16_32_Q15_armv5e(opus_val16 a, opus_val32 b) +{ + int res; + __asm__( + "#MULT16_32_Q15\n\t" + "smulwb %0, %1, %2\n\t" + : "=r"(res) + : "r"(b), "r"(a) + ); + return res<<1; +} +#define MULT16_32_Q15(a, b) (MULT16_32_Q15_armv5e(a, b)) + + +/** 16x32 multiply, followed by a 15-bit shift right and 32-bit add. + b must fit in 31 bits. + Result fits in 32 bits. */ +#undef MAC16_32_Q15 +static OPUS_INLINE opus_val32 MAC16_32_Q15_armv5e(opus_val32 c, opus_val16 a, + opus_val32 b) +{ + int res; + __asm__( + "#MAC16_32_Q15\n\t" + "smlawb %0, %1, %2, %3;\n" + : "=r"(res) + : "r"(b<<1), "r"(a), "r"(c) + ); + return res; +} +#define MAC16_32_Q15(c, a, b) (MAC16_32_Q15_armv5e(c, a, b)) + +/** 16x16 multiply-add where the result fits in 32 bits */ +#undef MAC16_16 +static OPUS_INLINE opus_val32 MAC16_16_armv5e(opus_val32 c, opus_val16 a, + opus_val16 b) +{ + int res; + __asm__( + "#MAC16_16\n\t" + "smlabb %0, %1, %2, %3;\n" + : "=r"(res) + : "r"(a), "r"(b), "r"(c) + ); + return res; +} +#define MAC16_16(c, a, b) (MAC16_16_armv5e(c, a, b)) + +/** 16x16 multiplication where the result fits in 32 bits */ +#undef MULT16_16 +static OPUS_INLINE opus_val32 MULT16_16_armv5e(opus_val16 a, opus_val16 b) +{ + int res; + __asm__( + "#MULT16_16\n\t" + "smulbb %0, %1, %2;\n" + : "=r"(res) + : "r"(a), "r"(b) + ); + return res; +} +#define MULT16_16(a, b) (MULT16_16_armv5e(a, b)) + +#endif diff --git a/src/opus-1.1/celt/arm/kiss_fft_armv4.h b/src/opus-1.1/celt/arm/kiss_fft_armv4.h new file mode 100644 index 00000000..e4faad6f --- /dev/null +++ b/src/opus-1.1/celt/arm/kiss_fft_armv4.h @@ -0,0 +1,121 @@ +/*Copyright (c) 2013, Xiph.Org Foundation and contributors. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.*/ + +#ifndef KISS_FFT_ARMv4_H +#define KISS_FFT_ARMv4_H + +#if !defined(KISS_FFT_GUTS_H) +#error "This file should only be included from _kiss_fft_guts.h" +#endif + +#ifdef FIXED_POINT + +#undef C_MUL +#define C_MUL(m,a,b) \ + do{ \ + int br__; \ + int bi__; \ + int tt__; \ + __asm__ __volatile__( \ + "#C_MUL\n\t" \ + "ldrsh %[br], [%[bp], #0]\n\t" \ + "ldm %[ap], {r0,r1}\n\t" \ + "ldrsh %[bi], [%[bp], #2]\n\t" \ + "smull %[tt], %[mi], r1, %[br]\n\t" \ + "smlal %[tt], %[mi], r0, %[bi]\n\t" \ + "rsb %[bi], %[bi], #0\n\t" \ + "smull %[br], %[mr], r0, %[br]\n\t" \ + "mov %[tt], %[tt], lsr #15\n\t" \ + "smlal %[br], %[mr], r1, %[bi]\n\t" \ + "orr %[mi], %[tt], %[mi], lsl #17\n\t" \ + "mov %[br], %[br], lsr #15\n\t" \ + "orr %[mr], %[br], %[mr], lsl #17\n\t" \ + : [mr]"=r"((m).r), [mi]"=r"((m).i), \ + [br]"=&r"(br__), [bi]"=r"(bi__), [tt]"=r"(tt__) \ + : [ap]"r"(&(a)), [bp]"r"(&(b)) \ + : "r0", "r1" \ + ); \ + } \ + while(0) + +#undef C_MUL4 +#define C_MUL4(m,a,b) \ + do{ \ + int br__; \ + int bi__; \ + int tt__; \ + __asm__ __volatile__( \ + "#C_MUL4\n\t" \ + "ldrsh %[br], [%[bp], #0]\n\t" \ + "ldm %[ap], {r0,r1}\n\t" \ + "ldrsh %[bi], [%[bp], #2]\n\t" \ + "smull %[tt], %[mi], r1, %[br]\n\t" \ + "smlal %[tt], %[mi], r0, %[bi]\n\t" \ + "rsb %[bi], %[bi], #0\n\t" \ + "smull %[br], %[mr], r0, %[br]\n\t" \ + "mov %[tt], %[tt], lsr #17\n\t" \ + "smlal %[br], %[mr], r1, %[bi]\n\t" \ + "orr %[mi], %[tt], %[mi], lsl #15\n\t" \ + "mov %[br], %[br], lsr #17\n\t" \ + "orr %[mr], %[br], %[mr], lsl #15\n\t" \ + : [mr]"=r"((m).r), [mi]"=r"((m).i), \ + [br]"=&r"(br__), [bi]"=r"(bi__), [tt]"=r"(tt__) \ + : [ap]"r"(&(a)), [bp]"r"(&(b)) \ + : "r0", "r1" \ + ); \ + } \ + while(0) + +#undef C_MULC +#define C_MULC(m,a,b) \ + do{ \ + int br__; \ + int bi__; \ + int tt__; \ + __asm__ __volatile__( \ + "#C_MULC\n\t" \ + "ldrsh %[br], [%[bp], #0]\n\t" \ + "ldm %[ap], {r0,r1}\n\t" \ + "ldrsh %[bi], [%[bp], #2]\n\t" \ + "smull %[tt], %[mr], r0, %[br]\n\t" \ + "smlal %[tt], %[mr], r1, %[bi]\n\t" \ + "rsb %[bi], %[bi], #0\n\t" \ + "smull %[br], %[mi], r1, %[br]\n\t" \ + "mov %[tt], %[tt], lsr #15\n\t" \ + "smlal %[br], %[mi], r0, %[bi]\n\t" \ + "orr %[mr], %[tt], %[mr], lsl #17\n\t" \ + "mov %[br], %[br], lsr #15\n\t" \ + "orr %[mi], %[br], %[mi], lsl #17\n\t" \ + : [mr]"=r"((m).r), [mi]"=r"((m).i), \ + [br]"=&r"(br__), [bi]"=r"(bi__), [tt]"=r"(tt__) \ + : [ap]"r"(&(a)), [bp]"r"(&(b)) \ + : "r0", "r1" \ + ); \ + } \ + while(0) + +#endif /* FIXED_POINT */ + +#endif /* KISS_FFT_ARMv4_H */ diff --git a/src/opus-1.1/celt/arm/kiss_fft_armv5e.h b/src/opus-1.1/celt/arm/kiss_fft_armv5e.h new file mode 100644 index 00000000..9eca183d --- /dev/null +++ b/src/opus-1.1/celt/arm/kiss_fft_armv5e.h @@ -0,0 +1,118 @@ +/*Copyright (c) 2013, Xiph.Org Foundation and contributors. + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.*/ + +#ifndef KISS_FFT_ARMv5E_H +#define KISS_FFT_ARMv5E_H + +#if !defined(KISS_FFT_GUTS_H) +#error "This file should only be included from _kiss_fft_guts.h" +#endif + +#ifdef FIXED_POINT + +#if defined(__thumb__)||defined(__thumb2__) +#define LDRD_CONS "Q" +#else +#define LDRD_CONS "Uq" +#endif + +#undef C_MUL +#define C_MUL(m,a,b) \ + do{ \ + int mr1__; \ + int mr2__; \ + int mi__; \ + long long aval__; \ + int bval__; \ + __asm__( \ + "#C_MUL\n\t" \ + "ldrd %[aval], %H[aval], %[ap]\n\t" \ + "ldr %[bval], %[bp]\n\t" \ + "smulwb %[mi], %H[aval], %[bval]\n\t" \ + "smulwb %[mr1], %[aval], %[bval]\n\t" \ + "smulwt %[mr2], %H[aval], %[bval]\n\t" \ + "smlawt %[mi], %[aval], %[bval], %[mi]\n\t" \ + : [mr1]"=r"(mr1__), [mr2]"=r"(mr2__), [mi]"=r"(mi__), \ + [aval]"=&r"(aval__), [bval]"=r"(bval__) \ + : [ap]LDRD_CONS(a), [bp]"m"(b) \ + ); \ + (m).r = SHL32(SUB32(mr1__, mr2__), 1); \ + (m).i = SHL32(mi__, 1); \ + } \ + while(0) + +#undef C_MUL4 +#define C_MUL4(m,a,b) \ + do{ \ + int mr1__; \ + int mr2__; \ + int mi__; \ + long long aval__; \ + int bval__; \ + __asm__( \ + "#C_MUL4\n\t" \ + "ldrd %[aval], %H[aval], %[ap]\n\t" \ + "ldr %[bval], %[bp]\n\t" \ + "smulwb %[mi], %H[aval], %[bval]\n\t" \ + "smulwb %[mr1], %[aval], %[bval]\n\t" \ + "smulwt %[mr2], %H[aval], %[bval]\n\t" \ + "smlawt %[mi], %[aval], %[bval], %[mi]\n\t" \ + : [mr1]"=r"(mr1__), [mr2]"=r"(mr2__), [mi]"=r"(mi__), \ + [aval]"=&r"(aval__), [bval]"=r"(bval__) \ + : [ap]LDRD_CONS(a), [bp]"m"(b) \ + ); \ + (m).r = SHR32(SUB32(mr1__, mr2__), 1); \ + (m).i = SHR32(mi__, 1); \ + } \ + while(0) + +#undef C_MULC +#define C_MULC(m,a,b) \ + do{ \ + int mr__; \ + int mi1__; \ + int mi2__; \ + long long aval__; \ + int bval__; \ + __asm__( \ + "#C_MULC\n\t" \ + "ldrd %[aval], %H[aval], %[ap]\n\t" \ + "ldr %[bval], %[bp]\n\t" \ + "smulwb %[mr], %[aval], %[bval]\n\t" \ + "smulwb %[mi1], %H[aval], %[bval]\n\t" \ + "smulwt %[mi2], %[aval], %[bval]\n\t" \ + "smlawt %[mr], %H[aval], %[bval], %[mr]\n\t" \ + : [mr]"=r"(mr__), [mi1]"=r"(mi1__), [mi2]"=r"(mi2__), \ + [aval]"=&r"(aval__), [bval]"=r"(bval__) \ + : [ap]LDRD_CONS(a), [bp]"m"(b) \ + ); \ + (m).r = SHL32(mr__, 1); \ + (m).i = SHL32(SUB32(mi1__, mi2__), 1); \ + } \ + while(0) + +#endif /* FIXED_POINT */ + +#endif /* KISS_FFT_GUTS_H */ diff --git a/src/opus-1.1/celt/arm/pitch_arm.h b/src/opus-1.1/celt/arm/pitch_arm.h new file mode 100644 index 00000000..a07f8ac2 --- /dev/null +++ b/src/opus-1.1/celt/arm/pitch_arm.h @@ -0,0 +1,57 @@ +/* Copyright (c) 2010 Xiph.Org Foundation + * Copyright (c) 2013 Parrot */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#if !defined(PITCH_ARM_H) +# define PITCH_ARM_H + +# include "armcpu.h" + +# if defined(FIXED_POINT) + +# if defined(OPUS_ARM_MAY_HAVE_NEON) +opus_val32 celt_pitch_xcorr_neon(const opus_val16 *_x, const opus_val16 *_y, + opus_val32 *xcorr, int len, int max_pitch); +# endif + +# if defined(OPUS_ARM_MAY_HAVE_MEDIA) +# define celt_pitch_xcorr_media MAY_HAVE_EDSP(celt_pitch_xcorr) +# endif + +# if defined(OPUS_ARM_MAY_HAVE_EDSP) +opus_val32 celt_pitch_xcorr_edsp(const opus_val16 *_x, const opus_val16 *_y, + opus_val32 *xcorr, int len, int max_pitch); +# endif + +# if !defined(OPUS_HAVE_RTCD) +# define OVERRIDE_PITCH_XCORR (1) +# define celt_pitch_xcorr(_x, _y, xcorr, len, max_pitch, arch) \ + ((void)(arch),PRESUME_NEON(celt_pitch_xcorr)(_x, _y, xcorr, len, max_pitch)) +# endif + +# endif + +#endif diff --git a/src/opus-1.1/celt/bands.c b/src/opus-1.1/celt/bands.c new file mode 100644 index 00000000..cce56e2f --- /dev/null +++ b/src/opus-1.1/celt/bands.c @@ -0,0 +1,1518 @@ +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation + Copyright (c) 2008-2009 Gregory Maxwell + Written by Jean-Marc Valin and Gregory Maxwell */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "bands.h" +#include "modes.h" +#include "vq.h" +#include "cwrs.h" +#include "stack_alloc.h" +#include "os_support.h" +#include "mathops.h" +#include "rate.h" +#include "quant_bands.h" +#include "pitch.h" + +int hysteresis_decision(opus_val16 val, const opus_val16 *thresholds, const opus_val16 *hysteresis, int N, int prev) +{ + int i; + for (i=0;iprev && val < thresholds[prev]+hysteresis[prev]) + i=prev; + if (i thresholds[prev-1]-hysteresis[prev-1]) + i=prev; + return i; +} + +opus_uint32 celt_lcg_rand(opus_uint32 seed) +{ + return 1664525 * seed + 1013904223; +} + +/* This is a cos() approximation designed to be bit-exact on any platform. Bit exactness + with this approximation is important because it has an impact on the bit allocation */ +static opus_int16 bitexact_cos(opus_int16 x) +{ + opus_int32 tmp; + opus_int16 x2; + tmp = (4096+((opus_int32)(x)*(x)))>>13; + celt_assert(tmp<=32767); + x2 = tmp; + x2 = (32767-x2) + FRAC_MUL16(x2, (-7651 + FRAC_MUL16(x2, (8277 + FRAC_MUL16(-626, x2))))); + celt_assert(x2<=32766); + return 1+x2; +} + +static int bitexact_log2tan(int isin,int icos) +{ + int lc; + int ls; + lc=EC_ILOG(icos); + ls=EC_ILOG(isin); + icos<<=15-lc; + isin<<=15-ls; + return (ls-lc)*(1<<11) + +FRAC_MUL16(isin, FRAC_MUL16(isin, -2597) + 7932) + -FRAC_MUL16(icos, FRAC_MUL16(icos, -2597) + 7932); +} + +#ifdef FIXED_POINT +/* Compute the amplitude (sqrt energy) in each of the bands */ +void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int M) +{ + int i, c, N; + const opus_int16 *eBands = m->eBands; + N = M*m->shortMdctSize; + c=0; do { + for (i=0;i 0) + { + int shift = celt_ilog2(maxval)-10; + j=M*eBands[i]; do { + sum = MAC16_16(sum, EXTRACT16(VSHR32(X[j+c*N],shift)), + EXTRACT16(VSHR32(X[j+c*N],shift))); + } while (++jnbEBands] = EPSILON+VSHR32(EXTEND32(celt_sqrt(sum)),-shift); + } else { + bandE[i+c*m->nbEBands] = EPSILON; + } + /*printf ("%f ", bandE[i+c*m->nbEBands]);*/ + } + } while (++ceBands; + N = M*m->shortMdctSize; + c=0; do { + i=0; do { + opus_val16 g; + int j,shift; + opus_val16 E; + shift = celt_zlog2(bandE[i+c*m->nbEBands])-13; + E = VSHR32(bandE[i+c*m->nbEBands], shift); + g = EXTRACT16(celt_rcp(SHL32(E,3))); + j=M*eBands[i]; do { + X[j+c*N] = MULT16_16_Q15(VSHR32(freq[j+c*N],shift-1),g); + } while (++jeBands; + N = M*m->shortMdctSize; + c=0; do { + for (i=0;inbEBands] = celt_sqrt(sum); + /*printf ("%f ", bandE[i+c*m->nbEBands]);*/ + } + } while (++ceBands; + N = M*m->shortMdctSize; + c=0; do { + for (i=0;inbEBands]); + for (j=M*eBands[i];jeBands; + N = M*m->shortMdctSize; + celt_assert2(C<=2, "denormalise_bands() not implemented for >2 channels"); + c=0; do { + celt_sig * OPUS_RESTRICT f; + const celt_norm * OPUS_RESTRICT x; + f = freq+c*N; + x = X+c*N+M*eBands[start]; + for (i=0;inbEBands], SHL16((opus_val16)eMeans[i],6)); +#ifndef FIXED_POINT + g = celt_exp2(lg); +#else + /* Handle the integer part of the log energy */ + shift = 16-(lg>>DB_SHIFT); + if (shift>31) + { + shift=0; + g=0; + } else { + /* Handle the fractional part. */ + g = celt_exp2_frac(lg&((1<eBands[i+1]-m->eBands[i]; + /* depth in 1/8 bits */ + depth = (1+pulses[i])/((m->eBands[i+1]-m->eBands[i])<>1; + t = SHL32(t, (7-shift)<<1); + sqrt_1 = celt_rsqrt_norm(t); + } +#else + thresh = .5f*celt_exp2(-.125f*depth); + sqrt_1 = celt_rsqrt(N0<nbEBands+i]; + prev2 = prev2logE[c*m->nbEBands+i]; + if (C==1) + { + prev1 = MAX16(prev1,prev1logE[m->nbEBands+i]); + prev2 = MAX16(prev2,prev2logE[m->nbEBands+i]); + } + Ediff = EXTEND32(logE[c*m->nbEBands+i])-EXTEND32(MIN16(prev1,prev2)); + Ediff = MAX32(0, Ediff); + +#ifdef FIXED_POINT + if (Ediff < 16384) + { + opus_val32 r32 = SHR32(celt_exp2(-EXTRACT16(Ediff)),1); + r = 2*MIN16(16383,r32); + } else { + r = 0; + } + if (LM==3) + r = MULT16_16_Q14(23170, MIN32(23169, r)); + r = SHR16(MIN16(thresh, r),1); + r = SHR32(MULT16_16_Q15(sqrt_1, r),shift); +#else + /* r needs to be multiplied by 2 or 2*sqrt(2) depending on LM because + short blocks don't have the same energy as long */ + r = 2.f*celt_exp2(-Ediff); + if (LM==3) + r *= 1.41421356f; + r = MIN16(thresh, r); + r = r*sqrt_1; +#endif + X = X_+c*size+(m->eBands[i]<nbEBands]))-13; +#endif + left = VSHR32(bandE[i],shift); + right = VSHR32(bandE[i+m->nbEBands],shift); + norm = EPSILON + celt_sqrt(EPSILON+MULT16_16(left,left)+MULT16_16(right,right)); + a1 = DIV32_16(SHL32(EXTEND32(left),14),norm); + a2 = DIV32_16(SHL32(EXTEND32(right),14),norm); + for (j=0;j>1; + kr = celt_ilog2(Er)>>1; +#endif + t = VSHR32(El, (kl-7)<<1); + lgain = celt_rsqrt_norm(t); + t = VSHR32(Er, (kr-7)<<1); + rgain = celt_rsqrt_norm(t); + +#ifdef FIXED_POINT + if (kl < 7) + kl = 7; + if (kr < 7) + kr = 7; +#endif + + for (j=0;jeBands; + int decision; + int hf_sum=0; + + celt_assert(end>0); + + N0 = M*m->shortMdctSize; + + if (M*(eBands[end]-eBands[end-1]) <= 8) + return SPREAD_NONE; + c=0; do { + for (i=0;im->nbEBands-4) + hf_sum += 32*(tcount[1]+tcount[0])/N; + tmp = (2*tcount[2] >= N) + (2*tcount[1] >= N) + (2*tcount[0] >= N); + sum += tmp*256; + nbBands++; + } + } while (++cnbEBands+end); + *hf_average = (*hf_average+hf_sum)>>1; + hf_sum = *hf_average; + if (*tapset_decision==2) + hf_sum += 4; + else if (*tapset_decision==0) + hf_sum -= 4; + if (hf_sum > 22) + *tapset_decision=2; + else if (hf_sum > 18) + *tapset_decision=1; + else + *tapset_decision=0; + } + /*printf("%d %d %d\n", hf_sum, *hf_average, *tapset_decision);*/ + celt_assert(nbBands>0); /* end has to be non-zero */ + sum /= nbBands; + /* Recursive averaging */ + sum = (sum+*average)>>1; + *average = sum; + /* Hysteresis */ + sum = (3*sum + (((3-last_decision)<<7) + 64) + 2)>>2; + if (sum < 80) + { + decision = SPREAD_AGGRESSIVE; + } else if (sum < 256) + { + decision = SPREAD_NORMAL; + } else if (sum < 384) + { + decision = SPREAD_LIGHT; + } else { + decision = SPREAD_NONE; + } +#ifdef FUZZING + decision = rand()&0x3; + *tapset_decision=rand()%3; +#endif + return decision; +} + +/* Indexing table for converting from natural Hadamard to ordery Hadamard + This is essentially a bit-reversed Gray, on top of which we've added + an inversion of the order because we want the DC at the end rather than + the beginning. The lines are for N=2, 4, 8, 16 */ +static const int ordery_table[] = { + 1, 0, + 3, 0, 2, 1, + 7, 0, 4, 3, 6, 1, 5, 2, + 15, 0, 8, 7, 12, 3, 11, 4, 14, 1, 9, 6, 13, 2, 10, 5, +}; + +static void deinterleave_hadamard(celt_norm *X, int N0, int stride, int hadamard) +{ + int i,j; + VARDECL(celt_norm, tmp); + int N; + SAVE_STACK; + N = N0*stride; + ALLOC(tmp, N, celt_norm); + celt_assert(stride>0); + if (hadamard) + { + const int *ordery = ordery_table+stride-2; + for (i=0;i>= 1; + for (i=0;i>1)) { + qn = 1; + } else { + qn = exp2_table8[qb&0x7]>>(14-(qb>>BITRES)); + qn = (qn+1)>>1<<1; + } + celt_assert(qn <= 256); + return qn; +} + +struct band_ctx { + int encode; + const CELTMode *m; + int i; + int intensity; + int spread; + int tf_change; + ec_ctx *ec; + opus_int32 remaining_bits; + const celt_ener *bandE; + opus_uint32 seed; +}; + +struct split_ctx { + int inv; + int imid; + int iside; + int delta; + int itheta; + int qalloc; +}; + +static void compute_theta(struct band_ctx *ctx, struct split_ctx *sctx, + celt_norm *X, celt_norm *Y, int N, int *b, int B, int B0, + int LM, + int stereo, int *fill) +{ + int qn; + int itheta=0; + int delta; + int imid, iside; + int qalloc; + int pulse_cap; + int offset; + opus_int32 tell; + int inv=0; + int encode; + const CELTMode *m; + int i; + int intensity; + ec_ctx *ec; + const celt_ener *bandE; + + encode = ctx->encode; + m = ctx->m; + i = ctx->i; + intensity = ctx->intensity; + ec = ctx->ec; + bandE = ctx->bandE; + + /* Decide on the resolution to give to the split parameter theta */ + pulse_cap = m->logN[i]+LM*(1<>1) - (stereo&&N==2 ? QTHETA_OFFSET_TWOPHASE : QTHETA_OFFSET); + qn = compute_qn(N, *b, offset, pulse_cap, stereo); + if (stereo && i>=intensity) + qn = 1; + if (encode) + { + /* theta is the atan() of the ratio between the (normalized) + side and mid. With just that parameter, we can re-scale both + mid and side because we know that 1) they have unit norm and + 2) they are orthogonal. */ + itheta = stereo_itheta(X, Y, stereo, N); + } + tell = ec_tell_frac(ec); + if (qn!=1) + { + if (encode) + itheta = (itheta*qn+8192)>>14; + + /* Entropy coding of the angle. We use a uniform pdf for the + time split, a step for stereo, and a triangular one for the rest. */ + if (stereo && N>2) + { + int p0 = 3; + int x = itheta; + int x0 = qn/2; + int ft = p0*(x0+1) + x0; + /* Use a probability of p0 up to itheta=8192 and then use 1 after */ + if (encode) + { + ec_encode(ec,x<=x0?p0*x:(x-1-x0)+(x0+1)*p0,x<=x0?p0*(x+1):(x-x0)+(x0+1)*p0,ft); + } else { + int fs; + fs=ec_decode(ec,ft); + if (fs<(x0+1)*p0) + x=fs/p0; + else + x=x0+1+(fs-(x0+1)*p0); + ec_dec_update(ec,x<=x0?p0*x:(x-1-x0)+(x0+1)*p0,x<=x0?p0*(x+1):(x-x0)+(x0+1)*p0,ft); + itheta = x; + } + } else if (B0>1 || stereo) { + /* Uniform pdf */ + if (encode) + ec_enc_uint(ec, itheta, qn+1); + else + itheta = ec_dec_uint(ec, qn+1); + } else { + int fs=1, ft; + ft = ((qn>>1)+1)*((qn>>1)+1); + if (encode) + { + int fl; + + fs = itheta <= (qn>>1) ? itheta + 1 : qn + 1 - itheta; + fl = itheta <= (qn>>1) ? itheta*(itheta + 1)>>1 : + ft - ((qn + 1 - itheta)*(qn + 2 - itheta)>>1); + + ec_encode(ec, fl, fl+fs, ft); + } else { + /* Triangular pdf */ + int fl=0; + int fm; + fm = ec_decode(ec, ft); + + if (fm < ((qn>>1)*((qn>>1) + 1)>>1)) + { + itheta = (isqrt32(8*(opus_uint32)fm + 1) - 1)>>1; + fs = itheta + 1; + fl = itheta*(itheta + 1)>>1; + } + else + { + itheta = (2*(qn + 1) + - isqrt32(8*(opus_uint32)(ft - fm - 1) + 1))>>1; + fs = qn + 1 - itheta; + fl = ft - ((qn + 1 - itheta)*(qn + 2 - itheta)>>1); + } + + ec_dec_update(ec, fl, fl+fs, ft); + } + } + itheta = (opus_int32)itheta*16384/qn; + if (encode && stereo) + { + if (itheta==0) + intensity_stereo(m, X, Y, bandE, i, N); + else + stereo_split(X, Y, N); + } + /* NOTE: Renormalising X and Y *may* help fixed-point a bit at very high rate. + Let's do that at higher complexity */ + } else if (stereo) { + if (encode) + { + inv = itheta > 8192; + if (inv) + { + int j; + for (j=0;j2<remaining_bits > 2<inv = inv; + sctx->imid = imid; + sctx->iside = iside; + sctx->delta = delta; + sctx->itheta = itheta; + sctx->qalloc = qalloc; +} +static unsigned quant_band_n1(struct band_ctx *ctx, celt_norm *X, celt_norm *Y, int b, + celt_norm *lowband_out) +{ +#ifdef RESYNTH + int resynth = 1; +#else + int resynth = !ctx->encode; +#endif + int c; + int stereo; + celt_norm *x = X; + int encode; + ec_ctx *ec; + + encode = ctx->encode; + ec = ctx->ec; + + stereo = Y != NULL; + c=0; do { + int sign=0; + if (ctx->remaining_bits>=1<remaining_bits -= 1<encode; +#endif + celt_norm *Y=NULL; + int encode; + const CELTMode *m; + int i; + int spread; + ec_ctx *ec; + + encode = ctx->encode; + m = ctx->m; + i = ctx->i; + spread = ctx->spread; + ec = ctx->ec; + + /* If we need 1.5 more bit than we can produce, split the band in two. */ + cache = m->cache.bits + m->cache.index[(LM+1)*m->nbEBands+i]; + if (LM != -1 && b > cache[cache[0]]+12 && N>2) + { + int mbits, sbits, delta; + int itheta; + int qalloc; + struct split_ctx sctx; + celt_norm *next_lowband2=NULL; + opus_int32 rebalance; + + N >>= 1; + Y = X+N; + LM -= 1; + if (B==1) + fill = (fill&1)|(fill<<1); + B = (B+1)>>1; + + compute_theta(ctx, &sctx, X, Y, N, &b, B, B0, + LM, 0, &fill); + imid = sctx.imid; + iside = sctx.iside; + delta = sctx.delta; + itheta = sctx.itheta; + qalloc = sctx.qalloc; +#ifdef FIXED_POINT + mid = imid; + side = iside; +#else + mid = (1.f/32768)*imid; + side = (1.f/32768)*iside; +#endif + + /* Give more bits to low-energy MDCTs than they would otherwise deserve */ + if (B0>1 && (itheta&0x3fff)) + { + if (itheta > 8192) + /* Rough approximation for pre-echo masking */ + delta -= delta>>(4-LM); + else + /* Corresponds to a forward-masking slope of 1.5 dB per 10 ms */ + delta = IMIN(0, delta + (N<>(5-LM))); + } + mbits = IMAX(0, IMIN(b, (b-delta)/2)); + sbits = b-mbits; + ctx->remaining_bits -= qalloc; + + if (lowband) + next_lowband2 = lowband+N; /* >32-bit split case */ + + rebalance = ctx->remaining_bits; + if (mbits >= sbits) + { + cm = quant_partition(ctx, X, N, mbits, B, + lowband, LM, + MULT16_16_P15(gain,mid), fill); + rebalance = mbits - (rebalance-ctx->remaining_bits); + if (rebalance > 3<>B)<<(B0>>1); + } else { + cm = quant_partition(ctx, Y, N, sbits, B, + next_lowband2, LM, + MULT16_16_P15(gain,side), fill>>B)<<(B0>>1); + rebalance = sbits - (rebalance-ctx->remaining_bits); + if (rebalance > 3<remaining_bits -= curr_bits; + + /* Ensures we can never bust the budget */ + while (ctx->remaining_bits < 0 && q > 0) + { + ctx->remaining_bits += curr_bits; + q--; + curr_bits = pulses2bits(m, i, LM, q); + ctx->remaining_bits -= curr_bits; + } + + if (q!=0) + { + int K = get_pulses(q); + + /* Finally do the actual quantization */ + if (encode) + { + cm = alg_quant(X, N, K, spread, B, ec +#ifdef RESYNTH + , gain +#endif + ); + } else { + cm = alg_unquant(X, N, K, spread, B, ec, gain); + } + } else { + /* If there's no pulse, fill the band anyway */ + int j; + if (resynth) + { + unsigned cm_mask; + /* B can be as large as 16, so this shift might overflow an int on a + 16-bit platform; use a long to get defined behavior.*/ + cm_mask = (unsigned)(1UL<seed = celt_lcg_rand(ctx->seed); + X[j] = (celt_norm)((opus_int32)ctx->seed>>20); + } + cm = cm_mask; + } else { + /* Folded spectrum */ + for (j=0;jseed = celt_lcg_rand(ctx->seed); + /* About 48 dB below the "normal" folding level */ + tmp = QCONST16(1.0f/256, 10); + tmp = (ctx->seed)&0x8000 ? tmp : -tmp; + X[j] = lowband[j]+tmp; + } + cm = fill; + } + renormalise_vector(X, N, gain); + } + } + } + } + + return cm; +} + + +/* This function is responsible for encoding and decoding a band for the mono case. */ +static unsigned quant_band(struct band_ctx *ctx, celt_norm *X, + int N, int b, int B, celt_norm *lowband, + int LM, celt_norm *lowband_out, + opus_val16 gain, celt_norm *lowband_scratch, int fill) +{ + int N0=N; + int N_B=N; + int N_B0; + int B0=B; + int time_divide=0; + int recombine=0; + int longBlocks; + unsigned cm=0; +#ifdef RESYNTH + int resynth = 1; +#else + int resynth = !ctx->encode; +#endif + int k; + int encode; + int tf_change; + + encode = ctx->encode; + tf_change = ctx->tf_change; + + longBlocks = B0==1; + + N_B /= B; + + /* Special case for one sample */ + if (N==1) + { + return quant_band_n1(ctx, X, NULL, b, lowband_out); + } + + if (tf_change>0) + recombine = tf_change; + /* Band recombining to increase frequency resolution */ + + if (lowband_scratch && lowband && (recombine || ((N_B&1) == 0 && tf_change<0) || B0>1)) + { + int j; + for (j=0;j>k, 1<>k, 1<>4]<<2; + } + B>>=recombine; + N_B<<=recombine; + + /* Increasing the time resolution */ + while ((N_B&1) == 0 && tf_change<0) + { + if (encode) + haar1(X, N_B, B); + if (lowband) + haar1(lowband, N_B, B); + fill |= fill<>= 1; + time_divide++; + tf_change++; + } + B0=B; + N_B0 = N_B; + + /* Reorganize the samples in time order instead of frequency order */ + if (B0>1) + { + if (encode) + deinterleave_hadamard(X, N_B>>recombine, B0<>recombine, B0<1) + interleave_hadamard(X, N_B>>recombine, B0<>= 1; + N_B <<= 1; + cm |= cm>>B; + haar1(X, N_B, B); + } + + for (k=0;k>k, 1<encode; +#endif + int mbits, sbits, delta; + int itheta; + int qalloc; + struct split_ctx sctx; + int orig_fill; + int encode; + ec_ctx *ec; + + encode = ctx->encode; + ec = ctx->ec; + + /* Special case for one sample */ + if (N==1) + { + return quant_band_n1(ctx, X, Y, b, lowband_out); + } + + orig_fill = fill; + + compute_theta(ctx, &sctx, X, Y, N, &b, B, B, + LM, 1, &fill); + inv = sctx.inv; + imid = sctx.imid; + iside = sctx.iside; + delta = sctx.delta; + itheta = sctx.itheta; + qalloc = sctx.qalloc; +#ifdef FIXED_POINT + mid = imid; + side = iside; +#else + mid = (1.f/32768)*imid; + side = (1.f/32768)*iside; +#endif + + /* This is a special case for N=2 that only works for stereo and takes + advantage of the fact that mid and side are orthogonal to encode + the side with just one bit. */ + if (N==2) + { + int c; + int sign=0; + celt_norm *x2, *y2; + mbits = b; + sbits = 0; + /* Only need one bit for the side. */ + if (itheta != 0 && itheta != 16384) + sbits = 1< 8192; + ctx->remaining_bits -= qalloc+sbits; + + x2 = c ? Y : X; + y2 = c ? X : Y; + if (sbits) + { + if (encode) + { + /* Here we only need to encode a sign for the side. */ + sign = x2[0]*y2[1] - x2[1]*y2[0] < 0; + ec_enc_bits(ec, sign, 1); + } else { + sign = ec_dec_bits(ec, 1); + } + } + sign = 1-2*sign; + /* We use orig_fill here because we want to fold the side, but if + itheta==16384, we'll have cleared the low bits of fill. */ + cm = quant_band(ctx, x2, N, mbits, B, lowband, + LM, lowband_out, Q15ONE, lowband_scratch, orig_fill); + /* We don't split N=2 bands, so cm is either 1 or 0 (for a fold-collapse), + and there's no need to worry about mixing with the other channel. */ + y2[0] = -sign*x2[1]; + y2[1] = sign*x2[0]; + if (resynth) + { + celt_norm tmp; + X[0] = MULT16_16_Q15(mid, X[0]); + X[1] = MULT16_16_Q15(mid, X[1]); + Y[0] = MULT16_16_Q15(side, Y[0]); + Y[1] = MULT16_16_Q15(side, Y[1]); + tmp = X[0]; + X[0] = SUB16(tmp,Y[0]); + Y[0] = ADD16(tmp,Y[0]); + tmp = X[1]; + X[1] = SUB16(tmp,Y[1]); + Y[1] = ADD16(tmp,Y[1]); + } + } else { + /* "Normal" split code */ + opus_int32 rebalance; + + mbits = IMAX(0, IMIN(b, (b-delta)/2)); + sbits = b-mbits; + ctx->remaining_bits -= qalloc; + + rebalance = ctx->remaining_bits; + if (mbits >= sbits) + { + /* In stereo mode, we do not apply a scaling to the mid because we need the normalized + mid for folding later. */ + cm = quant_band(ctx, X, N, mbits, B, + lowband, LM, lowband_out, + Q15ONE, lowband_scratch, fill); + rebalance = mbits - (rebalance-ctx->remaining_bits); + if (rebalance > 3<>B); + } else { + /* For a stereo split, the high bits of fill are always zero, so no + folding will be done to the side. */ + cm = quant_band(ctx, Y, N, sbits, B, + NULL, LM, NULL, + side, NULL, fill>>B); + rebalance = sbits - (rebalance-ctx->remaining_bits); + if (rebalance > 3<eBands; + celt_norm * OPUS_RESTRICT norm, * OPUS_RESTRICT norm2; + VARDECL(celt_norm, _norm); + celt_norm *lowband_scratch; + int B; + int M; + int lowband_offset; + int update_lowband = 1; + int C = Y_ != NULL ? 2 : 1; + int norm_offset; +#ifdef RESYNTH + int resynth = 1; +#else + int resynth = !encode; +#endif + struct band_ctx ctx; + SAVE_STACK; + + M = 1<nbEBands-1]-norm_offset), celt_norm); + norm = _norm; + norm2 = norm + M*eBands[m->nbEBands-1]-norm_offset; + /* We can use the last band as scratch space because we don't need that + scratch space for the last band. */ + lowband_scratch = X_+M*eBands[m->nbEBands-1]; + + lowband_offset = 0; + ctx.bandE = bandE; + ctx.ec = ec; + ctx.encode = encode; + ctx.intensity = intensity; + ctx.m = m; + ctx.seed = *seed; + ctx.spread = spread; + for (i=start;i= M*eBands[start] && (update_lowband || lowband_offset==0)) + lowband_offset = i; + + tf_change = tf_res[i]; + ctx.tf_change = tf_change; + if (i>=m->effEBands) + { + X=norm; + if (Y_!=NULL) + Y = norm; + lowband_scratch = NULL; + } + if (i==end-1) + lowband_scratch = NULL; + + /* Get a conservative estimate of the collapse_mask's for the bands we're + going to be folding from. */ + if (lowband_offset != 0 && (spread!=SPREAD_AGGRESSIVE || B>1 || tf_change<0)) + { + int fold_start; + int fold_end; + int fold_i; + /* This ensures we never repeat spectral content within one band */ + effective_lowband = IMAX(0, M*eBands[lowband_offset]-norm_offset-N); + fold_start = lowband_offset; + while(M*eBands[--fold_start] > effective_lowband+norm_offset); + fold_end = lowband_offset-1; + while(M*eBands[++fold_end] < effective_lowband+norm_offset+N); + x_cm = y_cm = 0; + fold_i = fold_start; do { + x_cm |= collapse_masks[fold_i*C+0]; + y_cm |= collapse_masks[fold_i*C+C-1]; + } while (++fold_i(N< +#include "celt.h" +#include "pitch.h" +#include "bands.h" +#include "modes.h" +#include "entcode.h" +#include "quant_bands.h" +#include "rate.h" +#include "stack_alloc.h" +#include "mathops.h" +#include "float_cast.h" +#include +#include "celt_lpc.h" +#include "vq.h" + +#ifndef PACKAGE_VERSION +#define PACKAGE_VERSION "unknown" +#endif + + +int resampling_factor(opus_int32 rate) +{ + int ret; + switch (rate) + { + case 48000: + ret = 1; + break; + case 24000: + ret = 2; + break; + case 16000: + ret = 3; + break; + case 12000: + ret = 4; + break; + case 8000: + ret = 6; + break; + default: +#ifndef CUSTOM_MODES + celt_assert(0); +#endif + ret = 0; + break; + } + return ret; +} + +#ifndef OVERRIDE_COMB_FILTER_CONST +static void comb_filter_const(opus_val32 *y, opus_val32 *x, int T, int N, + opus_val16 g10, opus_val16 g11, opus_val16 g12) +{ + opus_val32 x0, x1, x2, x3, x4; + int i; + x4 = x[-T-2]; + x3 = x[-T-1]; + x2 = x[-T]; + x1 = x[-T+1]; + for (i=0;inbEBands;i++) + { + int N; + N=(m->eBands[i+1]-m->eBands[i])<cache.caps[m->nbEBands*(2*LM+C-1)+i]+64)*C*N>>2; + } +} + + + +const char *opus_strerror(int error) +{ + static const char * const error_strings[8] = { + "success", + "invalid argument", + "buffer too small", + "internal error", + "corrupted stream", + "request not implemented", + "invalid state", + "memory allocation failed" + }; + if (error > 0 || error < -7) + return "unknown error"; + else + return error_strings[-error]; +} + +const char *opus_get_version_string(void) +{ + return "libopus " PACKAGE_VERSION +#ifdef FIXED_POINT + "-fixed" +#endif +#ifdef FUZZING + "-fuzzing" +#endif + ; +} diff --git a/src/opus-1.1/celt/celt.h b/src/opus-1.1/celt/celt.h new file mode 100644 index 00000000..5deea1f0 --- /dev/null +++ b/src/opus-1.1/celt/celt.h @@ -0,0 +1,218 @@ +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation + Copyright (c) 2008 Gregory Maxwell + Written by Jean-Marc Valin and Gregory Maxwell */ +/** + @file celt.h + @brief Contains all the functions for encoding and decoding audio + */ + +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef CELT_H +#define CELT_H + +#include "opus_types.h" +#include "opus_defines.h" +#include "opus_custom.h" +#include "entenc.h" +#include "entdec.h" +#include "arch.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define CELTEncoder OpusCustomEncoder +#define CELTDecoder OpusCustomDecoder +#define CELTMode OpusCustomMode + +typedef struct { + int valid; + float tonality; + float tonality_slope; + float noisiness; + float activity; + float music_prob; + int bandwidth; +}AnalysisInfo; + +#define __celt_check_mode_ptr_ptr(ptr) ((ptr) + ((ptr) - (const CELTMode**)(ptr))) + +#define __celt_check_analysis_ptr(ptr) ((ptr) + ((ptr) - (const AnalysisInfo*)(ptr))) + +/* Encoder/decoder Requests */ + +/* Expose this option again when variable framesize actually works */ +#define OPUS_FRAMESIZE_VARIABLE 5010 /**< Optimize the frame size dynamically */ + + +#define CELT_SET_PREDICTION_REQUEST 10002 +/** Controls the use of interframe prediction. + 0=Independent frames + 1=Short term interframe prediction allowed + 2=Long term prediction allowed + */ +#define CELT_SET_PREDICTION(x) CELT_SET_PREDICTION_REQUEST, __opus_check_int(x) + +#define CELT_SET_INPUT_CLIPPING_REQUEST 10004 +#define CELT_SET_INPUT_CLIPPING(x) CELT_SET_INPUT_CLIPPING_REQUEST, __opus_check_int(x) + +#define CELT_GET_AND_CLEAR_ERROR_REQUEST 10007 +#define CELT_GET_AND_CLEAR_ERROR(x) CELT_GET_AND_CLEAR_ERROR_REQUEST, __opus_check_int_ptr(x) + +#define CELT_SET_CHANNELS_REQUEST 10008 +#define CELT_SET_CHANNELS(x) CELT_SET_CHANNELS_REQUEST, __opus_check_int(x) + + +/* Internal */ +#define CELT_SET_START_BAND_REQUEST 10010 +#define CELT_SET_START_BAND(x) CELT_SET_START_BAND_REQUEST, __opus_check_int(x) + +#define CELT_SET_END_BAND_REQUEST 10012 +#define CELT_SET_END_BAND(x) CELT_SET_END_BAND_REQUEST, __opus_check_int(x) + +#define CELT_GET_MODE_REQUEST 10015 +/** Get the CELTMode used by an encoder or decoder */ +#define CELT_GET_MODE(x) CELT_GET_MODE_REQUEST, __celt_check_mode_ptr_ptr(x) + +#define CELT_SET_SIGNALLING_REQUEST 10016 +#define CELT_SET_SIGNALLING(x) CELT_SET_SIGNALLING_REQUEST, __opus_check_int(x) + +#define CELT_SET_TONALITY_REQUEST 10018 +#define CELT_SET_TONALITY(x) CELT_SET_TONALITY_REQUEST, __opus_check_int(x) +#define CELT_SET_TONALITY_SLOPE_REQUEST 10020 +#define CELT_SET_TONALITY_SLOPE(x) CELT_SET_TONALITY_SLOPE_REQUEST, __opus_check_int(x) + +#define CELT_SET_ANALYSIS_REQUEST 10022 +#define CELT_SET_ANALYSIS(x) CELT_SET_ANALYSIS_REQUEST, __celt_check_analysis_ptr(x) + +#define OPUS_SET_LFE_REQUEST 10024 +#define OPUS_SET_LFE(x) OPUS_SET_LFE_REQUEST, __opus_check_int(x) + +#define OPUS_SET_ENERGY_MASK_REQUEST 10026 +#define OPUS_SET_ENERGY_MASK(x) OPUS_SET_ENERGY_MASK_REQUEST, __opus_check_val16_ptr(x) + +/* Encoder stuff */ + +int celt_encoder_get_size(int channels); + +int celt_encode_with_ec(OpusCustomEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc); + +int celt_encoder_init(CELTEncoder *st, opus_int32 sampling_rate, int channels, + int arch); + + + +/* Decoder stuff */ + +int celt_decoder_get_size(int channels); + + +int celt_decoder_init(CELTDecoder *st, opus_int32 sampling_rate, int channels); + +int celt_decode_with_ec(OpusCustomDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, opus_val16 * OPUS_RESTRICT pcm, int frame_size, ec_dec *dec); + +#define celt_encoder_ctl opus_custom_encoder_ctl +#define celt_decoder_ctl opus_custom_decoder_ctl + + +#ifdef CUSTOM_MODES +#define OPUS_CUSTOM_NOSTATIC +#else +#define OPUS_CUSTOM_NOSTATIC static OPUS_INLINE +#endif + +static const unsigned char trim_icdf[11] = {126, 124, 119, 109, 87, 41, 19, 9, 4, 2, 0}; +/* Probs: NONE: 21.875%, LIGHT: 6.25%, NORMAL: 65.625%, AGGRESSIVE: 6.25% */ +static const unsigned char spread_icdf[4] = {25, 23, 2, 0}; + +static const unsigned char tapset_icdf[3]={2,1,0}; + +#ifdef CUSTOM_MODES +static const unsigned char toOpusTable[20] = { + 0xE0, 0xE8, 0xF0, 0xF8, + 0xC0, 0xC8, 0xD0, 0xD8, + 0xA0, 0xA8, 0xB0, 0xB8, + 0x00, 0x00, 0x00, 0x00, + 0x80, 0x88, 0x90, 0x98, +}; + +static const unsigned char fromOpusTable[16] = { + 0x80, 0x88, 0x90, 0x98, + 0x40, 0x48, 0x50, 0x58, + 0x20, 0x28, 0x30, 0x38, + 0x00, 0x08, 0x10, 0x18 +}; + +static OPUS_INLINE int toOpus(unsigned char c) +{ + int ret=0; + if (c<0xA0) + ret = toOpusTable[c>>3]; + if (ret == 0) + return -1; + else + return ret|(c&0x7); +} + +static OPUS_INLINE int fromOpus(unsigned char c) +{ + if (c<0x80) + return -1; + else + return fromOpusTable[(c>>3)-16] | (c&0x7); +} +#endif /* CUSTOM_MODES */ + +#define COMBFILTER_MAXPERIOD 1024 +#define COMBFILTER_MINPERIOD 15 + +extern const signed char tf_select_table[4][8]; + +int resampling_factor(opus_int32 rate); + +void celt_preemphasis(const opus_val16 * OPUS_RESTRICT pcmp, celt_sig * OPUS_RESTRICT inp, + int N, int CC, int upsample, const opus_val16 *coef, celt_sig *mem, int clip); + +void comb_filter(opus_val32 *y, opus_val32 *x, int T0, int T1, int N, + opus_val16 g0, opus_val16 g1, int tapset0, int tapset1, + const opus_val16 *window, int overlap); + +void init_caps(const CELTMode *m,int *cap,int LM,int C); + +#ifdef RESYNTH +void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, const opus_val16 *coef, celt_sig *mem, celt_sig * OPUS_RESTRICT scratch); + +void compute_inv_mdcts(const CELTMode *mode, int shortBlocks, celt_sig *X, + celt_sig * OPUS_RESTRICT out_mem[], int C, int LM); +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* CELT_H */ diff --git a/src/opus-1.1/celt/celt_decoder.c b/src/opus-1.1/celt/celt_decoder.c new file mode 100644 index 00000000..830398ee --- /dev/null +++ b/src/opus-1.1/celt/celt_decoder.c @@ -0,0 +1,1195 @@ +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2010 Xiph.Org Foundation + Copyright (c) 2008 Gregory Maxwell + Written by Jean-Marc Valin and Gregory Maxwell */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define CELT_DECODER_C + +#include "cpu_support.h" +#include "os_support.h" +#include "mdct.h" +#include +#include "celt.h" +#include "pitch.h" +#include "bands.h" +#include "modes.h" +#include "entcode.h" +#include "quant_bands.h" +#include "rate.h" +#include "stack_alloc.h" +#include "mathops.h" +#include "float_cast.h" +#include +#include "celt_lpc.h" +#include "vq.h" + +/**********************************************************************/ +/* */ +/* DECODER */ +/* */ +/**********************************************************************/ +#define DECODE_BUFFER_SIZE 2048 + +/** Decoder state + @brief Decoder state + */ +struct OpusCustomDecoder { + const OpusCustomMode *mode; + int overlap; + int channels; + int stream_channels; + + int downsample; + int start, end; + int signalling; + int arch; + + /* Everything beyond this point gets cleared on a reset */ +#define DECODER_RESET_START rng + + opus_uint32 rng; + int error; + int last_pitch_index; + int loss_count; + int postfilter_period; + int postfilter_period_old; + opus_val16 postfilter_gain; + opus_val16 postfilter_gain_old; + int postfilter_tapset; + int postfilter_tapset_old; + + celt_sig preemph_memD[2]; + + celt_sig _decode_mem[1]; /* Size = channels*(DECODE_BUFFER_SIZE+mode->overlap) */ + /* opus_val16 lpc[], Size = channels*LPC_ORDER */ + /* opus_val16 oldEBands[], Size = 2*mode->nbEBands */ + /* opus_val16 oldLogE[], Size = 2*mode->nbEBands */ + /* opus_val16 oldLogE2[], Size = 2*mode->nbEBands */ + /* opus_val16 backgroundLogE[], Size = 2*mode->nbEBands */ +}; + +int celt_decoder_get_size(int channels) +{ + const CELTMode *mode = opus_custom_mode_create(48000, 960, NULL); + return opus_custom_decoder_get_size(mode, channels); +} + +OPUS_CUSTOM_NOSTATIC int opus_custom_decoder_get_size(const CELTMode *mode, int channels) +{ + int size = sizeof(struct CELTDecoder) + + (channels*(DECODE_BUFFER_SIZE+mode->overlap)-1)*sizeof(celt_sig) + + channels*LPC_ORDER*sizeof(opus_val16) + + 4*2*mode->nbEBands*sizeof(opus_val16); + return size; +} + +#ifdef CUSTOM_MODES +CELTDecoder *opus_custom_decoder_create(const CELTMode *mode, int channels, int *error) +{ + int ret; + CELTDecoder *st = (CELTDecoder *)opus_alloc(opus_custom_decoder_get_size(mode, channels)); + ret = opus_custom_decoder_init(st, mode, channels); + if (ret != OPUS_OK) + { + opus_custom_decoder_destroy(st); + st = NULL; + } + if (error) + *error = ret; + return st; +} +#endif /* CUSTOM_MODES */ + +int celt_decoder_init(CELTDecoder *st, opus_int32 sampling_rate, int channels) +{ + int ret; + ret = opus_custom_decoder_init(st, opus_custom_mode_create(48000, 960, NULL), channels); + if (ret != OPUS_OK) + return ret; + st->downsample = resampling_factor(sampling_rate); + if (st->downsample==0) + return OPUS_BAD_ARG; + else + return OPUS_OK; +} + +OPUS_CUSTOM_NOSTATIC int opus_custom_decoder_init(CELTDecoder *st, const CELTMode *mode, int channels) +{ + if (channels < 0 || channels > 2) + return OPUS_BAD_ARG; + + if (st==NULL) + return OPUS_ALLOC_FAIL; + + OPUS_CLEAR((char*)st, opus_custom_decoder_get_size(mode, channels)); + + st->mode = mode; + st->overlap = mode->overlap; + st->stream_channels = st->channels = channels; + + st->downsample = 1; + st->start = 0; + st->end = st->mode->effEBands; + st->signalling = 1; + st->arch = opus_select_arch(); + + st->loss_count = 0; + + opus_custom_decoder_ctl(st, OPUS_RESET_STATE); + + return OPUS_OK; +} + +#ifdef CUSTOM_MODES +void opus_custom_decoder_destroy(CELTDecoder *st) +{ + opus_free(st); +} +#endif /* CUSTOM_MODES */ + +static OPUS_INLINE opus_val16 SIG2WORD16(celt_sig x) +{ +#ifdef FIXED_POINT + x = PSHR32(x, SIG_SHIFT); + x = MAX32(x, -32768); + x = MIN32(x, 32767); + return EXTRACT16(x); +#else + return (opus_val16)x; +#endif +} + +#ifndef RESYNTH +static +#endif +void deemphasis(celt_sig *in[], opus_val16 *pcm, int N, int C, int downsample, const opus_val16 *coef, celt_sig *mem, celt_sig * OPUS_RESTRICT scratch) +{ + int c; + int Nd; + int apply_downsampling=0; + opus_val16 coef0; + + coef0 = coef[0]; + Nd = N/downsample; + c=0; do { + int j; + celt_sig * OPUS_RESTRICT x; + opus_val16 * OPUS_RESTRICT y; + celt_sig m = mem[c]; + x =in[c]; + y = pcm+c; +#ifdef CUSTOM_MODES + if (coef[1] != 0) + { + opus_val16 coef1 = coef[1]; + opus_val16 coef3 = coef[3]; + for (j=0;j1) + { + /* Shortcut for the standard (non-custom modes) case */ + for (j=0;jshortMdctSize; + shift = mode->maxLM; + } else { + B = 1; + N = mode->shortMdctSize<maxLM-LM; + } + c=0; do { + /* IMDCT on the interleaved the sub-frames, overlap-add is performed by the IMDCT */ + for (b=0;bmdct, &X[b+c*N*B], out_mem[c]+N*b, mode->window, overlap, shift, B); + } while (++cstorage*8; + tell = ec_tell(dec); + logp = isTransient ? 2 : 4; + tf_select_rsv = LM>0 && tell+logp+1<=budget; + budget -= tf_select_rsv; + tf_changed = curr = 0; + for (i=start;ichannels; + celt_sig *decode_mem[2]; + celt_sig *out_syn[2]; + opus_val16 *lpc; + opus_val16 *oldBandE, *oldLogE, *oldLogE2, *backgroundLogE; + const OpusCustomMode *mode; + int nbEBands; + int overlap; + int start; + int downsample; + int loss_count; + int noise_based; + const opus_int16 *eBands; + VARDECL(celt_sig, scratch); + SAVE_STACK; + + mode = st->mode; + nbEBands = mode->nbEBands; + overlap = mode->overlap; + eBands = mode->eBands; + + c=0; do { + decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+overlap); + out_syn[c] = decode_mem[c]+DECODE_BUFFER_SIZE-N; + } while (++c_decode_mem+(DECODE_BUFFER_SIZE+overlap)*C); + oldBandE = lpc+C*LPC_ORDER; + oldLogE = oldBandE + 2*nbEBands; + oldLogE2 = oldLogE + 2*nbEBands; + backgroundLogE = oldLogE2 + 2*nbEBands; + + loss_count = st->loss_count; + start = st->start; + downsample = st->downsample; + noise_based = loss_count >= 5 || start != 0; + ALLOC(scratch, noise_based?N*C:N, celt_sig); + if (noise_based) + { + /* Noise-based PLC/CNG */ + celt_sig *freq; + VARDECL(celt_norm, X); + opus_uint32 seed; + opus_val16 *plcLogE; + int end; + int effEnd; + + end = st->end; + effEnd = IMAX(start, IMIN(end, mode->effEBands)); + + /* Share the interleaved signal MDCT coefficient buffer with the + deemphasis scratch buffer. */ + freq = scratch; + ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */ + + if (loss_count >= 5) + plcLogE = backgroundLogE; + else { + /* Energy decay */ + opus_val16 decay = loss_count==0 ? + QCONST16(1.5f, DB_SHIFT) : QCONST16(.5f, DB_SHIFT); + c=0; do + { + for (i=start;irng; + for (c=0;c>20); + } + renormalise_vector(X+boffs, blen, Q15ONE); + } + } + st->rng = seed; + + denormalise_bands(mode, X, freq, plcLogE, start, effEnd, C, 1<>1)); + } while (++c>1, opus_val16 ); + pitch_downsample(decode_mem, lp_pitch_buf, + DECODE_BUFFER_SIZE, C, st->arch); + pitch_search(lp_pitch_buf+(PLC_PITCH_LAG_MAX>>1), lp_pitch_buf, + DECODE_BUFFER_SIZE-PLC_PITCH_LAG_MAX, + PLC_PITCH_LAG_MAX-PLC_PITCH_LAG_MIN, &pitch_index, st->arch); + pitch_index = PLC_PITCH_LAG_MAX-pitch_index; + st->last_pitch_index = pitch_index; + } else { + pitch_index = st->last_pitch_index; + fade = QCONST16(.8f,15); + } + + ALLOC(etmp, overlap, opus_val32); + ALLOC(exc, MAX_PERIOD, opus_val16); + window = mode->window; + c=0; do { + opus_val16 decay; + opus_val16 attenuation; + opus_val32 S1=0; + celt_sig *buf; + int extrapolation_offset; + int extrapolation_len; + int exc_length; + int j; + + buf = decode_mem[c]; + for (i=0;iarch); + /* Add a noise floor of -40 dB. */ +#ifdef FIXED_POINT + ac[0] += SHR32(ac[0],13); +#else + ac[0] *= 1.0001f; +#endif + /* Use lag windowing to stabilize the Levinson-Durbin recursion. */ + for (i=1;i<=LPC_ORDER;i++) + { + /*ac[i] *= exp(-.5*(2*M_PI*.002*i)*(2*M_PI*.002*i));*/ +#ifdef FIXED_POINT + ac[i] -= MULT16_32_Q15(2*i*i, ac[i]); +#else + ac[i] -= ac[i]*(0.008f*0.008f)*i*i; +#endif + } + _celt_lpc(lpc+c*LPC_ORDER, ac, LPC_ORDER); + } + /* We want the excitation for 2 pitch periods in order to look for a + decaying signal, but we can't get more than MAX_PERIOD. */ + exc_length = IMIN(2*pitch_index, MAX_PERIOD); + /* Initialize the LPC history with the samples just before the start + of the region for which we're computing the excitation. */ + { + opus_val16 lpc_mem[LPC_ORDER]; + for (i=0;i>1; + for (i=0;i= pitch_index) { + j -= pitch_index; + attenuation = MULT16_16_Q15(attenuation, decay); + } + buf[DECODE_BUFFER_SIZE-N+i] = + SHL32(EXTEND32(MULT16_16_Q15(attenuation, + exc[extrapolation_offset+j])), SIG_SHIFT); + /* Compute the energy of the previously decoded signal whose + excitation we're copying. */ + tmp = ROUND16( + buf[DECODE_BUFFER_SIZE-MAX_PERIOD-N+extrapolation_offset+j], + SIG_SHIFT); + S1 += SHR32(MULT16_16(tmp, tmp), 8); + } + + { + opus_val16 lpc_mem[LPC_ORDER]; + /* Copy the last decoded samples (prior to the overlap region) to + synthesis filter memory so we can have a continuous signal. */ + for (i=0;i SHR32(S2,2))) +#else + /* The float test is written this way to catch NaNs in the output + of the IIR filter at the same time. */ + if (!(S1 > 0.2f*S2)) +#endif + { + for (i=0;ipostfilter_period, st->postfilter_period, overlap, + -st->postfilter_gain, -st->postfilter_gain, + st->postfilter_tapset, st->postfilter_tapset, NULL, 0); + + /* Simulate TDAC on the concealed audio so that it blends with the + MDCT of the next frame. */ + for (i=0;ipreemph, st->preemph_memD, scratch); + + st->loss_count = loss_count+1; + + RESTORE_STACK; +} + +int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, opus_val16 * OPUS_RESTRICT pcm, int frame_size, ec_dec *dec) +{ + int c, i, N; + int spread_decision; + opus_int32 bits; + ec_dec _dec; + VARDECL(celt_sig, freq); + VARDECL(celt_norm, X); + VARDECL(int, fine_quant); + VARDECL(int, pulses); + VARDECL(int, cap); + VARDECL(int, offsets); + VARDECL(int, fine_priority); + VARDECL(int, tf_res); + VARDECL(unsigned char, collapse_masks); + celt_sig *decode_mem[2]; + celt_sig *out_syn[2]; + opus_val16 *lpc; + opus_val16 *oldBandE, *oldLogE, *oldLogE2, *backgroundLogE; + + int shortBlocks; + int isTransient; + int intra_ener; + const int CC = st->channels; + int LM, M; + int effEnd; + int codedBands; + int alloc_trim; + int postfilter_pitch; + opus_val16 postfilter_gain; + int intensity=0; + int dual_stereo=0; + opus_int32 total_bits; + opus_int32 balance; + opus_int32 tell; + int dynalloc_logp; + int postfilter_tapset; + int anti_collapse_rsv; + int anti_collapse_on=0; + int silence; + int C = st->stream_channels; + const OpusCustomMode *mode; + int nbEBands; + int overlap; + const opus_int16 *eBands; + ALLOC_STACK; + + mode = st->mode; + nbEBands = mode->nbEBands; + overlap = mode->overlap; + eBands = mode->eBands; + frame_size *= st->downsample; + + c=0; do { + decode_mem[c] = st->_decode_mem + c*(DECODE_BUFFER_SIZE+overlap); + } while (++c_decode_mem+(DECODE_BUFFER_SIZE+overlap)*CC); + oldBandE = lpc+CC*LPC_ORDER; + oldLogE = oldBandE + 2*nbEBands; + oldLogE2 = oldLogE + 2*nbEBands; + backgroundLogE = oldLogE2 + 2*nbEBands; + +#ifdef CUSTOM_MODES + if (st->signalling && data!=NULL) + { + int data0=data[0]; + /* Convert "standard mode" to Opus header */ + if (mode->Fs==48000 && mode->shortMdctSize==120) + { + data0 = fromOpus(data0); + if (data0<0) + return OPUS_INVALID_PACKET; + } + st->end = IMAX(1, mode->effEBands-2*(data0>>5)); + LM = (data0>>3)&0x3; + C = 1 + ((data0>>2)&0x1); + data++; + len--; + if (LM>mode->maxLM) + return OPUS_INVALID_PACKET; + if (frame_size < mode->shortMdctSize<shortMdctSize<maxLM;LM++) + if (mode->shortMdctSize<mode->maxLM) + return OPUS_BAD_ARG; + } + M=1<1275 || pcm==NULL) + return OPUS_BAD_ARG; + + N = M*mode->shortMdctSize; + + effEnd = st->end; + if (effEnd > mode->effEBands) + effEnd = mode->effEBands; + + if (data == NULL || len<=1) + { + celt_decode_lost(st, pcm, N, LM); + RESTORE_STACK; + return frame_size/st->downsample; + } + + if (dec == NULL) + { + ec_dec_init(&_dec,(unsigned char*)data,len); + dec = &_dec; + } + + if (C==1) + { + for (i=0;i= total_bits) + silence = 1; + else if (tell==1) + silence = ec_dec_bit_logp(dec, 15); + else + silence = 0; + if (silence) + { + /* Pretend we've read all the remaining bits */ + tell = len*8; + dec->nbits_total+=tell-ec_tell(dec); + } + + postfilter_gain = 0; + postfilter_pitch = 0; + postfilter_tapset = 0; + if (st->start==0 && tell+16 <= total_bits) + { + if(ec_dec_bit_logp(dec, 1)) + { + int qg, octave; + octave = ec_dec_uint(dec, 6); + postfilter_pitch = (16< 0 && tell+3 <= total_bits) + { + isTransient = ec_dec_bit_logp(dec, 3); + tell = ec_tell(dec); + } + else + isTransient = 0; + + if (isTransient) + shortBlocks = M; + else + shortBlocks = 0; + + /* Decode the global flags (first symbols in the stream) */ + intra_ener = tell+3<=total_bits ? ec_dec_bit_logp(dec, 3) : 0; + /* Get band energies */ + unquant_coarse_energy(mode, st->start, st->end, oldBandE, + intra_ener, dec, C, LM); + + ALLOC(tf_res, nbEBands, int); + tf_decode(st->start, st->end, isTransient, tf_res, LM, dec); + + tell = ec_tell(dec); + spread_decision = SPREAD_NORMAL; + if (tell+4 <= total_bits) + spread_decision = ec_dec_icdf(dec, spread_icdf, 5); + + ALLOC(cap, nbEBands, int); + + init_caps(mode,cap,LM,C); + + ALLOC(offsets, nbEBands, int); + + dynalloc_logp = 6; + total_bits<<=BITRES; + tell = ec_tell_frac(dec); + for (i=st->start;iend;i++) + { + int width, quanta; + int dynalloc_loop_logp; + int boost; + width = C*(eBands[i+1]-eBands[i])<0) + dynalloc_logp = IMAX(2, dynalloc_logp-1); + } + + ALLOC(fine_quant, nbEBands, int); + alloc_trim = tell+(6<=2&&bits>=((LM+2)<start, st->end, offsets, cap, + alloc_trim, &intensity, &dual_stereo, bits, &balance, pulses, + fine_quant, fine_priority, C, LM, dec, 0, 0, 0); + + unquant_fine_energy(mode, st->start, st->end, oldBandE, fine_quant, dec, C); + + /* Decode fixed codebook */ + ALLOC(collapse_masks, C*nbEBands, unsigned char); + ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */ + + quant_all_bands(0, mode, st->start, st->end, X, C==2 ? X+N : NULL, collapse_masks, + NULL, pulses, shortBlocks, spread_decision, dual_stereo, intensity, tf_res, + len*(8<rng); + + if (anti_collapse_rsv > 0) + { + anti_collapse_on = ec_dec_bits(dec, 1); + } + + unquant_energy_finalise(mode, st->start, st->end, oldBandE, + fine_quant, fine_priority, len*8-ec_tell(dec), dec, C); + + if (anti_collapse_on) + anti_collapse(mode, X, collapse_masks, LM, C, N, + st->start, st->end, oldBandE, oldLogE, oldLogE2, pulses, st->rng); + + ALLOC(freq, IMAX(CC,C)*N, celt_sig); /**< Interleaved signal MDCTs */ + + if (silence) + { + for (i=0;istart, effEnd, C, M); + } + c=0; do { + OPUS_MOVE(decode_mem[c], decode_mem[c]+N, DECODE_BUFFER_SIZE-N+overlap/2); + } while (++cdownsample!=1) + bound = IMIN(bound, N/st->downsample); + for (i=bound;ipostfilter_period=IMAX(st->postfilter_period, COMBFILTER_MINPERIOD); + st->postfilter_period_old=IMAX(st->postfilter_period_old, COMBFILTER_MINPERIOD); + comb_filter(out_syn[c], out_syn[c], st->postfilter_period_old, st->postfilter_period, mode->shortMdctSize, + st->postfilter_gain_old, st->postfilter_gain, st->postfilter_tapset_old, st->postfilter_tapset, + mode->window, overlap); + if (LM!=0) + comb_filter(out_syn[c]+mode->shortMdctSize, out_syn[c]+mode->shortMdctSize, st->postfilter_period, postfilter_pitch, N-mode->shortMdctSize, + st->postfilter_gain, postfilter_gain, st->postfilter_tapset, postfilter_tapset, + mode->window, overlap); + + } while (++cpostfilter_period_old = st->postfilter_period; + st->postfilter_gain_old = st->postfilter_gain; + st->postfilter_tapset_old = st->postfilter_tapset; + st->postfilter_period = postfilter_pitch; + st->postfilter_gain = postfilter_gain; + st->postfilter_tapset = postfilter_tapset; + if (LM!=0) + { + st->postfilter_period_old = st->postfilter_period; + st->postfilter_gain_old = st->postfilter_gain; + st->postfilter_tapset_old = st->postfilter_tapset; + } + + if (C==1) { + for (i=0;istart;i++) + { + oldBandE[c*nbEBands+i]=0; + oldLogE[c*nbEBands+i]=oldLogE2[c*nbEBands+i]=-QCONST16(28.f,DB_SHIFT); + } + for (i=st->end;irng = dec->rng; + + /* We reuse freq[] as scratch space for the de-emphasis */ + deemphasis(out_syn, pcm, N, CC, st->downsample, mode->preemph, st->preemph_memD, freq); + st->loss_count = 0; + RESTORE_STACK; + if (ec_tell(dec) > 8*len) + return OPUS_INTERNAL_ERROR; + if(ec_get_error(dec)) + st->error = 1; + return frame_size/st->downsample; +} + + +#ifdef CUSTOM_MODES + +#ifdef FIXED_POINT +int opus_custom_decode(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, opus_int16 * OPUS_RESTRICT pcm, int frame_size) +{ + return celt_decode_with_ec(st, data, len, pcm, frame_size, NULL); +} + +#ifndef DISABLE_FLOAT_API +int opus_custom_decode_float(CELTDecoder * OPUS_RESTRICT st, const unsigned char *data, int len, float * OPUS_RESTRICT pcm, int frame_size) +{ + int j, ret, C, N; + VARDECL(opus_int16, out); + ALLOC_STACK; + + if (pcm==NULL) + return OPUS_BAD_ARG; + + C = st->channels; + N = frame_size; + + ALLOC(out, C*N, opus_int16); + ret=celt_decode_with_ec(st, data, len, out, frame_size, NULL); + if (ret>0) + for (j=0;jchannels; + N = frame_size; + ALLOC(out, C*N, celt_sig); + + ret=celt_decode_with_ec(st, data, len, out, frame_size, NULL); + + if (ret>0) + for (j=0;j=st->mode->nbEBands) + goto bad_arg; + st->start = value; + } + break; + case CELT_SET_END_BAND_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if (value<1 || value>st->mode->nbEBands) + goto bad_arg; + st->end = value; + } + break; + case CELT_SET_CHANNELS_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if (value<1 || value>2) + goto bad_arg; + st->stream_channels = value; + } + break; + case CELT_GET_AND_CLEAR_ERROR_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (value==NULL) + goto bad_arg; + *value=st->error; + st->error = 0; + } + break; + case OPUS_GET_LOOKAHEAD_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (value==NULL) + goto bad_arg; + *value = st->overlap/st->downsample; + } + break; + case OPUS_RESET_STATE: + { + int i; + opus_val16 *lpc, *oldBandE, *oldLogE, *oldLogE2; + lpc = (opus_val16*)(st->_decode_mem+(DECODE_BUFFER_SIZE+st->overlap)*st->channels); + oldBandE = lpc+st->channels*LPC_ORDER; + oldLogE = oldBandE + 2*st->mode->nbEBands; + oldLogE2 = oldLogE + 2*st->mode->nbEBands; + OPUS_CLEAR((char*)&st->DECODER_RESET_START, + opus_custom_decoder_get_size(st->mode, st->channels)- + ((char*)&st->DECODER_RESET_START - (char*)st)); + for (i=0;i<2*st->mode->nbEBands;i++) + oldLogE[i]=oldLogE2[i]=-QCONST16(28.f,DB_SHIFT); + } + break; + case OPUS_GET_PITCH_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (value==NULL) + goto bad_arg; + *value = st->postfilter_period; + } + break; + case CELT_GET_MODE_REQUEST: + { + const CELTMode ** value = va_arg(ap, const CELTMode**); + if (value==0) + goto bad_arg; + *value=st->mode; + } + break; + case CELT_SET_SIGNALLING_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + st->signalling = value; + } + break; + case OPUS_GET_FINAL_RANGE_REQUEST: + { + opus_uint32 * value = va_arg(ap, opus_uint32 *); + if (value==0) + goto bad_arg; + *value=st->rng; + } + break; + default: + goto bad_request; + } + va_end(ap); + return OPUS_OK; +bad_arg: + va_end(ap); + return OPUS_BAD_ARG; +bad_request: + va_end(ap); + return OPUS_UNIMPLEMENTED; +} diff --git a/src/opus-1.1/celt/celt_encoder.c b/src/opus-1.1/celt/celt_encoder.c new file mode 100644 index 00000000..ffff0775 --- /dev/null +++ b/src/opus-1.1/celt/celt_encoder.c @@ -0,0 +1,2353 @@ +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2010 Xiph.Org Foundation + Copyright (c) 2008 Gregory Maxwell + Written by Jean-Marc Valin and Gregory Maxwell */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#define CELT_ENCODER_C + +#include "cpu_support.h" +#include "os_support.h" +#include "mdct.h" +#include +#include "celt.h" +#include "pitch.h" +#include "bands.h" +#include "modes.h" +#include "entcode.h" +#include "quant_bands.h" +#include "rate.h" +#include "stack_alloc.h" +#include "mathops.h" +#include "float_cast.h" +#include +#include "celt_lpc.h" +#include "vq.h" + + +/** Encoder state + @brief Encoder state + */ +struct OpusCustomEncoder { + const OpusCustomMode *mode; /**< Mode used by the encoder */ + int overlap; + int channels; + int stream_channels; + + int force_intra; + int clip; + int disable_pf; + int complexity; + int upsample; + int start, end; + + opus_int32 bitrate; + int vbr; + int signalling; + int constrained_vbr; /* If zero, VBR can do whatever it likes with the rate */ + int loss_rate; + int lsb_depth; + int variable_duration; + int lfe; + int arch; + + /* Everything beyond this point gets cleared on a reset */ +#define ENCODER_RESET_START rng + + opus_uint32 rng; + int spread_decision; + opus_val32 delayedIntra; + int tonal_average; + int lastCodedBands; + int hf_average; + int tapset_decision; + + int prefilter_period; + opus_val16 prefilter_gain; + int prefilter_tapset; +#ifdef RESYNTH + int prefilter_period_old; + opus_val16 prefilter_gain_old; + int prefilter_tapset_old; +#endif + int consec_transient; + AnalysisInfo analysis; + + opus_val32 preemph_memE[2]; + opus_val32 preemph_memD[2]; + + /* VBR-related parameters */ + opus_int32 vbr_reservoir; + opus_int32 vbr_drift; + opus_int32 vbr_offset; + opus_int32 vbr_count; + opus_val32 overlap_max; + opus_val16 stereo_saving; + int intensity; + opus_val16 *energy_mask; + opus_val16 spec_avg; + +#ifdef RESYNTH + /* +MAX_PERIOD/2 to make space for overlap */ + celt_sig syn_mem[2][2*MAX_PERIOD+MAX_PERIOD/2]; +#endif + + celt_sig in_mem[1]; /* Size = channels*mode->overlap */ + /* celt_sig prefilter_mem[], Size = channels*COMBFILTER_MAXPERIOD */ + /* opus_val16 oldBandE[], Size = channels*mode->nbEBands */ + /* opus_val16 oldLogE[], Size = channels*mode->nbEBands */ + /* opus_val16 oldLogE2[], Size = channels*mode->nbEBands */ +}; + +int celt_encoder_get_size(int channels) +{ + CELTMode *mode = opus_custom_mode_create(48000, 960, NULL); + return opus_custom_encoder_get_size(mode, channels); +} + +OPUS_CUSTOM_NOSTATIC int opus_custom_encoder_get_size(const CELTMode *mode, int channels) +{ + int size = sizeof(struct CELTEncoder) + + (channels*mode->overlap-1)*sizeof(celt_sig) /* celt_sig in_mem[channels*mode->overlap]; */ + + channels*COMBFILTER_MAXPERIOD*sizeof(celt_sig) /* celt_sig prefilter_mem[channels*COMBFILTER_MAXPERIOD]; */ + + 3*channels*mode->nbEBands*sizeof(opus_val16); /* opus_val16 oldBandE[channels*mode->nbEBands]; */ + /* opus_val16 oldLogE[channels*mode->nbEBands]; */ + /* opus_val16 oldLogE2[channels*mode->nbEBands]; */ + return size; +} + +#ifdef CUSTOM_MODES +CELTEncoder *opus_custom_encoder_create(const CELTMode *mode, int channels, int *error) +{ + int ret; + CELTEncoder *st = (CELTEncoder *)opus_alloc(opus_custom_encoder_get_size(mode, channels)); + /* init will handle the NULL case */ + ret = opus_custom_encoder_init(st, mode, channels); + if (ret != OPUS_OK) + { + opus_custom_encoder_destroy(st); + st = NULL; + } + if (error) + *error = ret; + return st; +} +#endif /* CUSTOM_MODES */ + +static int opus_custom_encoder_init_arch(CELTEncoder *st, const CELTMode *mode, + int channels, int arch) +{ + if (channels < 0 || channels > 2) + return OPUS_BAD_ARG; + + if (st==NULL || mode==NULL) + return OPUS_ALLOC_FAIL; + + OPUS_CLEAR((char*)st, opus_custom_encoder_get_size(mode, channels)); + + st->mode = mode; + st->overlap = mode->overlap; + st->stream_channels = st->channels = channels; + + st->upsample = 1; + st->start = 0; + st->end = st->mode->effEBands; + st->signalling = 1; + + st->arch = arch; + + st->constrained_vbr = 1; + st->clip = 1; + + st->bitrate = OPUS_BITRATE_MAX; + st->vbr = 0; + st->force_intra = 0; + st->complexity = 5; + st->lsb_depth=24; + + opus_custom_encoder_ctl(st, OPUS_RESET_STATE); + + return OPUS_OK; +} + +#ifdef CUSTOM_MODES +int opus_custom_encoder_init(CELTEncoder *st, const CELTMode *mode, int channels) +{ + return opus_custom_encoder_init_arch(st, mode, channels, opus_select_arch()); +} +#endif + +int celt_encoder_init(CELTEncoder *st, opus_int32 sampling_rate, int channels, + int arch) +{ + int ret; + ret = opus_custom_encoder_init_arch(st, + opus_custom_mode_create(48000, 960, NULL), channels, arch); + if (ret != OPUS_OK) + return ret; + st->upsample = resampling_factor(sampling_rate); + return OPUS_OK; +} + +#ifdef CUSTOM_MODES +void opus_custom_encoder_destroy(CELTEncoder *st) +{ + opus_free(st); +} +#endif /* CUSTOM_MODES */ + + +static int transient_analysis(const opus_val32 * OPUS_RESTRICT in, int len, int C, + opus_val16 *tf_estimate, int *tf_chan) +{ + int i; + VARDECL(opus_val16, tmp); + opus_val32 mem0,mem1; + int is_transient = 0; + opus_int32 mask_metric = 0; + int c; + opus_val16 tf_max; + int len2; + /* Table of 6*64/x, trained on real data to minimize the average error */ + static const unsigned char inv_table[128] = { + 255,255,156,110, 86, 70, 59, 51, 45, 40, 37, 33, 31, 28, 26, 25, + 23, 22, 21, 20, 19, 18, 17, 16, 16, 15, 15, 14, 13, 13, 12, 12, + 12, 12, 11, 11, 11, 10, 10, 10, 9, 9, 9, 9, 9, 9, 8, 8, + 8, 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, + 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, + }; + SAVE_STACK; + ALLOC(tmp, len, opus_val16); + + len2=len/2; + for (c=0;c=0;i--) + { +#ifdef FIXED_POINT + /* FIXME: Use PSHR16() instead */ + tmp[i] = mem0 + PSHR32(tmp[i]-mem0,3); +#else + tmp[i] = mem0 + MULT16_16_P15(QCONST16(0.125f,15),tmp[i]-mem0); +#endif + mem0 = tmp[i]; + maxE = MAX16(maxE, mem0); + } + /*for (i=0;i>1))); +#else + mean = celt_sqrt(mean * maxE*.5*len2); +#endif + /* Inverse of the mean energy in Q15+6 */ + norm = SHL32(EXTEND32(len2),6+14)/ADD32(EPSILON,SHR32(mean,1)); + /* Compute harmonic mean discarding the unreliable boundaries + The data is smooth, so we only take 1/4th of the samples */ + unmask=0; + for (i=12;imask_metric) + { + *tf_chan = c; + mask_metric = unmask; + } + } + is_transient = mask_metric>200; + + /* Arbitrary metric for VBR boost */ + tf_max = MAX16(0,celt_sqrt(27*mask_metric)-42); + /* *tf_estimate = 1 + MIN16(1, sqrt(MAX16(0, tf_max-30))/20); */ + *tf_estimate = celt_sqrt(MAX16(0, SHL32(MULT16_16(QCONST16(0.0069,14),MIN16(163,tf_max)),14)-QCONST32(0.139,28))); + /*printf("%d %f\n", tf_max, mask_metric);*/ + RESTORE_STACK; +#ifdef FUZZING + is_transient = rand()&0x1; +#endif + /*printf("%d %f %d\n", is_transient, (float)*tf_estimate, tf_max);*/ + return is_transient; +} + +/* Looks for sudden increases of energy to decide whether we need to patch + the transient decision */ +int patch_transient_decision(opus_val16 *newE, opus_val16 *oldE, int nbEBands, + int end, int C) +{ + int i, c; + opus_val32 mean_diff=0; + opus_val16 spread_old[26]; + /* Apply an aggressive (-6 dB/Bark) spreading function to the old frame to + avoid false detection caused by irrelevant bands */ + if (C==1) + { + spread_old[0] = oldE[0]; + for (i=1;i=0;i--) + spread_old[i] = MAX16(spread_old[i], spread_old[i+1]-QCONST16(1.0f, DB_SHIFT)); + /* Compute mean increase */ + c=0; do { + for (i=2;i QCONST16(1.f, DB_SHIFT); +} + +/** Apply window and compute the MDCT for all sub-frames and + all channels in a frame */ +static void compute_mdcts(const CELTMode *mode, int shortBlocks, celt_sig * OPUS_RESTRICT in, + celt_sig * OPUS_RESTRICT out, int C, int CC, int LM, int upsample) +{ + const int overlap = OVERLAP(mode); + int N; + int B; + int shift; + int i, b, c; + if (shortBlocks) + { + B = shortBlocks; + N = mode->shortMdctSize; + shift = mode->maxLM; + } else { + B = 1; + N = mode->shortMdctSize<maxLM-LM; + } + c=0; do { + for (b=0;bmdct, in+c*(B*N+overlap)+b*N, &out[b+c*N*B], mode->window, overlap, shift, B); + } + } while (++ceBands[len]-m->eBands[len-1])<eBands[len]-m->eBands[len-1])<eBands[i+1]-m->eBands[i])<eBands[i+1]-m->eBands[i])==1; + for (j=0;jeBands[i]<eBands[i]<>LM, 1<>k, 1<=0;i--) + { + if (tf_res[i+1] == 1) + tf_res[i] = path1[i+1]; + else + tf_res[i] = path0[i+1]; + } + /*printf("%d %f\n", *tf_sum, tf_estimate);*/ + RESTORE_STACK; +#ifdef FUZZING + tf_select = rand()&0x1; + tf_res[0] = rand()&0x1; + for (i=1;istorage*8; + tell = ec_tell(enc); + logp = isTransient ? 2 : 4; + /* Reserve space to code the tf_select decision. */ + tf_select_rsv = LM>0 && tell+logp+1 <= budget; + budget -= tf_select_rsv; + curr = tf_changed = 0; + for (i=start;ieBands[i]<eBands[i+1]<eBands[i]<eBands[i+1]< QCONST16(.995f,10)) + trim_index-=4; + else if (sum > QCONST16(.92f,10)) + trim_index-=3; + else if (sum > QCONST16(.85f,10)) + trim_index-=2; + else if (sum > QCONST16(.8f,10)) + trim_index-=1; + /* mid-side savings estimations based on the LF average*/ + logXC = celt_log2(QCONST32(1.001f, 20)-MULT16_16(sum, sum)); + /* mid-side savings estimations based on min correlation */ + logXC2 = MAX16(HALF16(logXC), celt_log2(QCONST32(1.001f, 20)-MULT16_16(minXC, minXC))); +#ifdef FIXED_POINT + /* Compensate for Q20 vs Q14 input and convert output to Q8 */ + logXC = PSHR32(logXC-QCONST16(6.f, DB_SHIFT),DB_SHIFT-8); + logXC2 = PSHR32(logXC2-QCONST16(6.f, DB_SHIFT),DB_SHIFT-8); +#endif + + trim += MAX16(-QCONST16(4.f, 8), MULT16_16_Q15(QCONST16(.75f,15),logXC)); + *stereo_saving = MIN16(*stereo_saving + QCONST16(0.25f, 8), -HALF16(logXC2)); + } + + /* Estimate spectral tilt */ + c=0; do { + for (i=0;inbEBands]*(opus_int32)(2+2*i-end); + } + } while (++c QCONST16(2.f, DB_SHIFT)) + trim_index--; + if (diff > QCONST16(8.f, DB_SHIFT)) + trim_index--; + if (diff < -QCONST16(4.f, DB_SHIFT)) + trim_index++; + if (diff < -QCONST16(10.f, DB_SHIFT)) + trim_index++; + trim -= MAX16(-QCONST16(2.f, 8), MIN16(QCONST16(2.f, 8), SHR16(diff+QCONST16(1.f, DB_SHIFT),DB_SHIFT-8)/6 )); + trim -= SHR16(surround_trim, DB_SHIFT-8); + trim -= 2*SHR16(tf_estimate, 14-8); +#ifndef DISABLE_FLOAT_API + if (analysis->valid) + { + trim -= MAX16(-QCONST16(2.f, 8), MIN16(QCONST16(2.f, 8), + (opus_val16)(QCONST16(2.f, 8)*(analysis->tonality_slope+.05f)))); + } +#endif + +#ifdef FIXED_POINT + trim_index = PSHR32(trim, 8); +#else + trim_index = (int)floor(.5f+trim); +#endif + if (trim_index<0) + trim_index = 0; + if (trim_index>10) + trim_index = 10; + /*printf("%d\n", trim_index);*/ +#ifdef FUZZING + trim_index = rand()%11; +#endif + return trim_index; +} + +static int stereo_analysis(const CELTMode *m, const celt_norm *X, + int LM, int N0) +{ + int i; + int thetas; + opus_val32 sumLR = EPSILON, sumMS = EPSILON; + + /* Use the L1 norm to model the entropy of the L/R signal vs the M/S signal */ + for (i=0;i<13;i++) + { + int j; + for (j=m->eBands[i]<eBands[i+1]<eBands[13]<<(LM+1))+thetas, sumMS) + > MULT16_32_Q15(m->eBands[13]<<(LM+1), sumLR); +} + +static opus_val16 dynalloc_analysis(const opus_val16 *bandLogE, const opus_val16 *bandLogE2, + int nbEBands, int start, int end, int C, int *offsets, int lsb_depth, const opus_int16 *logN, + int isTransient, int vbr, int constrained_vbr, const opus_int16 *eBands, int LM, + int effectiveBytes, opus_int32 *tot_boost_, int lfe, opus_val16 *surround_dynalloc) +{ + int i, c; + opus_int32 tot_boost=0; + opus_val16 maxDepth; + VARDECL(opus_val16, follower); + VARDECL(opus_val16, noise_floor); + SAVE_STACK; + ALLOC(follower, C*nbEBands, opus_val16); + ALLOC(noise_floor, C*nbEBands, opus_val16); + for (i=0;i 50 && LM>=1 && !lfe) + { + int last=0; + c=0;do + { + follower[c*nbEBands] = bandLogE2[c*nbEBands]; + for (i=1;i bandLogE2[c*nbEBands+i-1]+QCONST16(.5f,DB_SHIFT)) + last=i; + follower[c*nbEBands+i] = MIN16(follower[c*nbEBands+i-1]+QCONST16(1.5f,DB_SHIFT), bandLogE2[c*nbEBands+i]); + } + for (i=last-1;i>=0;i--) + follower[c*nbEBands+i] = MIN16(follower[c*nbEBands+i], MIN16(follower[c*nbEBands+i+1]+QCONST16(2.f,DB_SHIFT), bandLogE2[c*nbEBands+i])); + for (i=0;i=12) + follower[i] = HALF16(follower[i]); + follower[i] = MIN16(follower[i], QCONST16(4, DB_SHIFT)); + + width = C*(eBands[i+1]-eBands[i])< 48) { + boost = (int)SHR32(EXTEND32(follower[i])*8,DB_SHIFT); + boost_bits = (boost*width<>BITRES>>3 > effectiveBytes/4) + { + opus_int32 cap = ((effectiveBytes/4)<mode; + ALLOC(_pre, CC*(N+COMBFILTER_MAXPERIOD), celt_sig); + + pre[0] = _pre; + pre[1] = _pre + (N+COMBFILTER_MAXPERIOD); + + + c=0; do { + OPUS_COPY(pre[c], prefilter_mem+c*COMBFILTER_MAXPERIOD, COMBFILTER_MAXPERIOD); + OPUS_COPY(pre[c]+COMBFILTER_MAXPERIOD, in+c*(N+st->overlap)+st->overlap, N); + } while (++c>1, opus_val16); + + pitch_downsample(pre, pitch_buf, COMBFILTER_MAXPERIOD+N, CC, st->arch); + /* Don't search for the fir last 1.5 octave of the range because + there's too many false-positives due to short-term correlation */ + pitch_search(pitch_buf+(COMBFILTER_MAXPERIOD>>1), pitch_buf, N, + COMBFILTER_MAXPERIOD-3*COMBFILTER_MINPERIOD, &pitch_index, + st->arch); + pitch_index = COMBFILTER_MAXPERIOD-pitch_index; + + gain1 = remove_doubling(pitch_buf, COMBFILTER_MAXPERIOD, COMBFILTER_MINPERIOD, + N, &pitch_index, st->prefilter_period, st->prefilter_gain); + if (pitch_index > COMBFILTER_MAXPERIOD-2) + pitch_index = COMBFILTER_MAXPERIOD-2; + gain1 = MULT16_16_Q15(QCONST16(.7f,15),gain1); + /*printf("%d %d %f %f\n", pitch_change, pitch_index, gain1, st->analysis.tonality);*/ + if (st->loss_rate>2) + gain1 = HALF32(gain1); + if (st->loss_rate>4) + gain1 = HALF32(gain1); + if (st->loss_rate>8) + gain1 = 0; + } else { + gain1 = 0; + pitch_index = COMBFILTER_MINPERIOD; + } + + /* Gain threshold for enabling the prefilter/postfilter */ + pf_threshold = QCONST16(.2f,15); + + /* Adjusting the threshold based on rate and continuity */ + if (abs(pitch_index-st->prefilter_period)*10>pitch_index) + pf_threshold += QCONST16(.2f,15); + if (nbAvailableBytes<25) + pf_threshold += QCONST16(.1f,15); + if (nbAvailableBytes<35) + pf_threshold += QCONST16(.1f,15); + if (st->prefilter_gain > QCONST16(.4f,15)) + pf_threshold -= QCONST16(.1f,15); + if (st->prefilter_gain > QCONST16(.55f,15)) + pf_threshold -= QCONST16(.1f,15); + + /* Hard threshold at 0.2 */ + pf_threshold = MAX16(pf_threshold, QCONST16(.2f,15)); + if (gain1prefilter_gain)prefilter_gain; + +#ifdef FIXED_POINT + qg = ((gain1+1536)>>10)/3-1; +#else + qg = (int)floor(.5f+gain1*32/3)-1; +#endif + qg = IMAX(0, IMIN(7, qg)); + gain1 = QCONST16(0.09375f,15)*(qg+1); + pf_on = 1; + } + /*printf("%d %f\n", pitch_index, gain1);*/ + + c=0; do { + int offset = mode->shortMdctSize-st->overlap; + st->prefilter_period=IMAX(st->prefilter_period, COMBFILTER_MINPERIOD); + OPUS_COPY(in+c*(N+st->overlap), st->in_mem+c*(st->overlap), st->overlap); + if (offset) + comb_filter(in+c*(N+st->overlap)+st->overlap, pre[c]+COMBFILTER_MAXPERIOD, + st->prefilter_period, st->prefilter_period, offset, -st->prefilter_gain, -st->prefilter_gain, + st->prefilter_tapset, st->prefilter_tapset, NULL, 0); + + comb_filter(in+c*(N+st->overlap)+st->overlap+offset, pre[c]+COMBFILTER_MAXPERIOD+offset, + st->prefilter_period, pitch_index, N-offset, -st->prefilter_gain, -gain1, + st->prefilter_tapset, prefilter_tapset, mode->window, st->overlap); + OPUS_COPY(st->in_mem+c*(st->overlap), in+c*(N+st->overlap)+N, st->overlap); + + if (N>COMBFILTER_MAXPERIOD) + { + OPUS_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD, pre[c]+N, COMBFILTER_MAXPERIOD); + } else { + OPUS_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD, prefilter_mem+c*COMBFILTER_MAXPERIOD+N, COMBFILTER_MAXPERIOD-N); + OPUS_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD+COMBFILTER_MAXPERIOD-N, pre[c]+COMBFILTER_MAXPERIOD, N); + } + } while (++cnbEBands; + eBands = mode->eBands; + + coded_bands = lastCodedBands ? lastCodedBands : nbEBands; + coded_bins = eBands[coded_bands]<analysis.activity, st->analysis.tonality, tf_estimate, st->stereo_saving, tot_boost, coded_bands);*/ +#ifndef DISABLE_FLOAT_API + if (analysis->valid && analysis->activity<.4) + target -= (opus_int32)((coded_bins<activity)); +#endif + /* Stereo savings */ + if (C==2) + { + int coded_stereo_bands; + int coded_stereo_dof; + opus_val16 max_frac; + coded_stereo_bands = IMIN(intensity, coded_bands); + coded_stereo_dof = (eBands[coded_stereo_bands]<valid && !lfe) + { + opus_int32 tonal_target; + float tonal; + + /* Tonality boost (compensating for the average). */ + tonal = MAX16(0.f,analysis->tonality-.15f)-0.09f; + tonal_target = target + (opus_int32)((coded_bins<tonality, tonal);*/ + target = tonal_target; + } +#endif + + if (has_surround_mask&&!lfe) + { + opus_int32 surround_target = target + (opus_int32)SHR32(MULT16_16(surround_masking,coded_bins<end, st->intensity, surround_target, target, st->bitrate);*/ + target = IMAX(target/4, surround_target); + } + + { + opus_int32 floor_depth; + int bins; + bins = eBands[nbEBands-2]<>2); + target = IMIN(target, floor_depth); + /*printf("%f %d\n", maxDepth, floor_depth);*/ + } + + if ((!has_surround_mask||lfe) && (constrained_vbr || bitrate<64000)) + { + opus_val16 rate_factor; +#ifdef FIXED_POINT + rate_factor = MAX16(0,(bitrate-32000)); +#else + rate_factor = MAX16(0,(1.f/32768)*(bitrate-32000)); +#endif + if (constrained_vbr) + rate_factor = MIN16(rate_factor, QCONST16(0.67f, 15)); + target = base_target + (opus_int32)MULT16_32_Q15(rate_factor, target-base_target); + + } + + if (!has_surround_mask && tf_estimate < QCONST16(.2f, 14)) + { + opus_val16 amount; + opus_val16 tvbr_factor; + amount = MULT16_16_Q15(QCONST16(.0000031f, 30), IMAX(0, IMIN(32000, 96000-bitrate))); + tvbr_factor = SHR32(MULT16_16(temporal_vbr, amount), DB_SHIFT); + target += (opus_int32)MULT16_32_Q15(tvbr_factor, target); + } + + /* Don't allow more than doubling the rate */ + target = IMIN(2*base_target, target); + + return target; +} + +int celt_encode_with_ec(CELTEncoder * OPUS_RESTRICT st, const opus_val16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes, ec_enc *enc) +{ + int i, c, N; + opus_int32 bits; + ec_enc _enc; + VARDECL(celt_sig, in); + VARDECL(celt_sig, freq); + VARDECL(celt_norm, X); + VARDECL(celt_ener, bandE); + VARDECL(opus_val16, bandLogE); + VARDECL(opus_val16, bandLogE2); + VARDECL(int, fine_quant); + VARDECL(opus_val16, error); + VARDECL(int, pulses); + VARDECL(int, cap); + VARDECL(int, offsets); + VARDECL(int, fine_priority); + VARDECL(int, tf_res); + VARDECL(unsigned char, collapse_masks); + celt_sig *prefilter_mem; + opus_val16 *oldBandE, *oldLogE, *oldLogE2; + int shortBlocks=0; + int isTransient=0; + const int CC = st->channels; + const int C = st->stream_channels; + int LM, M; + int tf_select; + int nbFilledBytes, nbAvailableBytes; + int effEnd; + int codedBands; + int tf_sum; + int alloc_trim; + int pitch_index=COMBFILTER_MINPERIOD; + opus_val16 gain1 = 0; + int dual_stereo=0; + int effectiveBytes; + int dynalloc_logp; + opus_int32 vbr_rate; + opus_int32 total_bits; + opus_int32 total_boost; + opus_int32 balance; + opus_int32 tell; + int prefilter_tapset=0; + int pf_on; + int anti_collapse_rsv; + int anti_collapse_on=0; + int silence=0; + int tf_chan = 0; + opus_val16 tf_estimate; + int pitch_change=0; + opus_int32 tot_boost; + opus_val32 sample_max; + opus_val16 maxDepth; + const OpusCustomMode *mode; + int nbEBands; + int overlap; + const opus_int16 *eBands; + int secondMdct; + int signalBandwidth; + int transient_got_disabled=0; + opus_val16 surround_masking=0; + opus_val16 temporal_vbr=0; + opus_val16 surround_trim = 0; + opus_int32 equiv_rate = 510000; + VARDECL(opus_val16, surround_dynalloc); + ALLOC_STACK; + + mode = st->mode; + nbEBands = mode->nbEBands; + overlap = mode->overlap; + eBands = mode->eBands; + tf_estimate = 0; + if (nbCompressedBytes<2 || pcm==NULL) + { + RESTORE_STACK; + return OPUS_BAD_ARG; + } + + frame_size *= st->upsample; + for (LM=0;LM<=mode->maxLM;LM++) + if (mode->shortMdctSize<mode->maxLM) + { + RESTORE_STACK; + return OPUS_BAD_ARG; + } + M=1<shortMdctSize; + + prefilter_mem = st->in_mem+CC*(st->overlap); + oldBandE = (opus_val16*)(st->in_mem+CC*(st->overlap+COMBFILTER_MAXPERIOD)); + oldLogE = oldBandE + CC*nbEBands; + oldLogE2 = oldLogE + CC*nbEBands; + + if (enc==NULL) + { + tell=1; + nbFilledBytes=0; + } else { + tell=ec_tell(enc); + nbFilledBytes=(tell+4)>>3; + } + +#ifdef CUSTOM_MODES + if (st->signalling && enc==NULL) + { + int tmp = (mode->effEBands-st->end)>>1; + st->end = IMAX(1, mode->effEBands-tmp); + compressed[0] = tmp<<5; + compressed[0] |= LM<<3; + compressed[0] |= (C==2)<<2; + /* Convert "standard mode" to Opus header */ + if (mode->Fs==48000 && mode->shortMdctSize==120) + { + int c0 = toOpus(compressed[0]); + if (c0<0) + { + RESTORE_STACK; + return OPUS_BAD_ARG; + } + compressed[0] = c0; + } + compressed++; + nbCompressedBytes--; + } +#else + celt_assert(st->signalling==0); +#endif + + /* Can't produce more than 1275 output bytes */ + nbCompressedBytes = IMIN(nbCompressedBytes,1275); + nbAvailableBytes = nbCompressedBytes - nbFilledBytes; + + if (st->vbr && st->bitrate!=OPUS_BITRATE_MAX) + { + opus_int32 den=mode->Fs>>BITRES; + vbr_rate=(st->bitrate*frame_size+(den>>1))/den; +#ifdef CUSTOM_MODES + if (st->signalling) + vbr_rate -= 8<>(3+BITRES); + } else { + opus_int32 tmp; + vbr_rate = 0; + tmp = st->bitrate*frame_size; + if (tell>1) + tmp += tell; + if (st->bitrate!=OPUS_BITRATE_MAX) + nbCompressedBytes = IMAX(2, IMIN(nbCompressedBytes, + (tmp+4*mode->Fs)/(8*mode->Fs)-!!st->signalling)); + effectiveBytes = nbCompressedBytes; + } + if (st->bitrate != OPUS_BITRATE_MAX) + equiv_rate = st->bitrate - (40*C+20)*((400>>LM) - 50); + + if (enc==NULL) + { + ec_enc_init(&_enc, compressed, nbCompressedBytes); + enc = &_enc; + } + + if (vbr_rate>0) + { + /* Computes the max bit-rate allowed in VBR mode to avoid violating the + target rate and buffering. + We must do this up front so that bust-prevention logic triggers + correctly if we don't have enough bits. */ + if (st->constrained_vbr) + { + opus_int32 vbr_bound; + opus_int32 max_allowed; + /* We could use any multiple of vbr_rate as bound (depending on the + delay). + This is clamped to ensure we use at least two bytes if the encoder + was entirely empty, but to allow 0 in hybrid mode. */ + vbr_bound = vbr_rate; + max_allowed = IMIN(IMAX(tell==1?2:0, + (vbr_rate+vbr_bound-st->vbr_reservoir)>>(BITRES+3)), + nbAvailableBytes); + if(max_allowed < nbAvailableBytes) + { + nbCompressedBytes = nbFilledBytes+max_allowed; + nbAvailableBytes = max_allowed; + ec_enc_shrink(enc, nbCompressedBytes); + } + } + } + total_bits = nbCompressedBytes*8; + + effEnd = st->end; + if (effEnd > mode->effEBands) + effEnd = mode->effEBands; + + ALLOC(in, CC*(N+st->overlap), celt_sig); + + sample_max=MAX32(st->overlap_max, celt_maxabs16(pcm, C*(N-overlap)/st->upsample)); + st->overlap_max=celt_maxabs16(pcm+C*(N-overlap)/st->upsample, C*overlap/st->upsample); + sample_max=MAX32(sample_max, st->overlap_max); +#ifdef FIXED_POINT + silence = (sample_max==0); +#else + silence = (sample_max <= (opus_val16)1/(1<lsb_depth)); +#endif +#ifdef FUZZING + if ((rand()&0x3F)==0) + silence = 1; +#endif + if (tell==1) + ec_enc_bit_logp(enc, silence, 15); + else + silence=0; + if (silence) + { + /*In VBR mode there is no need to send more than the minimum. */ + if (vbr_rate>0) + { + effectiveBytes=nbCompressedBytes=IMIN(nbCompressedBytes, nbFilledBytes+2); + total_bits=nbCompressedBytes*8; + nbAvailableBytes=2; + ec_enc_shrink(enc, nbCompressedBytes); + } + /* Pretend we've filled all the remaining bits with zeros + (that's what the initialiser did anyway) */ + tell = nbCompressedBytes*8; + enc->nbits_total+=tell-ec_tell(enc); + } + c=0; do { + celt_preemphasis(pcm+c, in+c*(N+st->overlap)+st->overlap, N, CC, st->upsample, + mode->preemph, st->preemph_memE+c, st->clip); + } while (++clfe&&nbAvailableBytes>3) || nbAvailableBytes>12*C) && st->start==0 && !silence && !st->disable_pf + && st->complexity >= 5 && !(st->consec_transient && LM!=3 && st->variable_duration==OPUS_FRAMESIZE_VARIABLE); + + prefilter_tapset = st->tapset_decision; + pf_on = run_prefilter(st, in, prefilter_mem, CC, N, prefilter_tapset, &pitch_index, &gain1, &qg, enabled, nbAvailableBytes); + if ((gain1 > QCONST16(.4f,15) || st->prefilter_gain > QCONST16(.4f,15)) && (!st->analysis.valid || st->analysis.tonality > .3) + && (pitch_index > 1.26*st->prefilter_period || pitch_index < .79*st->prefilter_period)) + pitch_change = 1; + if (pf_on==0) + { + if(st->start==0 && tell+16<=total_bits) + ec_enc_bit_logp(enc, 0, 1); + } else { + /*This block is not gated by a total bits check only because + of the nbAvailableBytes check above.*/ + int octave; + ec_enc_bit_logp(enc, 1, 1); + pitch_index += 1; + octave = EC_ILOG(pitch_index)-5; + ec_enc_uint(enc, octave, 6); + ec_enc_bits(enc, pitch_index-(16<complexity >= 1 && !st->lfe) + { + isTransient = transient_analysis(in, N+st->overlap, CC, + &tf_estimate, &tf_chan); + } + if (LM>0 && ec_tell(enc)+3<=total_bits) + { + if (isTransient) + shortBlocks = M; + } else { + isTransient = 0; + transient_got_disabled=1; + } + + ALLOC(freq, CC*N, celt_sig); /**< Interleaved signal MDCTs */ + ALLOC(bandE,nbEBands*CC, celt_ener); + ALLOC(bandLogE,nbEBands*CC, opus_val16); + + secondMdct = shortBlocks && st->complexity>=8; + ALLOC(bandLogE2, C*nbEBands, opus_val16); + if (secondMdct) + { + compute_mdcts(mode, 0, in, freq, C, CC, LM, st->upsample); + compute_band_energies(mode, freq, bandE, effEnd, C, M); + amp2Log2(mode, effEnd, st->end, bandE, bandLogE2, C); + for (i=0;iupsample); + if (CC==2&&C==1) + tf_chan = 0; + compute_band_energies(mode, freq, bandE, effEnd, C, M); + + if (st->lfe) + { + for (i=2;iend;i++) + { + bandE[i] = IMIN(bandE[i], MULT16_32_Q15(QCONST16(1e-4f,15),bandE[0])); + bandE[i] = MAX32(bandE[i], EPSILON); + } + } + amp2Log2(mode, effEnd, st->end, bandE, bandLogE, C); + + ALLOC(surround_dynalloc, C*nbEBands, opus_val16); + for(i=0;iend;i++) + surround_dynalloc[i] = 0; + /* This computes how much masking takes place between surround channels */ + if (st->start==0&&st->energy_mask&&!st->lfe) + { + int mask_end; + int midband; + int count_dynalloc; + opus_val32 mask_avg=0; + opus_val32 diff=0; + int count=0; + mask_end = IMAX(2,st->lastCodedBands); + for (c=0;cenergy_mask[nbEBands*c+i], + QCONST16(.25f, DB_SHIFT)), -QCONST16(2.0f, DB_SHIFT)); + if (mask > 0) + mask = HALF16(mask); + mask_avg += MULT16_16(mask, eBands[i+1]-eBands[i]); + count += eBands[i+1]-eBands[i]; + diff += MULT16_16(mask, 1+2*i-mask_end); + } + } + mask_avg = DIV32_16(mask_avg,count); + mask_avg += QCONST16(.2f, DB_SHIFT); + diff = diff*6/(C*(mask_end-1)*(mask_end+1)*mask_end); + /* Again, being conservative */ + diff = HALF32(diff); + diff = MAX32(MIN32(diff, QCONST32(.031f, DB_SHIFT)), -QCONST32(.031f, DB_SHIFT)); + /* Find the band that's in the middle of the coded spectrum */ + for (midband=0;eBands[midband+1] < eBands[mask_end]/2;midband++); + count_dynalloc=0; + for(i=0;ienergy_mask[i], st->energy_mask[nbEBands+i]); + else + unmask = st->energy_mask[i]; + unmask = MIN16(unmask, QCONST16(.0f, DB_SHIFT)); + unmask -= lin; + if (unmask > QCONST16(.25f, DB_SHIFT)) + { + surround_dynalloc[i] = unmask - QCONST16(.25f, DB_SHIFT); + count_dynalloc++; + } + } + if (count_dynalloc>=3) + { + /* If we need dynalloc in many bands, it's probably because our + initial masking rate was too low. */ + mask_avg += QCONST16(.25f, DB_SHIFT); + if (mask_avg>0) + { + /* Something went really wrong in the original calculations, + disabling masking. */ + mask_avg = 0; + diff = 0; + for(i=0;ilfe) + { + opus_val16 follow=-QCONST16(10.0f,DB_SHIFT); + opus_val32 frame_avg=0; + opus_val16 offset = shortBlocks?HALF16(SHL16(LM, DB_SHIFT)):0; + for(i=st->start;iend;i++) + { + follow = MAX16(follow-QCONST16(1.f, DB_SHIFT), bandLogE[i]-offset); + if (C==2) + follow = MAX16(follow, bandLogE[i+nbEBands]-offset); + frame_avg += follow; + } + frame_avg /= (st->end-st->start); + temporal_vbr = SUB16(frame_avg,st->spec_avg); + temporal_vbr = MIN16(QCONST16(3.f, DB_SHIFT), MAX16(-QCONST16(1.5f, DB_SHIFT), temporal_vbr)); + st->spec_avg += MULT16_16_Q15(QCONST16(.02f, 15), temporal_vbr); + } + /*for (i=0;i<21;i++) + printf("%f ", bandLogE[i]); + printf("\n");*/ + + if (!secondMdct) + { + for (i=0;i0 && ec_tell(enc)+3<=total_bits && !isTransient && st->complexity>=5 && !st->lfe) + { + if (patch_transient_decision(bandLogE, oldBandE, nbEBands, st->end, C)) + { + isTransient = 1; + shortBlocks = M; + compute_mdcts(mode, shortBlocks, in, freq, C, CC, LM, st->upsample); + compute_band_energies(mode, freq, bandE, effEnd, C, M); + amp2Log2(mode, effEnd, st->end, bandE, bandLogE, C); + /* Compensate for the scaling of short vs long mdcts */ + for (i=0;i0 && ec_tell(enc)+3<=total_bits) + ec_enc_bit_logp(enc, isTransient, 3); + + ALLOC(X, C*N, celt_norm); /**< Interleaved normalised MDCTs */ + + /* Band normalisation */ + normalise_bands(mode, freq, X, bandE, effEnd, C, M); + + ALLOC(tf_res, nbEBands, int); + /* Disable variable tf resolution for hybrid and at very low bitrate */ + if (effectiveBytes>=15*C && st->start==0 && st->complexity>=2 && !st->lfe) + { + int lambda; + if (effectiveBytes<40) + lambda = 12; + else if (effectiveBytes<60) + lambda = 6; + else if (effectiveBytes<100) + lambda = 4; + else + lambda = 3; + lambda*=2; + tf_select = tf_analysis(mode, effEnd, isTransient, tf_res, lambda, X, N, LM, &tf_sum, tf_estimate, tf_chan); + for (i=effEnd;iend;i++) + tf_res[i] = tf_res[effEnd-1]; + } else { + tf_sum = 0; + for (i=0;iend;i++) + tf_res[i] = isTransient; + tf_select=0; + } + + ALLOC(error, C*nbEBands, opus_val16); + quant_coarse_energy(mode, st->start, st->end, effEnd, bandLogE, + oldBandE, total_bits, error, enc, + C, LM, nbAvailableBytes, st->force_intra, + &st->delayedIntra, st->complexity >= 4, st->loss_rate, st->lfe); + + tf_encode(st->start, st->end, isTransient, tf_res, LM, tf_select, enc); + + if (ec_tell(enc)+4<=total_bits) + { + if (st->lfe) + { + st->tapset_decision = 0; + st->spread_decision = SPREAD_NORMAL; + } else if (shortBlocks || st->complexity < 3 || nbAvailableBytes < 10*C || st->start != 0) + { + if (st->complexity == 0) + st->spread_decision = SPREAD_NONE; + else + st->spread_decision = SPREAD_NORMAL; + } else { + /* Disable new spreading+tapset estimator until we can show it works + better than the old one. So far it seems like spreading_decision() + works best. */ +#if 0 + if (st->analysis.valid) + { + static const opus_val16 spread_thresholds[3] = {-QCONST16(.6f, 15), -QCONST16(.2f, 15), -QCONST16(.07f, 15)}; + static const opus_val16 spread_histeresis[3] = {QCONST16(.15f, 15), QCONST16(.07f, 15), QCONST16(.02f, 15)}; + static const opus_val16 tapset_thresholds[2] = {QCONST16(.0f, 15), QCONST16(.15f, 15)}; + static const opus_val16 tapset_histeresis[2] = {QCONST16(.1f, 15), QCONST16(.05f, 15)}; + st->spread_decision = hysteresis_decision(-st->analysis.tonality, spread_thresholds, spread_histeresis, 3, st->spread_decision); + st->tapset_decision = hysteresis_decision(st->analysis.tonality_slope, tapset_thresholds, tapset_histeresis, 2, st->tapset_decision); + } else +#endif + { + st->spread_decision = spreading_decision(mode, X, + &st->tonal_average, st->spread_decision, &st->hf_average, + &st->tapset_decision, pf_on&&!shortBlocks, effEnd, C, M); + } + /*printf("%d %d\n", st->tapset_decision, st->spread_decision);*/ + /*printf("%f %d %f %d\n\n", st->analysis.tonality, st->spread_decision, st->analysis.tonality_slope, st->tapset_decision);*/ + } + ec_enc_icdf(enc, st->spread_decision, spread_icdf, 5); + } + + ALLOC(offsets, nbEBands, int); + + maxDepth = dynalloc_analysis(bandLogE, bandLogE2, nbEBands, st->start, st->end, C, offsets, + st->lsb_depth, mode->logN, isTransient, st->vbr, st->constrained_vbr, + eBands, LM, effectiveBytes, &tot_boost, st->lfe, surround_dynalloc); + /* For LFE, everything interesting is in the first band */ + if (st->lfe) + offsets[0] = IMIN(8, effectiveBytes/3); + ALLOC(cap, nbEBands, int); + init_caps(mode,cap,LM,C); + + dynalloc_logp = 6; + total_bits<<=BITRES; + total_boost = 0; + tell = ec_tell_frac(enc); + for (i=st->start;iend;i++) + { + int width, quanta; + int dynalloc_loop_logp; + int boost; + int j; + width = C*(eBands[i+1]-eBands[i])<intensity = hysteresis_decision((opus_val16)(equiv_rate/1000), + intensity_thresholds, intensity_histeresis, 21, st->intensity); + st->intensity = IMIN(st->end,IMAX(st->start, st->intensity)); + } + + alloc_trim = 5; + if (tell+(6<lfe) + alloc_trim = 5; + else + alloc_trim = alloc_trim_analysis(mode, X, bandLogE, + st->end, LM, C, N, &st->analysis, &st->stereo_saving, tf_estimate, st->intensity, surround_trim); + ec_enc_icdf(enc, alloc_trim, trim_icdf, 7); + tell = ec_tell_frac(enc); + } + + /* Variable bitrate */ + if (vbr_rate>0) + { + opus_val16 alpha; + opus_int32 delta; + /* The target rate in 8th bits per frame */ + opus_int32 target, base_target; + opus_int32 min_allowed; + int lm_diff = mode->maxLM - LM; + + /* Don't attempt to use more than 510 kb/s, even for frames smaller than 20 ms. + The CELT allocator will just not be able to use more than that anyway. */ + nbCompressedBytes = IMIN(nbCompressedBytes,1275>>(3-LM)); + base_target = vbr_rate - ((40*C+20)<constrained_vbr) + base_target += (st->vbr_offset>>lm_diff); + + target = compute_vbr(mode, &st->analysis, base_target, LM, equiv_rate, + st->lastCodedBands, C, st->intensity, st->constrained_vbr, + st->stereo_saving, tot_boost, tf_estimate, pitch_change, maxDepth, + st->variable_duration, st->lfe, st->energy_mask!=NULL, surround_masking, + temporal_vbr); + + /* The current offset is removed from the target and the space used + so far is added*/ + target=target+tell; + /* In VBR mode the frame size must not be reduced so much that it would + result in the encoder running out of bits. + The margin of 2 bytes ensures that none of the bust-prevention logic + in the decoder will have triggered so far. */ + min_allowed = ((tell+total_boost+(1<<(BITRES+3))-1)>>(BITRES+3)) + 2 - nbFilledBytes; + + nbAvailableBytes = (target+(1<<(BITRES+2)))>>(BITRES+3); + nbAvailableBytes = IMAX(min_allowed,nbAvailableBytes); + nbAvailableBytes = IMIN(nbCompressedBytes,nbAvailableBytes+nbFilledBytes) - nbFilledBytes; + + /* By how much did we "miss" the target on that frame */ + delta = target - vbr_rate; + + target=nbAvailableBytes<<(BITRES+3); + + /*If the frame is silent we don't adjust our drift, otherwise + the encoder will shoot to very high rates after hitting a + span of silence, but we do allow the bitres to refill. + This means that we'll undershoot our target in CVBR/VBR modes + on files with lots of silence. */ + if(silence) + { + nbAvailableBytes = 2; + target = 2*8<vbr_count < 970) + { + st->vbr_count++; + alpha = celt_rcp(SHL32(EXTEND32(st->vbr_count+20),16)); + } else + alpha = QCONST16(.001f,15); + /* How many bits have we used in excess of what we're allowed */ + if (st->constrained_vbr) + st->vbr_reservoir += target - vbr_rate; + /*printf ("%d\n", st->vbr_reservoir);*/ + + /* Compute the offset we need to apply in order to reach the target */ + if (st->constrained_vbr) + { + st->vbr_drift += (opus_int32)MULT16_32_Q15(alpha,(delta*(1<vbr_offset-st->vbr_drift); + st->vbr_offset = -st->vbr_drift; + } + /*printf ("%d\n", st->vbr_drift);*/ + + if (st->constrained_vbr && st->vbr_reservoir < 0) + { + /* We're under the min value -- increase rate */ + int adjust = (-st->vbr_reservoir)/(8<vbr_reservoir = 0; + /*printf ("+%d\n", adjust);*/ + } + nbCompressedBytes = IMIN(nbCompressedBytes,nbAvailableBytes+nbFilledBytes); + /*printf("%d\n", nbCompressedBytes*50*8);*/ + /* This moves the raw bits to take into account the new compressed size */ + ec_enc_shrink(enc, nbCompressedBytes); + } + + /* Bit allocation */ + ALLOC(fine_quant, nbEBands, int); + ALLOC(pulses, nbEBands, int); + ALLOC(fine_priority, nbEBands, int); + + /* bits = packet size - where we are - safety*/ + bits = (((opus_int32)nbCompressedBytes*8)<=2&&bits>=((LM+2)<end-1; +#ifndef DISABLE_FLOAT_API + if (st->analysis.valid) + { + int min_bandwidth; + if (equiv_rate < (opus_int32)32000*C) + min_bandwidth = 13; + else if (equiv_rate < (opus_int32)48000*C) + min_bandwidth = 16; + else if (equiv_rate < (opus_int32)60000*C) + min_bandwidth = 18; + else if (equiv_rate < (opus_int32)80000*C) + min_bandwidth = 19; + else + min_bandwidth = 20; + signalBandwidth = IMAX(st->analysis.bandwidth, min_bandwidth); + } +#endif + if (st->lfe) + signalBandwidth = 1; + codedBands = compute_allocation(mode, st->start, st->end, offsets, cap, + alloc_trim, &st->intensity, &dual_stereo, bits, &balance, pulses, + fine_quant, fine_priority, C, LM, enc, 1, st->lastCodedBands, signalBandwidth); + if (st->lastCodedBands) + st->lastCodedBands = IMIN(st->lastCodedBands+1,IMAX(st->lastCodedBands-1,codedBands)); + else + st->lastCodedBands = codedBands; + + quant_fine_energy(mode, st->start, st->end, oldBandE, error, fine_quant, enc, C); + + /* Residual quantisation */ + ALLOC(collapse_masks, C*nbEBands, unsigned char); + quant_all_bands(1, mode, st->start, st->end, X, C==2 ? X+N : NULL, collapse_masks, + bandE, pulses, shortBlocks, st->spread_decision, dual_stereo, st->intensity, tf_res, + nbCompressedBytes*(8<rng); + + if (anti_collapse_rsv > 0) + { + anti_collapse_on = st->consec_transient<2; +#ifdef FUZZING + anti_collapse_on = rand()&0x1; +#endif + ec_enc_bits(enc, anti_collapse_on, 1); + } + quant_energy_finalise(mode, st->start, st->end, oldBandE, error, fine_quant, fine_priority, nbCompressedBytes*8-ec_tell(enc), enc, C); + + if (silence) + { + for (i=0;istart, st->end, oldBandE, oldLogE, oldLogE2, pulses, st->rng); + } + + if (silence) + { + for (i=0;istart, effEnd, C, M); + } + + c=0; do { + OPUS_MOVE(st->syn_mem[c], st->syn_mem[c]+N, 2*MAX_PERIOD-N+overlap/2); + } while (++csyn_mem[c]+2*MAX_PERIOD-N; + } while (++cprefilter_period=IMAX(st->prefilter_period, COMBFILTER_MINPERIOD); + st->prefilter_period_old=IMAX(st->prefilter_period_old, COMBFILTER_MINPERIOD); + comb_filter(out_mem[c], out_mem[c], st->prefilter_period_old, st->prefilter_period, mode->shortMdctSize, + st->prefilter_gain_old, st->prefilter_gain, st->prefilter_tapset_old, st->prefilter_tapset, + mode->window, st->overlap); + if (LM!=0) + comb_filter(out_mem[c]+mode->shortMdctSize, out_mem[c]+mode->shortMdctSize, st->prefilter_period, pitch_index, N-mode->shortMdctSize, + st->prefilter_gain, gain1, st->prefilter_tapset, prefilter_tapset, + mode->window, overlap); + } while (++cupsample, mode->preemph, st->preemph_memD, freq); + st->prefilter_period_old = st->prefilter_period; + st->prefilter_gain_old = st->prefilter_gain; + st->prefilter_tapset_old = st->prefilter_tapset; + } +#endif + + st->prefilter_period = pitch_index; + st->prefilter_gain = gain1; + st->prefilter_tapset = prefilter_tapset; +#ifdef RESYNTH + if (LM!=0) + { + st->prefilter_period_old = st->prefilter_period; + st->prefilter_gain_old = st->prefilter_gain; + st->prefilter_tapset_old = st->prefilter_tapset; + } +#endif + + if (CC==2&&C==1) { + for (i=0;istart;i++) + { + oldBandE[c*nbEBands+i]=0; + oldLogE[c*nbEBands+i]=oldLogE2[c*nbEBands+i]=-QCONST16(28.f,DB_SHIFT); + } + for (i=st->end;iconsec_transient++; + else + st->consec_transient=0; + st->rng = enc->rng; + + /* If there's any room left (can only happen for very high rates), + it's already filled with zeros */ + ec_enc_done(enc); + +#ifdef CUSTOM_MODES + if (st->signalling) + nbCompressedBytes++; +#endif + + RESTORE_STACK; + if (ec_get_error(enc)) + return OPUS_INTERNAL_ERROR; + else + return nbCompressedBytes; +} + + +#ifdef CUSTOM_MODES + +#ifdef FIXED_POINT +int opus_custom_encode(CELTEncoder * OPUS_RESTRICT st, const opus_int16 * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes) +{ + return celt_encode_with_ec(st, pcm, frame_size, compressed, nbCompressedBytes, NULL); +} + +#ifndef DISABLE_FLOAT_API +int opus_custom_encode_float(CELTEncoder * OPUS_RESTRICT st, const float * pcm, int frame_size, unsigned char *compressed, int nbCompressedBytes) +{ + int j, ret, C, N; + VARDECL(opus_int16, in); + ALLOC_STACK; + + if (pcm==NULL) + return OPUS_BAD_ARG; + + C = st->channels; + N = frame_size; + ALLOC(in, C*N, opus_int16); + + for (j=0;jchannels; + N=frame_size; + ALLOC(in, C*N, celt_sig); + for (j=0;j10) + goto bad_arg; + st->complexity = value; + } + break; + case CELT_SET_START_BAND_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if (value<0 || value>=st->mode->nbEBands) + goto bad_arg; + st->start = value; + } + break; + case CELT_SET_END_BAND_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if (value<1 || value>st->mode->nbEBands) + goto bad_arg; + st->end = value; + } + break; + case CELT_SET_PREDICTION_REQUEST: + { + int value = va_arg(ap, opus_int32); + if (value<0 || value>2) + goto bad_arg; + st->disable_pf = value<=1; + st->force_intra = value==0; + } + break; + case OPUS_SET_PACKET_LOSS_PERC_REQUEST: + { + int value = va_arg(ap, opus_int32); + if (value<0 || value>100) + goto bad_arg; + st->loss_rate = value; + } + break; + case OPUS_SET_VBR_CONSTRAINT_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + st->constrained_vbr = value; + } + break; + case OPUS_SET_VBR_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + st->vbr = value; + } + break; + case OPUS_SET_BITRATE_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if (value<=500 && value!=OPUS_BITRATE_MAX) + goto bad_arg; + value = IMIN(value, 260000*st->channels); + st->bitrate = value; + } + break; + case CELT_SET_CHANNELS_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if (value<1 || value>2) + goto bad_arg; + st->stream_channels = value; + } + break; + case OPUS_SET_LSB_DEPTH_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if (value<8 || value>24) + goto bad_arg; + st->lsb_depth=value; + } + break; + case OPUS_GET_LSB_DEPTH_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + *value=st->lsb_depth; + } + break; + case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + st->variable_duration = value; + } + break; + case OPUS_RESET_STATE: + { + int i; + opus_val16 *oldBandE, *oldLogE, *oldLogE2; + oldBandE = (opus_val16*)(st->in_mem+st->channels*(st->overlap+COMBFILTER_MAXPERIOD)); + oldLogE = oldBandE + st->channels*st->mode->nbEBands; + oldLogE2 = oldLogE + st->channels*st->mode->nbEBands; + OPUS_CLEAR((char*)&st->ENCODER_RESET_START, + opus_custom_encoder_get_size(st->mode, st->channels)- + ((char*)&st->ENCODER_RESET_START - (char*)st)); + for (i=0;ichannels*st->mode->nbEBands;i++) + oldLogE[i]=oldLogE2[i]=-QCONST16(28.f,DB_SHIFT); + st->vbr_offset = 0; + st->delayedIntra = 1; + st->spread_decision = SPREAD_NORMAL; + st->tonal_average = 256; + st->hf_average = 0; + st->tapset_decision = 0; + } + break; +#ifdef CUSTOM_MODES + case CELT_SET_INPUT_CLIPPING_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + st->clip = value; + } + break; +#endif + case CELT_SET_SIGNALLING_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + st->signalling = value; + } + break; + case CELT_SET_ANALYSIS_REQUEST: + { + AnalysisInfo *info = va_arg(ap, AnalysisInfo *); + if (info) + OPUS_COPY(&st->analysis, info, 1); + } + break; + case CELT_GET_MODE_REQUEST: + { + const CELTMode ** value = va_arg(ap, const CELTMode**); + if (value==0) + goto bad_arg; + *value=st->mode; + } + break; + case OPUS_GET_FINAL_RANGE_REQUEST: + { + opus_uint32 * value = va_arg(ap, opus_uint32 *); + if (value==0) + goto bad_arg; + *value=st->rng; + } + break; + case OPUS_SET_LFE_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + st->lfe = value; + } + break; + case OPUS_SET_ENERGY_MASK_REQUEST: + { + opus_val16 *value = va_arg(ap, opus_val16*); + st->energy_mask = value; + } + break; + default: + goto bad_request; + } + va_end(ap); + return OPUS_OK; +bad_arg: + va_end(ap); + return OPUS_BAD_ARG; +bad_request: + va_end(ap); + return OPUS_UNIMPLEMENTED; +} diff --git a/src/opus-1.1/celt/celt_lpc.c b/src/opus-1.1/celt/celt_lpc.c new file mode 100644 index 00000000..fa29d626 --- /dev/null +++ b/src/opus-1.1/celt/celt_lpc.c @@ -0,0 +1,309 @@ +/* Copyright (c) 2009-2010 Xiph.Org Foundation + Written by Jean-Marc Valin */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "celt_lpc.h" +#include "stack_alloc.h" +#include "mathops.h" +#include "pitch.h" + +void _celt_lpc( + opus_val16 *_lpc, /* out: [0...p-1] LPC coefficients */ +const opus_val32 *ac, /* in: [0...p] autocorrelation values */ +int p +) +{ + int i, j; + opus_val32 r; + opus_val32 error = ac[0]; +#ifdef FIXED_POINT + opus_val32 lpc[LPC_ORDER]; +#else + float *lpc = _lpc; +#endif + + for (i = 0; i < p; i++) + lpc[i] = 0; + if (ac[0] != 0) + { + for (i = 0; i < p; i++) { + /* Sum up this iteration's reflection coefficient */ + opus_val32 rr = 0; + for (j = 0; j < i; j++) + rr += MULT32_32_Q31(lpc[j],ac[i - j]); + rr += SHR32(ac[i + 1],3); + r = -frac_div32(SHL32(rr,3), error); + /* Update LPC coefficients and total error */ + lpc[i] = SHR32(r,3); + for (j = 0; j < (i+1)>>1; j++) + { + opus_val32 tmp1, tmp2; + tmp1 = lpc[j]; + tmp2 = lpc[i-1-j]; + lpc[j] = tmp1 + MULT32_32_Q31(r,tmp2); + lpc[i-1-j] = tmp2 + MULT32_32_Q31(r,tmp1); + } + + error = error - MULT32_32_Q31(MULT32_32_Q31(r,r),error); + /* Bail out once we get 30 dB gain */ +#ifdef FIXED_POINT + if (error=1;j--) + { + mem[j]=mem[j-1]; + } + mem[0] = ROUND16(sum,SIG_SHIFT); + _y[i] = sum; + } +#else + int i,j; + VARDECL(opus_val16, rden); + VARDECL(opus_val16, y); + SAVE_STACK; + + celt_assert((ord&3)==0); + ALLOC(rden, ord, opus_val16); + ALLOC(y, N+ord, opus_val16); + for(i=0;i0); + celt_assert(overlap>=0); + if (overlap == 0) + { + xptr = x; + } else { + for (i=0;i0) + { + for(i=0;i= 536870912) + { + int shift2=1; + if (ac[0] >= 1073741824) + shift2++; + for (i=0;i<=lag;i++) + ac[i] = SHR32(ac[i], shift2); + shift += shift2; + } +#endif + + RESTORE_STACK; + return shift; +} diff --git a/src/opus-1.1/celt/celt_lpc.h b/src/opus-1.1/celt/celt_lpc.h new file mode 100644 index 00000000..dc2a0a3d --- /dev/null +++ b/src/opus-1.1/celt/celt_lpc.h @@ -0,0 +1,54 @@ +/* Copyright (c) 2009-2010 Xiph.Org Foundation + Written by Jean-Marc Valin */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef PLC_H +#define PLC_H + +#include "arch.h" + +#define LPC_ORDER 24 + +void _celt_lpc(opus_val16 *_lpc, const opus_val32 *ac, int p); + +void celt_fir(const opus_val16 *x, + const opus_val16 *num, + opus_val16 *y, + int N, + int ord, + opus_val16 *mem); + +void celt_iir(const opus_val32 *x, + const opus_val16 *den, + opus_val32 *y, + int N, + int ord, + opus_val16 *mem); + +int _celt_autocorr(const opus_val16 *x, opus_val32 *ac, + const opus_val16 *window, int overlap, int lag, int n, int arch); + +#endif /* PLC_H */ diff --git a/src/opus-1.1/celt/cpu_support.h b/src/opus-1.1/celt/cpu_support.h new file mode 100644 index 00000000..d68dbe62 --- /dev/null +++ b/src/opus-1.1/celt/cpu_support.h @@ -0,0 +1,54 @@ +/* Copyright (c) 2010 Xiph.Org Foundation + * Copyright (c) 2013 Parrot */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef CPU_SUPPORT_H +#define CPU_SUPPORT_H + +#include "opus_types.h" +#include "opus_defines.h" + +#if defined(OPUS_HAVE_RTCD) && defined(OPUS_ARM_ASM) +#include "arm/armcpu.h" + +/* We currently support 4 ARM variants: + * arch[0] -> ARMv4 + * arch[1] -> ARMv5E + * arch[2] -> ARMv6 + * arch[3] -> NEON + */ +#define OPUS_ARCHMASK 3 + +#else +#define OPUS_ARCHMASK 0 + +static OPUS_INLINE int opus_select_arch(void) +{ + return 0; +} +#endif + +#endif diff --git a/src/opus-1.1/celt/cwrs.c b/src/opus-1.1/celt/cwrs.c new file mode 100644 index 00000000..ad980cc7 --- /dev/null +++ b/src/opus-1.1/celt/cwrs.c @@ -0,0 +1,697 @@ +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation + Copyright (c) 2007-2009 Timothy B. Terriberry + Written by Timothy B. Terriberry and Jean-Marc Valin */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "os_support.h" +#include "cwrs.h" +#include "mathops.h" +#include "arch.h" + +#ifdef CUSTOM_MODES + +/*Guaranteed to return a conservatively large estimate of the binary logarithm + with frac bits of fractional precision. + Tested for all possible 32-bit inputs with frac=4, where the maximum + overestimation is 0.06254243 bits.*/ +int log2_frac(opus_uint32 val, int frac) +{ + int l; + l=EC_ILOG(val); + if(val&(val-1)){ + /*This is (val>>l-16), but guaranteed to round up, even if adding a bias + before the shift would cause overflow (e.g., for 0xFFFFxxxx). + Doesn't work for val=0, but that case fails the test above.*/ + if(l>16)val=((val-1)>>(l-16))+1; + else val<<=16-l; + l=(l-1)<>16); + l+=b<>b; + val=(val*val+0x7FFF)>>15; + } + while(frac-->0); + /*If val is not exactly 0x8000, then we have to round up the remainder.*/ + return l+(val>0x8000); + } + /*Exact powers of two require no rounding.*/ + else return (l-1)<0 ? sum(k=1...K,2**k*choose(N,k)*choose(K-1,k-1)) : 1, + where choose() is the binomial function. + A table of values for N<10 and K<10 looks like: + V[10][10] = { + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {1, 2, 2, 2, 2, 2, 2, 2, 2, 2}, + {1, 4, 8, 12, 16, 20, 24, 28, 32, 36}, + {1, 6, 18, 38, 66, 102, 146, 198, 258, 326}, + {1, 8, 32, 88, 192, 360, 608, 952, 1408, 1992}, + {1, 10, 50, 170, 450, 1002, 1970, 3530, 5890, 9290}, + {1, 12, 72, 292, 912, 2364, 5336, 10836, 20256, 35436}, + {1, 14, 98, 462, 1666, 4942, 12642, 28814, 59906, 115598}, + {1, 16, 128, 688, 2816, 9424, 27008, 68464, 157184, 332688}, + {1, 18, 162, 978, 4482, 16722, 53154, 148626, 374274, 864146} + }; + + U(N,K) = the number of such combinations wherein N-1 objects are taken at + most K-1 at a time. + This is given by + U(N,K) = sum(k=0...K-1,V(N-1,k)) + = K>0 ? (V(N-1,K-1) + V(N,K-1))/2 : 0. + The latter expression also makes clear that U(N,K) is half the number of such + combinations wherein the first object is taken at least once. + Although it may not be clear from either of these definitions, U(N,K) is the + natural function to work with when enumerating the pulse vector codebooks, + not V(N,K). + U(N,K) is not well-defined for N=0, but with the extension + U(0,K) = K>0 ? 0 : 1, + the function becomes symmetric: U(N,K) = U(K,N), with a similar table: + U[10][10] = { + {1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + {0, 1, 3, 5, 7, 9, 11, 13, 15, 17}, + {0, 1, 5, 13, 25, 41, 61, 85, 113, 145}, + {0, 1, 7, 25, 63, 129, 231, 377, 575, 833}, + {0, 1, 9, 41, 129, 321, 681, 1289, 2241, 3649}, + {0, 1, 11, 61, 231, 681, 1683, 3653, 7183, 13073}, + {0, 1, 13, 85, 377, 1289, 3653, 8989, 19825, 40081}, + {0, 1, 15, 113, 575, 2241, 7183, 19825, 48639, 108545}, + {0, 1, 17, 145, 833, 3649, 13073, 40081, 108545, 265729} + }; + + With this extension, V(N,K) may be written in terms of U(N,K): + V(N,K) = U(N,K) + U(N,K+1) + for all N>=0, K>=0. + Thus U(N,K+1) represents the number of combinations where the first element + is positive or zero, and U(N,K) represents the number of combinations where + it is negative. + With a large enough table of U(N,K) values, we could write O(N) encoding + and O(min(N*log(K),N+K)) decoding routines, but such a table would be + prohibitively large for small embedded devices (K may be as large as 32767 + for small N, and N may be as large as 200). + + Both functions obey the same recurrence relation: + V(N,K) = V(N-1,K) + V(N,K-1) + V(N-1,K-1), + U(N,K) = U(N-1,K) + U(N,K-1) + U(N-1,K-1), + for all N>0, K>0, with different initial conditions at N=0 or K=0. + This allows us to construct a row of one of the tables above given the + previous row or the next row. + Thus we can derive O(NK) encoding and decoding routines with O(K) memory + using only addition and subtraction. + + When encoding, we build up from the U(2,K) row and work our way forwards. + When decoding, we need to start at the U(N,K) row and work our way backwards, + which requires a means of computing U(N,K). + U(N,K) may be computed from two previous values with the same N: + U(N,K) = ((2*N-1)*U(N,K-1) - U(N,K-2))/(K-1) + U(N,K-2) + for all N>1, and since U(N,K) is symmetric, a similar relation holds for two + previous values with the same K: + U(N,K>1) = ((2*K-1)*U(N-1,K) - U(N-2,K))/(N-1) + U(N-2,K) + for all K>1. + This allows us to construct an arbitrary row of the U(N,K) table by starting + with the first two values, which are constants. + This saves roughly 2/3 the work in our O(NK) decoding routine, but costs O(K) + multiplications. + Similar relations can be derived for V(N,K), but are not used here. + + For N>0 and K>0, U(N,K) and V(N,K) take on the form of an (N-1)-degree + polynomial for fixed N. + The first few are + U(1,K) = 1, + U(2,K) = 2*K-1, + U(3,K) = (2*K-2)*K+1, + U(4,K) = (((4*K-6)*K+8)*K-3)/3, + U(5,K) = ((((2*K-4)*K+10)*K-8)*K+3)/3, + and + V(1,K) = 2, + V(2,K) = 4*K, + V(3,K) = 4*K*K+2, + V(4,K) = 8*(K*K+2)*K/3, + V(5,K) = ((4*K*K+20)*K*K+6)/3, + for all K>0. + This allows us to derive O(N) encoding and O(N*log(K)) decoding routines for + small N (and indeed decoding is also O(N) for N<3). + + @ARTICLE{Fis86, + author="Thomas R. Fischer", + title="A Pyramid Vector Quantizer", + journal="IEEE Transactions on Information Theory", + volume="IT-32", + number=4, + pages="568--583", + month=Jul, + year=1986 + }*/ + +#if !defined(SMALL_FOOTPRINT) + +/*U(N,K) = U(K,N) := N>0?K>0?U(N-1,K)+U(N,K-1)+U(N-1,K-1):0:K>0?1:0*/ +# define CELT_PVQ_U(_n,_k) (CELT_PVQ_U_ROW[IMIN(_n,_k)][IMAX(_n,_k)]) +/*V(N,K) := U(N,K)+U(N,K+1) = the number of PVQ codewords for a band of size N + with K pulses allocated to it.*/ +# define CELT_PVQ_V(_n,_k) (CELT_PVQ_U(_n,_k)+CELT_PVQ_U(_n,(_k)+1)) + +/*For each V(N,K) supported, we will access element U(min(N,K+1),max(N,K+1)). + Thus, the number of entries in row I is the larger of the maximum number of + pulses we will ever allocate for a given N=I (K=128, or however many fit in + 32 bits, whichever is smaller), plus one, and the maximum N for which + K=I-1 pulses fit in 32 bits. + The largest band size in an Opus Custom mode is 208. + Otherwise, we can limit things to the set of N which can be achieved by + splitting a band from a standard Opus mode: 176, 144, 96, 88, 72, 64, 48, + 44, 36, 32, 24, 22, 18, 16, 8, 4, 2).*/ +#if defined(CUSTOM_MODES) +static const opus_uint32 CELT_PVQ_U_DATA[1488]={ +#else +static const opus_uint32 CELT_PVQ_U_DATA[1272]={ +#endif + /*N=0, K=0...176:*/ + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +#if defined(CUSTOM_MODES) + /*...208:*/ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, +#endif + /*N=1, K=1...176:*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +#if defined(CUSTOM_MODES) + /*...208:*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, +#endif + /*N=2, K=2...176:*/ + 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, + 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, + 81, 83, 85, 87, 89, 91, 93, 95, 97, 99, 101, 103, 105, 107, 109, 111, 113, + 115, 117, 119, 121, 123, 125, 127, 129, 131, 133, 135, 137, 139, 141, 143, + 145, 147, 149, 151, 153, 155, 157, 159, 161, 163, 165, 167, 169, 171, 173, + 175, 177, 179, 181, 183, 185, 187, 189, 191, 193, 195, 197, 199, 201, 203, + 205, 207, 209, 211, 213, 215, 217, 219, 221, 223, 225, 227, 229, 231, 233, + 235, 237, 239, 241, 243, 245, 247, 249, 251, 253, 255, 257, 259, 261, 263, + 265, 267, 269, 271, 273, 275, 277, 279, 281, 283, 285, 287, 289, 291, 293, + 295, 297, 299, 301, 303, 305, 307, 309, 311, 313, 315, 317, 319, 321, 323, + 325, 327, 329, 331, 333, 335, 337, 339, 341, 343, 345, 347, 349, 351, +#if defined(CUSTOM_MODES) + /*...208:*/ + 353, 355, 357, 359, 361, 363, 365, 367, 369, 371, 373, 375, 377, 379, 381, + 383, 385, 387, 389, 391, 393, 395, 397, 399, 401, 403, 405, 407, 409, 411, + 413, 415, +#endif + /*N=3, K=3...176:*/ + 13, 25, 41, 61, 85, 113, 145, 181, 221, 265, 313, 365, 421, 481, 545, 613, + 685, 761, 841, 925, 1013, 1105, 1201, 1301, 1405, 1513, 1625, 1741, 1861, + 1985, 2113, 2245, 2381, 2521, 2665, 2813, 2965, 3121, 3281, 3445, 3613, 3785, + 3961, 4141, 4325, 4513, 4705, 4901, 5101, 5305, 5513, 5725, 5941, 6161, 6385, + 6613, 6845, 7081, 7321, 7565, 7813, 8065, 8321, 8581, 8845, 9113, 9385, 9661, + 9941, 10225, 10513, 10805, 11101, 11401, 11705, 12013, 12325, 12641, 12961, + 13285, 13613, 13945, 14281, 14621, 14965, 15313, 15665, 16021, 16381, 16745, + 17113, 17485, 17861, 18241, 18625, 19013, 19405, 19801, 20201, 20605, 21013, + 21425, 21841, 22261, 22685, 23113, 23545, 23981, 24421, 24865, 25313, 25765, + 26221, 26681, 27145, 27613, 28085, 28561, 29041, 29525, 30013, 30505, 31001, + 31501, 32005, 32513, 33025, 33541, 34061, 34585, 35113, 35645, 36181, 36721, + 37265, 37813, 38365, 38921, 39481, 40045, 40613, 41185, 41761, 42341, 42925, + 43513, 44105, 44701, 45301, 45905, 46513, 47125, 47741, 48361, 48985, 49613, + 50245, 50881, 51521, 52165, 52813, 53465, 54121, 54781, 55445, 56113, 56785, + 57461, 58141, 58825, 59513, 60205, 60901, 61601, +#if defined(CUSTOM_MODES) + /*...208:*/ + 62305, 63013, 63725, 64441, 65161, 65885, 66613, 67345, 68081, 68821, 69565, + 70313, 71065, 71821, 72581, 73345, 74113, 74885, 75661, 76441, 77225, 78013, + 78805, 79601, 80401, 81205, 82013, 82825, 83641, 84461, 85285, 86113, +#endif + /*N=4, K=4...176:*/ + 63, 129, 231, 377, 575, 833, 1159, 1561, 2047, 2625, 3303, 4089, 4991, 6017, + 7175, 8473, 9919, 11521, 13287, 15225, 17343, 19649, 22151, 24857, 27775, + 30913, 34279, 37881, 41727, 45825, 50183, 54809, 59711, 64897, 70375, 76153, + 82239, 88641, 95367, 102425, 109823, 117569, 125671, 134137, 142975, 152193, + 161799, 171801, 182207, 193025, 204263, 215929, 228031, 240577, 253575, + 267033, 280959, 295361, 310247, 325625, 341503, 357889, 374791, 392217, + 410175, 428673, 447719, 467321, 487487, 508225, 529543, 551449, 573951, + 597057, 620775, 645113, 670079, 695681, 721927, 748825, 776383, 804609, + 833511, 863097, 893375, 924353, 956039, 988441, 1021567, 1055425, 1090023, + 1125369, 1161471, 1198337, 1235975, 1274393, 1313599, 1353601, 1394407, + 1436025, 1478463, 1521729, 1565831, 1610777, 1656575, 1703233, 1750759, + 1799161, 1848447, 1898625, 1949703, 2001689, 2054591, 2108417, 2163175, + 2218873, 2275519, 2333121, 2391687, 2451225, 2511743, 2573249, 2635751, + 2699257, 2763775, 2829313, 2895879, 2963481, 3032127, 3101825, 3172583, + 3244409, 3317311, 3391297, 3466375, 3542553, 3619839, 3698241, 3777767, + 3858425, 3940223, 4023169, 4107271, 4192537, 4278975, 4366593, 4455399, + 4545401, 4636607, 4729025, 4822663, 4917529, 5013631, 5110977, 5209575, + 5309433, 5410559, 5512961, 5616647, 5721625, 5827903, 5935489, 6044391, + 6154617, 6266175, 6379073, 6493319, 6608921, 6725887, 6844225, 6963943, + 7085049, 7207551, +#if defined(CUSTOM_MODES) + /*...208:*/ + 7331457, 7456775, 7583513, 7711679, 7841281, 7972327, 8104825, 8238783, + 8374209, 8511111, 8649497, 8789375, 8930753, 9073639, 9218041, 9363967, + 9511425, 9660423, 9810969, 9963071, 10116737, 10271975, 10428793, 10587199, + 10747201, 10908807, 11072025, 11236863, 11403329, 11571431, 11741177, + 11912575, +#endif + /*N=5, K=5...176:*/ + 321, 681, 1289, 2241, 3649, 5641, 8361, 11969, 16641, 22569, 29961, 39041, + 50049, 63241, 78889, 97281, 118721, 143529, 172041, 204609, 241601, 283401, + 330409, 383041, 441729, 506921, 579081, 658689, 746241, 842249, 947241, + 1061761, 1186369, 1321641, 1468169, 1626561, 1797441, 1981449, 2179241, + 2391489, 2618881, 2862121, 3121929, 3399041, 3694209, 4008201, 4341801, + 4695809, 5071041, 5468329, 5888521, 6332481, 6801089, 7295241, 7815849, + 8363841, 8940161, 9545769, 10181641, 10848769, 11548161, 12280841, 13047849, + 13850241, 14689089, 15565481, 16480521, 17435329, 18431041, 19468809, + 20549801, 21675201, 22846209, 24064041, 25329929, 26645121, 28010881, + 29428489, 30899241, 32424449, 34005441, 35643561, 37340169, 39096641, + 40914369, 42794761, 44739241, 46749249, 48826241, 50971689, 53187081, + 55473921, 57833729, 60268041, 62778409, 65366401, 68033601, 70781609, + 73612041, 76526529, 79526721, 82614281, 85790889, 89058241, 92418049, + 95872041, 99421961, 103069569, 106816641, 110664969, 114616361, 118672641, + 122835649, 127107241, 131489289, 135983681, 140592321, 145317129, 150160041, + 155123009, 160208001, 165417001, 170752009, 176215041, 181808129, 187533321, + 193392681, 199388289, 205522241, 211796649, 218213641, 224775361, 231483969, + 238341641, 245350569, 252512961, 259831041, 267307049, 274943241, 282741889, + 290705281, 298835721, 307135529, 315607041, 324252609, 333074601, 342075401, + 351257409, 360623041, 370174729, 379914921, 389846081, 399970689, 410291241, + 420810249, 431530241, 442453761, 453583369, 464921641, 476471169, 488234561, + 500214441, 512413449, 524834241, 537479489, 550351881, 563454121, 576788929, + 590359041, 604167209, 618216201, 632508801, +#if defined(CUSTOM_MODES) + /*...208:*/ + 647047809, 661836041, 676876329, 692171521, 707724481, 723538089, 739615241, + 755958849, 772571841, 789457161, 806617769, 824056641, 841776769, 859781161, + 878072841, 896654849, 915530241, 934702089, 954173481, 973947521, 994027329, + 1014416041, 1035116809, 1056132801, 1077467201, 1099123209, 1121104041, + 1143412929, 1166053121, 1189027881, 1212340489, 1235994241, +#endif + /*N=6, K=6...96:*/ + 1683, 3653, 7183, 13073, 22363, 36365, 56695, 85305, 124515, 177045, 246047, + 335137, 448427, 590557, 766727, 982729, 1244979, 1560549, 1937199, 2383409, + 2908411, 3522221, 4235671, 5060441, 6009091, 7095093, 8332863, 9737793, + 11326283, 13115773, 15124775, 17372905, 19880915, 22670725, 25765455, + 29189457, 32968347, 37129037, 41699767, 46710137, 52191139, 58175189, + 64696159, 71789409, 79491819, 87841821, 96879431, 106646281, 117185651, + 128542501, 140763503, 153897073, 167993403, 183104493, 199284183, 216588185, + 235074115, 254801525, 275831935, 298228865, 322057867, 347386557, 374284647, + 402823977, 433078547, 465124549, 499040399, 534906769, 572806619, 612825229, + 655050231, 699571641, 746481891, 795875861, 847850911, 902506913, 959946283, + 1020274013, 1083597703, 1150027593, 1219676595, 1292660325, 1369097135, + 1449108145, 1532817275, 1620351277, 1711839767, 1807415257, 1907213187, + 2011371957, 2120032959, +#if defined(CUSTOM_MODES) + /*...109:*/ + 2233340609U, 2351442379U, 2474488829U, 2602633639U, 2736033641U, 2874848851U, + 3019242501U, 3169381071U, 3325434321U, 3487575323U, 3655980493U, 3830829623U, + 4012305913U, +#endif + /*N=7, K=7...54*/ + 8989, 19825, 40081, 75517, 134245, 227305, 369305, 579125, 880685, 1303777, + 1884961, 2668525, 3707509, 5064793, 6814249, 9041957, 11847485, 15345233, + 19665841, 24957661, 31388293, 39146185, 48442297, 59511829, 72616013, + 88043969, 106114625, 127178701, 151620757, 179861305, 212358985, 249612805, + 292164445, 340600625, 395555537, 457713341, 527810725, 606639529, 695049433, + 793950709, 904317037, 1027188385, 1163673953, 1314955181, 1482288821, + 1667010073, 1870535785, 2094367717, +#if defined(CUSTOM_MODES) + /*...60:*/ + 2340095869U, 2609401873U, 2904062449U, 3225952925U, 3577050821U, 3959439497U, +#endif + /*N=8, K=8...37*/ + 48639, 108545, 224143, 433905, 795455, 1392065, 2340495, 3800305, 5984767, + 9173505, 13726991, 20103025, 28875327, 40754369, 56610575, 77500017, + 104692735, 139703809, 184327311, 240673265, 311207743, 398796225, 506750351, + 638878193, 799538175, 993696769, 1226990095, 1505789553, 1837271615, + 2229491905U, +#if defined(CUSTOM_MODES) + /*...40:*/ + 2691463695U, 3233240945U, 3866006015U, +#endif + /*N=9, K=9...28:*/ + 265729, 598417, 1256465, 2485825, 4673345, 8405905, 14546705, 24331777, + 39490049, 62390545, 96220561, 145198913, 214828609, 312193553, 446304145, + 628496897, 872893441, 1196924561, 1621925137, 2173806145U, +#if defined(CUSTOM_MODES) + /*...29:*/ + 2883810113U, +#endif + /*N=10, K=10...24:*/ + 1462563, 3317445, 7059735, 14218905, 27298155, 50250765, 89129247, 152951073, + 254831667, 413442773, 654862247, 1014889769, 1541911931, 2300409629U, + 3375210671U, + /*N=11, K=11...19:*/ + 8097453, 18474633, 39753273, 81270333, 158819253, 298199265, 540279585, + 948062325, 1616336765, +#if defined(CUSTOM_MODES) + /*...20:*/ + 2684641785U, +#endif + /*N=12, K=12...18:*/ + 45046719, 103274625, 224298231, 464387817, 921406335, 1759885185, + 3248227095U, + /*N=13, K=13...16:*/ + 251595969, 579168825, 1267854873, 2653649025U, + /*N=14, K=14:*/ + 1409933619 +}; + +#if defined(CUSTOM_MODES) +static const opus_uint32 *const CELT_PVQ_U_ROW[15]={ + CELT_PVQ_U_DATA+ 0,CELT_PVQ_U_DATA+ 208,CELT_PVQ_U_DATA+ 415, + CELT_PVQ_U_DATA+ 621,CELT_PVQ_U_DATA+ 826,CELT_PVQ_U_DATA+1030, + CELT_PVQ_U_DATA+1233,CELT_PVQ_U_DATA+1336,CELT_PVQ_U_DATA+1389, + CELT_PVQ_U_DATA+1421,CELT_PVQ_U_DATA+1441,CELT_PVQ_U_DATA+1455, + CELT_PVQ_U_DATA+1464,CELT_PVQ_U_DATA+1470,CELT_PVQ_U_DATA+1473 +}; +#else +static const opus_uint32 *const CELT_PVQ_U_ROW[15]={ + CELT_PVQ_U_DATA+ 0,CELT_PVQ_U_DATA+ 176,CELT_PVQ_U_DATA+ 351, + CELT_PVQ_U_DATA+ 525,CELT_PVQ_U_DATA+ 698,CELT_PVQ_U_DATA+ 870, + CELT_PVQ_U_DATA+1041,CELT_PVQ_U_DATA+1131,CELT_PVQ_U_DATA+1178, + CELT_PVQ_U_DATA+1207,CELT_PVQ_U_DATA+1226,CELT_PVQ_U_DATA+1240, + CELT_PVQ_U_DATA+1248,CELT_PVQ_U_DATA+1254,CELT_PVQ_U_DATA+1257 +}; +#endif + +#if defined(CUSTOM_MODES) +void get_required_bits(opus_int16 *_bits,int _n,int _maxk,int _frac){ + int k; + /*_maxk==0 => there's nothing to do.*/ + celt_assert(_maxk>0); + _bits[0]=0; + for(k=1;k<=_maxk;k++)_bits[k]=log2_frac(CELT_PVQ_V(_n,k),_frac); +} +#endif + +static opus_uint32 icwrs(int _n,const int *_y){ + opus_uint32 i; + int j; + int k; + celt_assert(_n>=2); + j=_n-1; + i=_y[j]<0; + k=abs(_y[j]); + do{ + j--; + i+=CELT_PVQ_U(_n-j,k); + k+=abs(_y[j]); + if(_y[j]<0)i+=CELT_PVQ_U(_n-j,k+1); + } + while(j>0); + return i; +} + +void encode_pulses(const int *_y,int _n,int _k,ec_enc *_enc){ + celt_assert(_k>0); + ec_enc_uint(_enc,icwrs(_n,_y),CELT_PVQ_V(_n,_k)); +} + +static void cwrsi(int _n,int _k,opus_uint32 _i,int *_y){ + opus_uint32 p; + int s; + int k0; + celt_assert(_k>0); + celt_assert(_n>1); + while(_n>2){ + opus_uint32 q; + /*Lots of pulses case:*/ + if(_k>=_n){ + const opus_uint32 *row; + row=CELT_PVQ_U_ROW[_n]; + /*Are the pulses in this dimension negative?*/ + p=row[_k+1]; + s=-(_i>=p); + _i-=p&s; + /*Count how many pulses were placed in this dimension.*/ + k0=_k; + q=row[_n]; + if(q>_i){ + celt_assert(p>q); + _k=_n; + do p=CELT_PVQ_U_ROW[--_k][_n]; + while(p>_i); + } + else for(p=row[_k];p>_i;p=row[_k])_k--; + _i-=p; + *_y++=(k0-_k+s)^s; + } + /*Lots of dimensions case:*/ + else{ + /*Are there any pulses in this dimension at all?*/ + p=CELT_PVQ_U_ROW[_k][_n]; + q=CELT_PVQ_U_ROW[_k+1][_n]; + if(p<=_i&&_i=q); + _i-=q&s; + /*Count how many pulses were placed in this dimension.*/ + k0=_k; + do p=CELT_PVQ_U_ROW[--_k][_n]; + while(p>_i); + _i-=p; + *_y++=(k0-_k+s)^s; + } + } + _n--; + } + /*_n==2*/ + p=2*_k+1; + s=-(_i>=p); + _i-=p&s; + k0=_k; + _k=(_i+1)>>1; + if(_k)_i-=2*_k-1; + *_y++=(k0-_k+s)^s; + /*_n==1*/ + s=-(int)_i; + *_y=(_k+s)^s; +} + +void decode_pulses(int *_y,int _n,int _k,ec_dec *_dec){ + cwrsi(_n,_k,ec_dec_uint(_dec,CELT_PVQ_V(_n,_k)),_y); +} + +#else /* SMALL_FOOTPRINT */ + +/*Computes the next row/column of any recurrence that obeys the relation + u[i][j]=u[i-1][j]+u[i][j-1]+u[i-1][j-1]. + _ui0 is the base case for the new row/column.*/ +static OPUS_INLINE void unext(opus_uint32 *_ui,unsigned _len,opus_uint32 _ui0){ + opus_uint32 ui1; + unsigned j; + /*This do-while will overrun the array if we don't have storage for at least + 2 values.*/ + j=1; do { + ui1=UADD32(UADD32(_ui[j],_ui[j-1]),_ui0); + _ui[j-1]=_ui0; + _ui0=ui1; + } while (++j<_len); + _ui[j-1]=_ui0; +} + +/*Computes the previous row/column of any recurrence that obeys the relation + u[i-1][j]=u[i][j]-u[i][j-1]-u[i-1][j-1]. + _ui0 is the base case for the new row/column.*/ +static OPUS_INLINE void uprev(opus_uint32 *_ui,unsigned _n,opus_uint32 _ui0){ + opus_uint32 ui1; + unsigned j; + /*This do-while will overrun the array if we don't have storage for at least + 2 values.*/ + j=1; do { + ui1=USUB32(USUB32(_ui[j],_ui[j-1]),_ui0); + _ui[j-1]=_ui0; + _ui0=ui1; + } while (++j<_n); + _ui[j-1]=_ui0; +} + +/*Compute V(_n,_k), as well as U(_n,0..._k+1). + _u: On exit, _u[i] contains U(_n,i) for i in [0..._k+1].*/ +static opus_uint32 ncwrs_urow(unsigned _n,unsigned _k,opus_uint32 *_u){ + opus_uint32 um2; + unsigned len; + unsigned k; + len=_k+2; + /*We require storage at least 3 values (e.g., _k>0).*/ + celt_assert(len>=3); + _u[0]=0; + _u[1]=um2=1; + /*If _n==0, _u[0] should be 1 and the rest should be 0.*/ + /*If _n==1, _u[i] should be 1 for i>1.*/ + celt_assert(_n>=2); + /*If _k==0, the following do-while loop will overflow the buffer.*/ + celt_assert(_k>0); + k=2; + do _u[k]=(k<<1)-1; + while(++k0); + j=0; + do{ + opus_uint32 p; + int s; + int yj; + p=_u[_k+1]; + s=-(_i>=p); + _i-=p&s; + yj=_k; + p=_u[_k]; + while(p>_i)p=_u[--_k]; + _i-=p; + yj-=_k; + _y[j]=(yj+s)^s; + uprev(_u,_k+2,0); + } + while(++j<_n); +} + +/*Returns the index of the given combination of K elements chosen from a set + of size 1 with associated sign bits. + _y: The vector of pulses, whose sum of absolute values is K. + _k: Returns K.*/ +static OPUS_INLINE opus_uint32 icwrs1(const int *_y,int *_k){ + *_k=abs(_y[0]); + return _y[0]<0; +} + +/*Returns the index of the given combination of K elements chosen from a set + of size _n with associated sign bits. + _y: The vector of pulses, whose sum of absolute values must be _k. + _nc: Returns V(_n,_k).*/ +static OPUS_INLINE opus_uint32 icwrs(int _n,int _k,opus_uint32 *_nc,const int *_y, + opus_uint32 *_u){ + opus_uint32 i; + int j; + int k; + /*We can't unroll the first two iterations of the loop unless _n>=2.*/ + celt_assert(_n>=2); + _u[0]=0; + for(k=1;k<=_k+1;k++)_u[k]=(k<<1)-1; + i=icwrs1(_y+_n-1,&k); + j=_n-2; + i+=_u[k]; + k+=abs(_y[j]); + if(_y[j]<0)i+=_u[k+1]; + while(j-->0){ + unext(_u,_k+2,0); + i+=_u[k]; + k+=abs(_y[j]); + if(_y[j]<0)i+=_u[k+1]; + } + *_nc=_u[k]+_u[k+1]; + return i; +} + +#ifdef CUSTOM_MODES +void get_required_bits(opus_int16 *_bits,int _n,int _maxk,int _frac){ + int k; + /*_maxk==0 => there's nothing to do.*/ + celt_assert(_maxk>0); + _bits[0]=0; + if (_n==1) + { + for (k=1;k<=_maxk;k++) + _bits[k] = 1<<_frac; + } + else { + VARDECL(opus_uint32,u); + SAVE_STACK; + ALLOC(u,_maxk+2U,opus_uint32); + ncwrs_urow(_n,_maxk,u); + for(k=1;k<=_maxk;k++) + _bits[k]=log2_frac(u[k]+u[k+1],_frac); + RESTORE_STACK; + } +} +#endif /* CUSTOM_MODES */ + +void encode_pulses(const int *_y,int _n,int _k,ec_enc *_enc){ + opus_uint32 i; + VARDECL(opus_uint32,u); + opus_uint32 nc; + SAVE_STACK; + celt_assert(_k>0); + ALLOC(u,_k+2U,opus_uint32); + i=icwrs(_n,_k,&nc,_y,u); + ec_enc_uint(_enc,i,nc); + RESTORE_STACK; +} + +void decode_pulses(int *_y,int _n,int _k,ec_dec *_dec){ + VARDECL(opus_uint32,u); + SAVE_STACK; + celt_assert(_k>0); + ALLOC(u,_k+2U,opus_uint32); + cwrsi(_n,_k,ec_dec_uint(_dec,ncwrs_urow(_n,_k,u)),_y,u); + RESTORE_STACK; +} + +#endif /* SMALL_FOOTPRINT */ diff --git a/src/opus-1.1/celt/cwrs.h b/src/opus-1.1/celt/cwrs.h new file mode 100644 index 00000000..7dfbd076 --- /dev/null +++ b/src/opus-1.1/celt/cwrs.h @@ -0,0 +1,48 @@ +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation + Copyright (c) 2007-2009 Timothy B. Terriberry + Written by Timothy B. Terriberry and Jean-Marc Valin */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef CWRS_H +#define CWRS_H + +#include "arch.h" +#include "stack_alloc.h" +#include "entenc.h" +#include "entdec.h" + +#ifdef CUSTOM_MODES +int log2_frac(opus_uint32 val, int frac); +#endif + +void get_required_bits(opus_int16 *bits, int N, int K, int frac); + +void encode_pulses(const int *_y, int N, int K, ec_enc *enc); + +void decode_pulses(int *_y, int N, int K, ec_dec *dec); + +#endif /* CWRS_H */ diff --git a/src/opus-1.1/celt/ecintrin.h b/src/opus-1.1/celt/ecintrin.h new file mode 100644 index 00000000..2263cff6 --- /dev/null +++ b/src/opus-1.1/celt/ecintrin.h @@ -0,0 +1,87 @@ +/* Copyright (c) 2003-2008 Timothy B. Terriberry + Copyright (c) 2008 Xiph.Org Foundation */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/*Some common macros for potential platform-specific optimization.*/ +#include "opus_types.h" +#include +#include +#include "arch.h" +#if !defined(_ecintrin_H) +# define _ecintrin_H (1) + +/*Some specific platforms may have optimized intrinsic or OPUS_INLINE assembly + versions of these functions which can substantially improve performance. + We define macros for them to allow easy incorporation of these non-ANSI + features.*/ + +/*Modern gcc (4.x) can compile the naive versions of min and max with cmov if + given an appropriate architecture, but the branchless bit-twiddling versions + are just as fast, and do not require any special target architecture. + Earlier gcc versions (3.x) compiled both code to the same assembly + instructions, because of the way they represented ((_b)>(_a)) internally.*/ +# define EC_MINI(_a,_b) ((_a)+(((_b)-(_a))&-((_b)<(_a)))) + +/*Count leading zeros. + This macro should only be used for implementing ec_ilog(), if it is defined. + All other code should use EC_ILOG() instead.*/ +#if defined(_MSC_VER) && (_MSC_VER >= 1400) +# include +/*In _DEBUG mode this is not an intrinsic by default.*/ +# pragma intrinsic(_BitScanReverse) + +static __inline int ec_bsr(unsigned long _x){ + unsigned long ret; + _BitScanReverse(&ret,_x); + return (int)ret; +} +# define EC_CLZ0 (1) +# define EC_CLZ(_x) (-ec_bsr(_x)) +#elif defined(ENABLE_TI_DSPLIB) +# include "dsplib.h" +# define EC_CLZ0 (31) +# define EC_CLZ(_x) (_lnorm(_x)) +#elif __GNUC_PREREQ(3,4) +# if INT_MAX>=2147483647 +# define EC_CLZ0 ((int)sizeof(unsigned)*CHAR_BIT) +# define EC_CLZ(_x) (__builtin_clz(_x)) +# elif LONG_MAX>=2147483647L +# define EC_CLZ0 ((int)sizeof(unsigned long)*CHAR_BIT) +# define EC_CLZ(_x) (__builtin_clzl(_x)) +# endif +#endif + +#if defined(EC_CLZ) +/*Note that __builtin_clz is not defined when _x==0, according to the gcc + documentation (and that of the BSR instruction that implements it on x86). + The majority of the time we can never pass it zero. + When we need to, it can be special cased.*/ +# define EC_ILOG(_x) (EC_CLZ0-EC_CLZ(_x)) +#else +int ec_ilog(opus_uint32 _v); +# define EC_ILOG(_x) (ec_ilog(_x)) +#endif +#endif diff --git a/src/opus-1.1/celt/entcode.c b/src/opus-1.1/celt/entcode.c new file mode 100644 index 00000000..fa5d7c7c --- /dev/null +++ b/src/opus-1.1/celt/entcode.c @@ -0,0 +1,93 @@ +/* Copyright (c) 2001-2011 Timothy B. Terriberry +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "entcode.h" +#include "arch.h" + +#if !defined(EC_CLZ) +/*This is a fallback for systems where we don't know how to access + a BSR or CLZ instruction (see ecintrin.h). + If you are optimizing Opus on a new platform and it has a native CLZ or + BZR (e.g. cell, MIPS, x86, etc) then making it available to Opus will be + an easy performance win.*/ +int ec_ilog(opus_uint32 _v){ + /*On a Pentium M, this branchless version tested as the fastest on + 1,000,000,000 random 32-bit integers, edging out a similar version with + branches, and a 256-entry LUT version.*/ + int ret; + int m; + ret=!!_v; + m=!!(_v&0xFFFF0000)<<4; + _v>>=m; + ret|=m; + m=!!(_v&0xFF00)<<3; + _v>>=m; + ret|=m; + m=!!(_v&0xF0)<<2; + _v>>=m; + ret|=m; + m=!!(_v&0xC)<<1; + _v>>=m; + ret|=m; + ret+=!!(_v&0x2); + return ret; +} +#endif + +opus_uint32 ec_tell_frac(ec_ctx *_this){ + opus_uint32 nbits; + opus_uint32 r; + int l; + int i; + /*To handle the non-integral number of bits still left in the encoder/decoder + state, we compute the worst-case number of bits of val that must be + encoded to ensure that the value is inside the range for any possible + subsequent bits. + The computation here is independent of val itself (the decoder does not + even track that value), even though the real number of bits used after + ec_enc_done() may be 1 smaller if rng is a power of two and the + corresponding trailing bits of val are all zeros. + If we did try to track that special case, then coding a value with a + probability of 1/(1<nbits_total<rng); + r=_this->rng>>(l-16); + for(i=BITRES;i-->0;){ + int b; + r=r*r>>15; + b=(int)(r>>16); + l=l<<1|b; + r>>=b; + } + return nbits-l; +} diff --git a/src/opus-1.1/celt/entcode.h b/src/opus-1.1/celt/entcode.h new file mode 100644 index 00000000..dd13e49e --- /dev/null +++ b/src/opus-1.1/celt/entcode.h @@ -0,0 +1,117 @@ +/* Copyright (c) 2001-2011 Timothy B. Terriberry + Copyright (c) 2008-2009 Xiph.Org Foundation */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "opus_types.h" +#include "opus_defines.h" + +#if !defined(_entcode_H) +# define _entcode_H (1) +# include +# include +# include "ecintrin.h" + +/*OPT: ec_window must be at least 32 bits, but if you have fast arithmetic on a + larger type, you can speed up the decoder by using it here.*/ +typedef opus_uint32 ec_window; +typedef struct ec_ctx ec_ctx; +typedef struct ec_ctx ec_enc; +typedef struct ec_ctx ec_dec; + +# define EC_WINDOW_SIZE ((int)sizeof(ec_window)*CHAR_BIT) + +/*The number of bits to use for the range-coded part of unsigned integers.*/ +# define EC_UINT_BITS (8) + +/*The resolution of fractional-precision bit usage measurements, i.e., + 3 => 1/8th bits.*/ +# define BITRES 3 + +/*The entropy encoder/decoder context. + We use the same structure for both, so that common functions like ec_tell() + can be used on either one.*/ +struct ec_ctx{ + /*Buffered input/output.*/ + unsigned char *buf; + /*The size of the buffer.*/ + opus_uint32 storage; + /*The offset at which the last byte containing raw bits was read/written.*/ + opus_uint32 end_offs; + /*Bits that will be read from/written at the end.*/ + ec_window end_window; + /*Number of valid bits in end_window.*/ + int nend_bits; + /*The total number of whole bits read/written. + This does not include partial bits currently in the range coder.*/ + int nbits_total; + /*The offset at which the next range coder byte will be read/written.*/ + opus_uint32 offs; + /*The number of values in the current range.*/ + opus_uint32 rng; + /*In the decoder: the difference between the top of the current range and + the input value, minus one. + In the encoder: the low end of the current range.*/ + opus_uint32 val; + /*In the decoder: the saved normalization factor from ec_decode(). + In the encoder: the number of oustanding carry propagating symbols.*/ + opus_uint32 ext; + /*A buffered input/output symbol, awaiting carry propagation.*/ + int rem; + /*Nonzero if an error occurred.*/ + int error; +}; + +static OPUS_INLINE opus_uint32 ec_range_bytes(ec_ctx *_this){ + return _this->offs; +} + +static OPUS_INLINE unsigned char *ec_get_buffer(ec_ctx *_this){ + return _this->buf; +} + +static OPUS_INLINE int ec_get_error(ec_ctx *_this){ + return _this->error; +} + +/*Returns the number of bits "used" by the encoded or decoded symbols so far. + This same number can be computed in either the encoder or the decoder, and is + suitable for making coding decisions. + Return: The number of bits. + This will always be slightly larger than the exact value (e.g., all + rounding error is in the positive direction).*/ +static OPUS_INLINE int ec_tell(ec_ctx *_this){ + return _this->nbits_total-EC_ILOG(_this->rng); +} + +/*Returns the number of bits "used" by the encoded or decoded symbols so far. + This same number can be computed in either the encoder or the decoder, and is + suitable for making coding decisions. + Return: The number of bits scaled by 2**BITRES. + This will always be slightly larger than the exact value (e.g., all + rounding error is in the positive direction).*/ +opus_uint32 ec_tell_frac(ec_ctx *_this); + +#endif diff --git a/src/opus-1.1/celt/entdec.c b/src/opus-1.1/celt/entdec.c new file mode 100644 index 00000000..3c264685 --- /dev/null +++ b/src/opus-1.1/celt/entdec.c @@ -0,0 +1,245 @@ +/* Copyright (c) 2001-2011 Timothy B. Terriberry + Copyright (c) 2008-2009 Xiph.Org Foundation */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "os_support.h" +#include "arch.h" +#include "entdec.h" +#include "mfrngcod.h" + +/*A range decoder. + This is an entropy decoder based upon \cite{Mar79}, which is itself a + rediscovery of the FIFO arithmetic code introduced by \cite{Pas76}. + It is very similar to arithmetic encoding, except that encoding is done with + digits in any base, instead of with bits, and so it is faster when using + larger bases (i.e.: a byte). + The author claims an average waste of $\frac{1}{2}\log_b(2b)$ bits, where $b$ + is the base, longer than the theoretical optimum, but to my knowledge there + is no published justification for this claim. + This only seems true when using near-infinite precision arithmetic so that + the process is carried out with no rounding errors. + + An excellent description of implementation details is available at + http://www.arturocampos.com/ac_range.html + A recent work \cite{MNW98} which proposes several changes to arithmetic + encoding for efficiency actually re-discovers many of the principles + behind range encoding, and presents a good theoretical analysis of them. + + End of stream is handled by writing out the smallest number of bits that + ensures that the stream will be correctly decoded regardless of the value of + any subsequent bits. + ec_tell() can be used to determine how many bits were needed to decode + all the symbols thus far; other data can be packed in the remaining bits of + the input buffer. + @PHDTHESIS{Pas76, + author="Richard Clark Pasco", + title="Source coding algorithms for fast data compression", + school="Dept. of Electrical Engineering, Stanford University", + address="Stanford, CA", + month=May, + year=1976 + } + @INPROCEEDINGS{Mar79, + author="Martin, G.N.N.", + title="Range encoding: an algorithm for removing redundancy from a digitised + message", + booktitle="Video & Data Recording Conference", + year=1979, + address="Southampton", + month=Jul + } + @ARTICLE{MNW98, + author="Alistair Moffat and Radford Neal and Ian H. Witten", + title="Arithmetic Coding Revisited", + journal="{ACM} Transactions on Information Systems", + year=1998, + volume=16, + number=3, + pages="256--294", + month=Jul, + URL="http://www.stanford.edu/class/ee398a/handouts/papers/Moffat98ArithmCoding.pdf" + }*/ + +static int ec_read_byte(ec_dec *_this){ + return _this->offs<_this->storage?_this->buf[_this->offs++]:0; +} + +static int ec_read_byte_from_end(ec_dec *_this){ + return _this->end_offs<_this->storage? + _this->buf[_this->storage-++(_this->end_offs)]:0; +} + +/*Normalizes the contents of val and rng so that rng lies entirely in the + high-order symbol.*/ +static void ec_dec_normalize(ec_dec *_this){ + /*If the range is too small, rescale it and input some bits.*/ + while(_this->rng<=EC_CODE_BOT){ + int sym; + _this->nbits_total+=EC_SYM_BITS; + _this->rng<<=EC_SYM_BITS; + /*Use up the remaining bits from our last symbol.*/ + sym=_this->rem; + /*Read the next value from the input.*/ + _this->rem=ec_read_byte(_this); + /*Take the rest of the bits we need from this new symbol.*/ + sym=(sym<rem)>>(EC_SYM_BITS-EC_CODE_EXTRA); + /*And subtract them from val, capped to be less than EC_CODE_TOP.*/ + _this->val=((_this->val<buf=_buf; + _this->storage=_storage; + _this->end_offs=0; + _this->end_window=0; + _this->nend_bits=0; + /*This is the offset from which ec_tell() will subtract partial bits. + The final value after the ec_dec_normalize() call will be the same as in + the encoder, but we have to compensate for the bits that are added there.*/ + _this->nbits_total=EC_CODE_BITS+1 + -((EC_CODE_BITS-EC_CODE_EXTRA)/EC_SYM_BITS)*EC_SYM_BITS; + _this->offs=0; + _this->rng=1U<rem=ec_read_byte(_this); + _this->val=_this->rng-1-(_this->rem>>(EC_SYM_BITS-EC_CODE_EXTRA)); + _this->error=0; + /*Normalize the interval.*/ + ec_dec_normalize(_this); +} + +unsigned ec_decode(ec_dec *_this,unsigned _ft){ + unsigned s; + _this->ext=_this->rng/_ft; + s=(unsigned)(_this->val/_this->ext); + return _ft-EC_MINI(s+1,_ft); +} + +unsigned ec_decode_bin(ec_dec *_this,unsigned _bits){ + unsigned s; + _this->ext=_this->rng>>_bits; + s=(unsigned)(_this->val/_this->ext); + return (1U<<_bits)-EC_MINI(s+1U,1U<<_bits); +} + +void ec_dec_update(ec_dec *_this,unsigned _fl,unsigned _fh,unsigned _ft){ + opus_uint32 s; + s=IMUL32(_this->ext,_ft-_fh); + _this->val-=s; + _this->rng=_fl>0?IMUL32(_this->ext,_fh-_fl):_this->rng-s; + ec_dec_normalize(_this); +} + +/*The probability of having a "one" is 1/(1<<_logp).*/ +int ec_dec_bit_logp(ec_dec *_this,unsigned _logp){ + opus_uint32 r; + opus_uint32 d; + opus_uint32 s; + int ret; + r=_this->rng; + d=_this->val; + s=r>>_logp; + ret=dval=d-s; + _this->rng=ret?s:r-s; + ec_dec_normalize(_this); + return ret; +} + +int ec_dec_icdf(ec_dec *_this,const unsigned char *_icdf,unsigned _ftb){ + opus_uint32 r; + opus_uint32 d; + opus_uint32 s; + opus_uint32 t; + int ret; + s=_this->rng; + d=_this->val; + r=s>>_ftb; + ret=-1; + do{ + t=s; + s=IMUL32(r,_icdf[++ret]); + } + while(dval=d-s; + _this->rng=t-s; + ec_dec_normalize(_this); + return ret; +} + +opus_uint32 ec_dec_uint(ec_dec *_this,opus_uint32 _ft){ + unsigned ft; + unsigned s; + int ftb; + /*In order to optimize EC_ILOG(), it is undefined for the value 0.*/ + celt_assert(_ft>1); + _ft--; + ftb=EC_ILOG(_ft); + if(ftb>EC_UINT_BITS){ + opus_uint32 t; + ftb-=EC_UINT_BITS; + ft=(unsigned)(_ft>>ftb)+1; + s=ec_decode(_this,ft); + ec_dec_update(_this,s,s+1,ft); + t=(opus_uint32)s<error=1; + return _ft; + } + else{ + _ft++; + s=ec_decode(_this,(unsigned)_ft); + ec_dec_update(_this,s,s+1,(unsigned)_ft); + return s; + } +} + +opus_uint32 ec_dec_bits(ec_dec *_this,unsigned _bits){ + ec_window window; + int available; + opus_uint32 ret; + window=_this->end_window; + available=_this->nend_bits; + if((unsigned)available<_bits){ + do{ + window|=(ec_window)ec_read_byte_from_end(_this)<>=_bits; + available-=_bits; + _this->end_window=window; + _this->nend_bits=available; + _this->nbits_total+=_bits; + return ret; +} diff --git a/src/opus-1.1/celt/entdec.h b/src/opus-1.1/celt/entdec.h new file mode 100644 index 00000000..d8ab3187 --- /dev/null +++ b/src/opus-1.1/celt/entdec.h @@ -0,0 +1,100 @@ +/* Copyright (c) 2001-2011 Timothy B. Terriberry + Copyright (c) 2008-2009 Xiph.Org Foundation */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#if !defined(_entdec_H) +# define _entdec_H (1) +# include +# include "entcode.h" + +/*Initializes the decoder. + _buf: The input buffer to use. + Return: 0 on success, or a negative value on error.*/ +void ec_dec_init(ec_dec *_this,unsigned char *_buf,opus_uint32 _storage); + +/*Calculates the cumulative frequency for the next symbol. + This can then be fed into the probability model to determine what that + symbol is, and the additional frequency information required to advance to + the next symbol. + This function cannot be called more than once without a corresponding call to + ec_dec_update(), or decoding will not proceed correctly. + _ft: The total frequency of the symbols in the alphabet the next symbol was + encoded with. + Return: A cumulative frequency representing the encoded symbol. + If the cumulative frequency of all the symbols before the one that + was encoded was fl, and the cumulative frequency of all the symbols + up to and including the one encoded is fh, then the returned value + will fall in the range [fl,fh).*/ +unsigned ec_decode(ec_dec *_this,unsigned _ft); + +/*Equivalent to ec_decode() with _ft==1<<_bits.*/ +unsigned ec_decode_bin(ec_dec *_this,unsigned _bits); + +/*Advance the decoder past the next symbol using the frequency information the + symbol was encoded with. + Exactly one call to ec_decode() must have been made so that all necessary + intermediate calculations are performed. + _fl: The cumulative frequency of all symbols that come before the symbol + decoded. + _fh: The cumulative frequency of all symbols up to and including the symbol + decoded. + Together with _fl, this defines the range [_fl,_fh) in which the value + returned above must fall. + _ft: The total frequency of the symbols in the alphabet the symbol decoded + was encoded in. + This must be the same as passed to the preceding call to ec_decode().*/ +void ec_dec_update(ec_dec *_this,unsigned _fl,unsigned _fh,unsigned _ft); + +/* Decode a bit that has a 1/(1<<_logp) probability of being a one */ +int ec_dec_bit_logp(ec_dec *_this,unsigned _logp); + +/*Decodes a symbol given an "inverse" CDF table. + No call to ec_dec_update() is necessary after this call. + _icdf: The "inverse" CDF, such that symbol s falls in the range + [s>0?ft-_icdf[s-1]:0,ft-_icdf[s]), where ft=1<<_ftb. + The values must be monotonically non-increasing, and the last value + must be 0. + _ftb: The number of bits of precision in the cumulative distribution. + Return: The decoded symbol s.*/ +int ec_dec_icdf(ec_dec *_this,const unsigned char *_icdf,unsigned _ftb); + +/*Extracts a raw unsigned integer with a non-power-of-2 range from the stream. + The bits must have been encoded with ec_enc_uint(). + No call to ec_dec_update() is necessary after this call. + _ft: The number of integers that can be decoded (one more than the max). + This must be at least one, and no more than 2**32-1. + Return: The decoded bits.*/ +opus_uint32 ec_dec_uint(ec_dec *_this,opus_uint32 _ft); + +/*Extracts a sequence of raw bits from the stream. + The bits must have been encoded with ec_enc_bits(). + No call to ec_dec_update() is necessary after this call. + _ftb: The number of bits to extract. + This must be between 0 and 25, inclusive. + Return: The decoded bits.*/ +opus_uint32 ec_dec_bits(ec_dec *_this,unsigned _ftb); + +#endif diff --git a/src/opus-1.1/celt/entenc.c b/src/opus-1.1/celt/entenc.c new file mode 100644 index 00000000..a7e34ece --- /dev/null +++ b/src/opus-1.1/celt/entenc.c @@ -0,0 +1,294 @@ +/* Copyright (c) 2001-2011 Timothy B. Terriberry + Copyright (c) 2008-2009 Xiph.Org Foundation */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#if defined(HAVE_CONFIG_H) +# include "config.h" +#endif +#include "os_support.h" +#include "arch.h" +#include "entenc.h" +#include "mfrngcod.h" + +/*A range encoder. + See entdec.c and the references for implementation details \cite{Mar79,MNW98}. + + @INPROCEEDINGS{Mar79, + author="Martin, G.N.N.", + title="Range encoding: an algorithm for removing redundancy from a digitised + message", + booktitle="Video \& Data Recording Conference", + year=1979, + address="Southampton", + month=Jul + } + @ARTICLE{MNW98, + author="Alistair Moffat and Radford Neal and Ian H. Witten", + title="Arithmetic Coding Revisited", + journal="{ACM} Transactions on Information Systems", + year=1998, + volume=16, + number=3, + pages="256--294", + month=Jul, + URL="http://www.stanford.edu/class/ee398/handouts/papers/Moffat98ArithmCoding.pdf" + }*/ + +static int ec_write_byte(ec_enc *_this,unsigned _value){ + if(_this->offs+_this->end_offs>=_this->storage)return -1; + _this->buf[_this->offs++]=(unsigned char)_value; + return 0; +} + +static int ec_write_byte_at_end(ec_enc *_this,unsigned _value){ + if(_this->offs+_this->end_offs>=_this->storage)return -1; + _this->buf[_this->storage-++(_this->end_offs)]=(unsigned char)_value; + return 0; +} + +/*Outputs a symbol, with a carry bit. + If there is a potential to propagate a carry over several symbols, they are + buffered until it can be determined whether or not an actual carry will + occur. + If the counter for the buffered symbols overflows, then the stream becomes + undecodable. + This gives a theoretical limit of a few billion symbols in a single packet on + 32-bit systems. + The alternative is to truncate the range in order to force a carry, but + requires similar carry tracking in the decoder, needlessly slowing it down.*/ +static void ec_enc_carry_out(ec_enc *_this,int _c){ + if(_c!=EC_SYM_MAX){ + /*No further carry propagation possible, flush buffer.*/ + int carry; + carry=_c>>EC_SYM_BITS; + /*Don't output a byte on the first write. + This compare should be taken care of by branch-prediction thereafter.*/ + if(_this->rem>=0)_this->error|=ec_write_byte(_this,_this->rem+carry); + if(_this->ext>0){ + unsigned sym; + sym=(EC_SYM_MAX+carry)&EC_SYM_MAX; + do _this->error|=ec_write_byte(_this,sym); + while(--(_this->ext)>0); + } + _this->rem=_c&EC_SYM_MAX; + } + else _this->ext++; +} + +static void ec_enc_normalize(ec_enc *_this){ + /*If the range is too small, output some bits and rescale it.*/ + while(_this->rng<=EC_CODE_BOT){ + ec_enc_carry_out(_this,(int)(_this->val>>EC_CODE_SHIFT)); + /*Move the next-to-high-order symbol into the high-order position.*/ + _this->val=(_this->val<rng<<=EC_SYM_BITS; + _this->nbits_total+=EC_SYM_BITS; + } +} + +void ec_enc_init(ec_enc *_this,unsigned char *_buf,opus_uint32 _size){ + _this->buf=_buf; + _this->end_offs=0; + _this->end_window=0; + _this->nend_bits=0; + /*This is the offset from which ec_tell() will subtract partial bits.*/ + _this->nbits_total=EC_CODE_BITS+1; + _this->offs=0; + _this->rng=EC_CODE_TOP; + _this->rem=-1; + _this->val=0; + _this->ext=0; + _this->storage=_size; + _this->error=0; +} + +void ec_encode(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _ft){ + opus_uint32 r; + r=_this->rng/_ft; + if(_fl>0){ + _this->val+=_this->rng-IMUL32(r,(_ft-_fl)); + _this->rng=IMUL32(r,(_fh-_fl)); + } + else _this->rng-=IMUL32(r,(_ft-_fh)); + ec_enc_normalize(_this); +} + +void ec_encode_bin(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _bits){ + opus_uint32 r; + r=_this->rng>>_bits; + if(_fl>0){ + _this->val+=_this->rng-IMUL32(r,((1U<<_bits)-_fl)); + _this->rng=IMUL32(r,(_fh-_fl)); + } + else _this->rng-=IMUL32(r,((1U<<_bits)-_fh)); + ec_enc_normalize(_this); +} + +/*The probability of having a "one" is 1/(1<<_logp).*/ +void ec_enc_bit_logp(ec_enc *_this,int _val,unsigned _logp){ + opus_uint32 r; + opus_uint32 s; + opus_uint32 l; + r=_this->rng; + l=_this->val; + s=r>>_logp; + r-=s; + if(_val)_this->val=l+r; + _this->rng=_val?s:r; + ec_enc_normalize(_this); +} + +void ec_enc_icdf(ec_enc *_this,int _s,const unsigned char *_icdf,unsigned _ftb){ + opus_uint32 r; + r=_this->rng>>_ftb; + if(_s>0){ + _this->val+=_this->rng-IMUL32(r,_icdf[_s-1]); + _this->rng=IMUL32(r,_icdf[_s-1]-_icdf[_s]); + } + else _this->rng-=IMUL32(r,_icdf[_s]); + ec_enc_normalize(_this); +} + +void ec_enc_uint(ec_enc *_this,opus_uint32 _fl,opus_uint32 _ft){ + unsigned ft; + unsigned fl; + int ftb; + /*In order to optimize EC_ILOG(), it is undefined for the value 0.*/ + celt_assert(_ft>1); + _ft--; + ftb=EC_ILOG(_ft); + if(ftb>EC_UINT_BITS){ + ftb-=EC_UINT_BITS; + ft=(_ft>>ftb)+1; + fl=(unsigned)(_fl>>ftb); + ec_encode(_this,fl,fl+1,ft); + ec_enc_bits(_this,_fl&(((opus_uint32)1<end_window; + used=_this->nend_bits; + celt_assert(_bits>0); + if(used+_bits>EC_WINDOW_SIZE){ + do{ + _this->error|=ec_write_byte_at_end(_this,(unsigned)window&EC_SYM_MAX); + window>>=EC_SYM_BITS; + used-=EC_SYM_BITS; + } + while(used>=EC_SYM_BITS); + } + window|=(ec_window)_fl<end_window=window; + _this->nend_bits=used; + _this->nbits_total+=_bits; +} + +void ec_enc_patch_initial_bits(ec_enc *_this,unsigned _val,unsigned _nbits){ + int shift; + unsigned mask; + celt_assert(_nbits<=EC_SYM_BITS); + shift=EC_SYM_BITS-_nbits; + mask=((1<<_nbits)-1)<offs>0){ + /*The first byte has been finalized.*/ + _this->buf[0]=(unsigned char)((_this->buf[0]&~mask)|_val<rem>=0){ + /*The first byte is still awaiting carry propagation.*/ + _this->rem=(_this->rem&~mask)|_val<rng<=(EC_CODE_TOP>>_nbits)){ + /*The renormalization loop has never been run.*/ + _this->val=(_this->val&~((opus_uint32)mask<error=-1; +} + +void ec_enc_shrink(ec_enc *_this,opus_uint32 _size){ + celt_assert(_this->offs+_this->end_offs<=_size); + OPUS_MOVE(_this->buf+_size-_this->end_offs, + _this->buf+_this->storage-_this->end_offs,_this->end_offs); + _this->storage=_size; +} + +void ec_enc_done(ec_enc *_this){ + ec_window window; + int used; + opus_uint32 msk; + opus_uint32 end; + int l; + /*We output the minimum number of bits that ensures that the symbols encoded + thus far will be decoded correctly regardless of the bits that follow.*/ + l=EC_CODE_BITS-EC_ILOG(_this->rng); + msk=(EC_CODE_TOP-1)>>l; + end=(_this->val+msk)&~msk; + if((end|msk)>=_this->val+_this->rng){ + l++; + msk>>=1; + end=(_this->val+msk)&~msk; + } + while(l>0){ + ec_enc_carry_out(_this,(int)(end>>EC_CODE_SHIFT)); + end=(end<rem>=0||_this->ext>0)ec_enc_carry_out(_this,0); + /*If we have buffered extra bits, flush them as well.*/ + window=_this->end_window; + used=_this->nend_bits; + while(used>=EC_SYM_BITS){ + _this->error|=ec_write_byte_at_end(_this,(unsigned)window&EC_SYM_MAX); + window>>=EC_SYM_BITS; + used-=EC_SYM_BITS; + } + /*Clear any excess space and add any remaining extra bits to the last byte.*/ + if(!_this->error){ + OPUS_CLEAR(_this->buf+_this->offs, + _this->storage-_this->offs-_this->end_offs); + if(used>0){ + /*If there's no range coder data at all, give up.*/ + if(_this->end_offs>=_this->storage)_this->error=-1; + else{ + l=-l; + /*If we've busted, don't add too many extra bits to the last byte; it + would corrupt the range coder data, and that's more important.*/ + if(_this->offs+_this->end_offs>=_this->storage&&lerror=-1; + } + _this->buf[_this->storage-_this->end_offs-1]|=(unsigned char)window; + } + } + } +} diff --git a/src/opus-1.1/celt/entenc.h b/src/opus-1.1/celt/entenc.h new file mode 100644 index 00000000..796bc4d5 --- /dev/null +++ b/src/opus-1.1/celt/entenc.h @@ -0,0 +1,110 @@ +/* Copyright (c) 2001-2011 Timothy B. Terriberry + Copyright (c) 2008-2009 Xiph.Org Foundation */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#if !defined(_entenc_H) +# define _entenc_H (1) +# include +# include "entcode.h" + +/*Initializes the encoder. + _buf: The buffer to store output bytes in. + _size: The size of the buffer, in chars.*/ +void ec_enc_init(ec_enc *_this,unsigned char *_buf,opus_uint32 _size); +/*Encodes a symbol given its frequency information. + The frequency information must be discernable by the decoder, assuming it + has read only the previous symbols from the stream. + It is allowable to change the frequency information, or even the entire + source alphabet, so long as the decoder can tell from the context of the + previously encoded information that it is supposed to do so as well. + _fl: The cumulative frequency of all symbols that come before the one to be + encoded. + _fh: The cumulative frequency of all symbols up to and including the one to + be encoded. + Together with _fl, this defines the range [_fl,_fh) in which the + decoded value will fall. + _ft: The sum of the frequencies of all the symbols*/ +void ec_encode(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _ft); + +/*Equivalent to ec_encode() with _ft==1<<_bits.*/ +void ec_encode_bin(ec_enc *_this,unsigned _fl,unsigned _fh,unsigned _bits); + +/* Encode a bit that has a 1/(1<<_logp) probability of being a one */ +void ec_enc_bit_logp(ec_enc *_this,int _val,unsigned _logp); + +/*Encodes a symbol given an "inverse" CDF table. + _s: The index of the symbol to encode. + _icdf: The "inverse" CDF, such that symbol _s falls in the range + [_s>0?ft-_icdf[_s-1]:0,ft-_icdf[_s]), where ft=1<<_ftb. + The values must be monotonically non-increasing, and the last value + must be 0. + _ftb: The number of bits of precision in the cumulative distribution.*/ +void ec_enc_icdf(ec_enc *_this,int _s,const unsigned char *_icdf,unsigned _ftb); + +/*Encodes a raw unsigned integer in the stream. + _fl: The integer to encode. + _ft: The number of integers that can be encoded (one more than the max). + This must be at least one, and no more than 2**32-1.*/ +void ec_enc_uint(ec_enc *_this,opus_uint32 _fl,opus_uint32 _ft); + +/*Encodes a sequence of raw bits in the stream. + _fl: The bits to encode. + _ftb: The number of bits to encode. + This must be between 1 and 25, inclusive.*/ +void ec_enc_bits(ec_enc *_this,opus_uint32 _fl,unsigned _ftb); + +/*Overwrites a few bits at the very start of an existing stream, after they + have already been encoded. + This makes it possible to have a few flags up front, where it is easy for + decoders to access them without parsing the whole stream, even if their + values are not determined until late in the encoding process, without having + to buffer all the intermediate symbols in the encoder. + In order for this to work, at least _nbits bits must have already been + encoded using probabilities that are an exact power of two. + The encoder can verify the number of encoded bits is sufficient, but cannot + check this latter condition. + _val: The bits to encode (in the least _nbits significant bits). + They will be decoded in order from most-significant to least. + _nbits: The number of bits to overwrite. + This must be no more than 8.*/ +void ec_enc_patch_initial_bits(ec_enc *_this,unsigned _val,unsigned _nbits); + +/*Compacts the data to fit in the target size. + This moves up the raw bits at the end of the current buffer so they are at + the end of the new buffer size. + The caller must ensure that the amount of data that's already been written + will fit in the new size. + _size: The number of bytes in the new buffer. + This must be large enough to contain the bits already written, and + must be no larger than the existing size.*/ +void ec_enc_shrink(ec_enc *_this,opus_uint32 _size); + +/*Indicates that there are no more symbols to encode. + All reamining output bytes are flushed to the output buffer. + ec_enc_init() must be called before the encoder can be used again.*/ +void ec_enc_done(ec_enc *_this); + +#endif diff --git a/src/opus-1.1/celt/fixed_debug.h b/src/opus-1.1/celt/fixed_debug.h new file mode 100644 index 00000000..80bc9491 --- /dev/null +++ b/src/opus-1.1/celt/fixed_debug.h @@ -0,0 +1,773 @@ +/* Copyright (C) 2003-2008 Jean-Marc Valin + Copyright (C) 2007-2012 Xiph.Org Foundation */ +/** + @file fixed_debug.h + @brief Fixed-point operations with debugging +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FIXED_DEBUG_H +#define FIXED_DEBUG_H + +#include +#include "opus_defines.h" + +#ifdef CELT_C +OPUS_EXPORT opus_int64 celt_mips=0; +#else +extern opus_int64 celt_mips; +#endif + +#define MULT16_16SU(a,b) ((opus_val32)(opus_val16)(a)*(opus_val32)(opus_uint16)(b)) +#define MULT32_32_Q31(a,b) ADD32(ADD32(SHL32(MULT16_16(SHR32((a),16),SHR((b),16)),1), SHR32(MULT16_16SU(SHR32((a),16),((b)&0x0000ffff)),15)), SHR32(MULT16_16SU(SHR32((b),16),((a)&0x0000ffff)),15)) + +/** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */ +#define MULT16_32_Q16(a,b) ADD32(MULT16_16((a),SHR32((b),16)), SHR32(MULT16_16SU((a),((b)&0x0000ffff)),16)) + +#define MULT16_32_P16(a,b) MULT16_32_PX(a,b,16) + +#define QCONST16(x,bits) ((opus_val16)(.5+(x)*(((opus_val32)1)<<(bits)))) +#define QCONST32(x,bits) ((opus_val32)(.5+(x)*(((opus_val32)1)<<(bits)))) + +#define VERIFY_SHORT(x) ((x)<=32767&&(x)>=-32768) +#define VERIFY_INT(x) ((x)<=2147483647LL&&(x)>=-2147483648LL) +#define VERIFY_UINT(x) ((x)<=(2147483647LLU<<1)) + +#define SHR(a,b) SHR32(a,b) +#define PSHR(a,b) PSHR32(a,b) + +static OPUS_INLINE short NEG16(int x) +{ + int res; + if (!VERIFY_SHORT(x)) + { + fprintf (stderr, "NEG16: input is not short: %d\n", (int)x); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + res = -x; + if (!VERIFY_SHORT(res)) + { + fprintf (stderr, "NEG16: output is not short: %d\n", (int)res); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + celt_mips++; + return res; +} +static OPUS_INLINE int NEG32(opus_int64 x) +{ + opus_int64 res; + if (!VERIFY_INT(x)) + { + fprintf (stderr, "NEG16: input is not int: %d\n", (int)x); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + res = -x; + if (!VERIFY_INT(res)) + { + fprintf (stderr, "NEG16: output is not int: %d\n", (int)res); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + celt_mips+=2; + return res; +} + +#define EXTRACT16(x) EXTRACT16_(x, __FILE__, __LINE__) +static OPUS_INLINE short EXTRACT16_(int x, char *file, int line) +{ + int res; + if (!VERIFY_SHORT(x)) + { + fprintf (stderr, "EXTRACT16: input is not short: %d in %s: line %d\n", x, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + res = x; + celt_mips++; + return res; +} + +#define EXTEND32(x) EXTEND32_(x, __FILE__, __LINE__) +static OPUS_INLINE int EXTEND32_(int x, char *file, int line) +{ + int res; + if (!VERIFY_SHORT(x)) + { + fprintf (stderr, "EXTEND32: input is not short: %d in %s: line %d\n", x, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + res = x; + celt_mips++; + return res; +} + +#define SHR16(a, shift) SHR16_(a, shift, __FILE__, __LINE__) +static OPUS_INLINE short SHR16_(int a, int shift, char *file, int line) +{ + int res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift)) + { + fprintf (stderr, "SHR16: inputs are not short: %d >> %d in %s: line %d\n", a, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + res = a>>shift; + if (!VERIFY_SHORT(res)) + { + fprintf (stderr, "SHR16: output is not short: %d in %s: line %d\n", res, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + celt_mips++; + return res; +} +#define SHL16(a, shift) SHL16_(a, shift, __FILE__, __LINE__) +static OPUS_INLINE short SHL16_(int a, int shift, char *file, int line) +{ + int res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(shift)) + { + fprintf (stderr, "SHL16: inputs are not short: %d %d in %s: line %d\n", a, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + res = a<>shift; + if (!VERIFY_INT(res)) + { + fprintf (stderr, "SHR32: output is not int: %d\n", (int)res); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + celt_mips+=2; + return res; +} +#define SHL32(a, shift) SHL32_(a, shift, __FILE__, __LINE__) +static OPUS_INLINE int SHL32_(opus_int64 a, int shift, char *file, int line) +{ + opus_int64 res; + if (!VERIFY_INT(a) || !VERIFY_SHORT(shift)) + { + fprintf (stderr, "SHL32: inputs are not int: %lld %d in %s: line %d\n", a, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + res = a<>1))),shift)) +#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift))) + +#define ROUND16(x,a) (celt_mips--,EXTRACT16(PSHR32((x),(a)))) +#define HALF16(x) (SHR16(x,1)) +#define HALF32(x) (SHR32(x,1)) + +//#define SHR(a,shift) ((a) >> (shift)) +//#define SHL(a,shift) ((a) << (shift)) + +#define ADD16(a, b) ADD16_(a, b, __FILE__, __LINE__) +static OPUS_INLINE short ADD16_(int a, int b, char *file, int line) +{ + int res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) + { + fprintf (stderr, "ADD16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + res = a+b; + if (!VERIFY_SHORT(res)) + { + fprintf (stderr, "ADD16: output is not short: %d+%d=%d in %s: line %d\n", a,b,res, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + celt_mips++; + return res; +} + +#define SUB16(a, b) SUB16_(a, b, __FILE__, __LINE__) +static OPUS_INLINE short SUB16_(int a, int b, char *file, int line) +{ + int res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) + { + fprintf (stderr, "SUB16: inputs are not short: %d %d in %s: line %d\n", a, b, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + res = a-b; + if (!VERIFY_SHORT(res)) + { + fprintf (stderr, "SUB16: output is not short: %d in %s: line %d\n", res, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + celt_mips++; + return res; +} + +#define ADD32(a, b) ADD32_(a, b, __FILE__, __LINE__) +static OPUS_INLINE int ADD32_(opus_int64 a, opus_int64 b, char *file, int line) +{ + opus_int64 res; + if (!VERIFY_INT(a) || !VERIFY_INT(b)) + { + fprintf (stderr, "ADD32: inputs are not int: %d %d in %s: line %d\n", (int)a, (int)b, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + res = a+b; + if (!VERIFY_INT(res)) + { + fprintf (stderr, "ADD32: output is not int: %d in %s: line %d\n", (int)res, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + celt_mips+=2; + return res; +} + +#define SUB32(a, b) SUB32_(a, b, __FILE__, __LINE__) +static OPUS_INLINE int SUB32_(opus_int64 a, opus_int64 b, char *file, int line) +{ + opus_int64 res; + if (!VERIFY_INT(a) || !VERIFY_INT(b)) + { + fprintf (stderr, "SUB32: inputs are not int: %d %d in %s: line %d\n", (int)a, (int)b, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + res = a-b; + if (!VERIFY_INT(res)) + { + fprintf (stderr, "SUB32: output is not int: %d in %s: line %d\n", (int)res, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + celt_mips+=2; + return res; +} + +#undef UADD32 +#define UADD32(a, b) UADD32_(a, b, __FILE__, __LINE__) +static OPUS_INLINE unsigned int UADD32_(opus_uint64 a, opus_uint64 b, char *file, int line) +{ + opus_uint64 res; + if (!VERIFY_UINT(a) || !VERIFY_UINT(b)) + { + fprintf (stderr, "UADD32: inputs are not uint32: %llu %llu in %s: line %d\n", a, b, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + res = a+b; + if (!VERIFY_UINT(res)) + { + fprintf (stderr, "UADD32: output is not uint32: %llu in %s: line %d\n", res, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + celt_mips+=2; + return res; +} + +#undef USUB32 +#define USUB32(a, b) USUB32_(a, b, __FILE__, __LINE__) +static OPUS_INLINE unsigned int USUB32_(opus_uint64 a, opus_uint64 b, char *file, int line) +{ + opus_uint64 res; + if (!VERIFY_UINT(a) || !VERIFY_UINT(b)) + { + fprintf (stderr, "USUB32: inputs are not uint32: %llu %llu in %s: line %d\n", a, b, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + if (a=((opus_val32)(1)<<(15+Q))) + { + fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n", Q, (int)a, (int)b, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + res = (((opus_int64)a)*(opus_int64)b) >> Q; + if (!VERIFY_INT(res)) + { + fprintf (stderr, "MULT16_32_Q%d: output is not int: %d*%d=%d in %s: line %d\n", Q, (int)a, (int)b,(int)res, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + if (Q==15) + celt_mips+=3; + else + celt_mips+=4; + return res; +} + +#define MULT16_32_PX(a, b, Q) MULT16_32_PX_(a, b, Q, __FILE__, __LINE__) +static OPUS_INLINE int MULT16_32_PX_(int a, opus_int64 b, int Q, char *file, int line) +{ + opus_int64 res; + if (!VERIFY_SHORT(a) || !VERIFY_INT(b)) + { + fprintf (stderr, "MULT16_32_P%d: inputs are not short+int: %d %d in %s: line %d\n\n", Q, (int)a, (int)b, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + if (ABS32(b)>=((opus_int64)(1)<<(15+Q))) + { + fprintf (stderr, "MULT16_32_Q%d: second operand too large: %d %d in %s: line %d\n\n", Q, (int)a, (int)b,file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + res = ((((opus_int64)a)*(opus_int64)b) + (((opus_val32)(1)<>1))>> Q; + if (!VERIFY_INT(res)) + { + fprintf (stderr, "MULT16_32_P%d: output is not int: %d*%d=%d in %s: line %d\n\n", Q, (int)a, (int)b,(int)res, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + if (Q==15) + celt_mips+=4; + else + celt_mips+=5; + return res; +} + +#define MULT16_32_Q15(a,b) MULT16_32_QX(a,b,15) +#define MAC16_32_Q15(c,a,b) (celt_mips-=2,ADD32((c),MULT16_32_Q15((a),(b)))) + +static OPUS_INLINE int SATURATE(int a, int b) +{ + if (a>b) + a=b; + if (a<-b) + a = -b; + celt_mips+=3; + return a; +} + +static OPUS_INLINE opus_int16 SATURATE16(opus_int32 a) +{ + celt_mips+=3; + if (a>32767) + return 32767; + else if (a<-32768) + return -32768; + else return a; +} + +static OPUS_INLINE int MULT16_16_Q11_32(int a, int b) +{ + opus_int64 res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) + { + fprintf (stderr, "MULT16_16_Q11: inputs are not short: %d %d\n", a, b); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + res = ((opus_int64)a)*b; + res >>= 11; + if (!VERIFY_INT(res)) + { + fprintf (stderr, "MULT16_16_Q11: output is not short: %d*%d=%d\n", (int)a, (int)b, (int)res); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + celt_mips+=3; + return res; +} +static OPUS_INLINE short MULT16_16_Q13(int a, int b) +{ + opus_int64 res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) + { + fprintf (stderr, "MULT16_16_Q13: inputs are not short: %d %d\n", a, b); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + res = ((opus_int64)a)*b; + res >>= 13; + if (!VERIFY_SHORT(res)) + { + fprintf (stderr, "MULT16_16_Q13: output is not short: %d*%d=%d\n", a, b, (int)res); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + celt_mips+=3; + return res; +} +static OPUS_INLINE short MULT16_16_Q14(int a, int b) +{ + opus_int64 res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) + { + fprintf (stderr, "MULT16_16_Q14: inputs are not short: %d %d\n", a, b); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + res = ((opus_int64)a)*b; + res >>= 14; + if (!VERIFY_SHORT(res)) + { + fprintf (stderr, "MULT16_16_Q14: output is not short: %d\n", (int)res); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + celt_mips+=3; + return res; +} + +#define MULT16_16_Q15(a, b) MULT16_16_Q15_(a, b, __FILE__, __LINE__) +static OPUS_INLINE short MULT16_16_Q15_(int a, int b, char *file, int line) +{ + opus_int64 res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) + { + fprintf (stderr, "MULT16_16_Q15: inputs are not short: %d %d in %s: line %d\n", a, b, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + res = ((opus_int64)a)*b; + res >>= 15; + if (!VERIFY_SHORT(res)) + { + fprintf (stderr, "MULT16_16_Q15: output is not short: %d in %s: line %d\n", (int)res, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + celt_mips+=1; + return res; +} + +static OPUS_INLINE short MULT16_16_P13(int a, int b) +{ + opus_int64 res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) + { + fprintf (stderr, "MULT16_16_P13: inputs are not short: %d %d\n", a, b); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + res = ((opus_int64)a)*b; + res += 4096; + if (!VERIFY_INT(res)) + { + fprintf (stderr, "MULT16_16_P13: overflow: %d*%d=%d\n", a, b, (int)res); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + res >>= 13; + if (!VERIFY_SHORT(res)) + { + fprintf (stderr, "MULT16_16_P13: output is not short: %d*%d=%d\n", a, b, (int)res); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + celt_mips+=4; + return res; +} +static OPUS_INLINE short MULT16_16_P14(int a, int b) +{ + opus_int64 res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) + { + fprintf (stderr, "MULT16_16_P14: inputs are not short: %d %d\n", a, b); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + res = ((opus_int64)a)*b; + res += 8192; + if (!VERIFY_INT(res)) + { + fprintf (stderr, "MULT16_16_P14: overflow: %d*%d=%d\n", a, b, (int)res); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + res >>= 14; + if (!VERIFY_SHORT(res)) + { + fprintf (stderr, "MULT16_16_P14: output is not short: %d*%d=%d\n", a, b, (int)res); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + celt_mips+=4; + return res; +} +static OPUS_INLINE short MULT16_16_P15(int a, int b) +{ + opus_int64 res; + if (!VERIFY_SHORT(a) || !VERIFY_SHORT(b)) + { + fprintf (stderr, "MULT16_16_P15: inputs are not short: %d %d\n", a, b); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + res = ((opus_int64)a)*b; + res += 16384; + if (!VERIFY_INT(res)) + { + fprintf (stderr, "MULT16_16_P15: overflow: %d*%d=%d\n", a, b, (int)res); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + res >>= 15; + if (!VERIFY_SHORT(res)) + { + fprintf (stderr, "MULT16_16_P15: output is not short: %d*%d=%d\n", a, b, (int)res); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + celt_mips+=2; + return res; +} + +#define DIV32_16(a, b) DIV32_16_(a, b, __FILE__, __LINE__) + +static OPUS_INLINE int DIV32_16_(opus_int64 a, opus_int64 b, char *file, int line) +{ + opus_int64 res; + if (b==0) + { + fprintf(stderr, "DIV32_16: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + return 0; + } + if (!VERIFY_INT(a) || !VERIFY_SHORT(b)) + { + fprintf (stderr, "DIV32_16: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + res = a/b; + if (!VERIFY_SHORT(res)) + { + fprintf (stderr, "DIV32_16: output is not short: %d / %d = %d in %s: line %d\n", (int)a,(int)b,(int)res, file, line); + if (res>32767) + res = 32767; + if (res<-32768) + res = -32768; +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + celt_mips+=35; + return res; +} + +#define DIV32(a, b) DIV32_(a, b, __FILE__, __LINE__) +static OPUS_INLINE int DIV32_(opus_int64 a, opus_int64 b, char *file, int line) +{ + opus_int64 res; + if (b==0) + { + fprintf(stderr, "DIV32: divide by zero: %d/%d in %s: line %d\n", (int)a, (int)b, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + return 0; + } + + if (!VERIFY_INT(a) || !VERIFY_INT(b)) + { + fprintf (stderr, "DIV32: inputs are not int/short: %d %d in %s: line %d\n", (int)a, (int)b, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + res = a/b; + if (!VERIFY_INT(res)) + { + fprintf (stderr, "DIV32: output is not int: %d in %s: line %d\n", (int)res, file, line); +#ifdef FIXED_DEBUG_ASSERT + celt_assert(0); +#endif + } + celt_mips+=70; + return res; +} + +#undef PRINT_MIPS +#define PRINT_MIPS(file) do {fprintf (file, "total complexity = %llu MIPS\n", celt_mips);} while (0); + +#endif diff --git a/src/opus-1.1/celt/fixed_generic.h b/src/opus-1.1/celt/fixed_generic.h new file mode 100644 index 00000000..ecf018a2 --- /dev/null +++ b/src/opus-1.1/celt/fixed_generic.h @@ -0,0 +1,134 @@ +/* Copyright (C) 2007-2009 Xiph.Org Foundation + Copyright (C) 2003-2008 Jean-Marc Valin + Copyright (C) 2007-2008 CSIRO */ +/** + @file fixed_generic.h + @brief Generic fixed-point operations +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef FIXED_GENERIC_H +#define FIXED_GENERIC_H + +/** Multiply a 16-bit signed value by a 16-bit unsigned value. The result is a 32-bit signed value */ +#define MULT16_16SU(a,b) ((opus_val32)(opus_val16)(a)*(opus_val32)(opus_uint16)(b)) + +/** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */ +#define MULT16_32_Q16(a,b) ADD32(MULT16_16((a),SHR((b),16)), SHR(MULT16_16SU((a),((b)&0x0000ffff)),16)) + +/** 16x32 multiplication, followed by a 16-bit shift right (round-to-nearest). Results fits in 32 bits */ +#define MULT16_32_P16(a,b) ADD32(MULT16_16((a),SHR((b),16)), PSHR(MULT16_16SU((a),((b)&0x0000ffff)),16)) + +/** 16x32 multiplication, followed by a 15-bit shift right. Results fits in 32 bits */ +#define MULT16_32_Q15(a,b) ADD32(SHL(MULT16_16((a),SHR((b),16)),1), SHR(MULT16_16SU((a),((b)&0x0000ffff)),15)) + +/** 32x32 multiplication, followed by a 31-bit shift right. Results fits in 32 bits */ +#define MULT32_32_Q31(a,b) ADD32(ADD32(SHL(MULT16_16(SHR((a),16),SHR((b),16)),1), SHR(MULT16_16SU(SHR((a),16),((b)&0x0000ffff)),15)), SHR(MULT16_16SU(SHR((b),16),((a)&0x0000ffff)),15)) + +/** Compile-time conversion of float constant to 16-bit value */ +#define QCONST16(x,bits) ((opus_val16)(.5+(x)*(((opus_val32)1)<<(bits)))) + +/** Compile-time conversion of float constant to 32-bit value */ +#define QCONST32(x,bits) ((opus_val32)(.5+(x)*(((opus_val32)1)<<(bits)))) + +/** Negate a 16-bit value */ +#define NEG16(x) (-(x)) +/** Negate a 32-bit value */ +#define NEG32(x) (-(x)) + +/** Change a 32-bit value into a 16-bit value. The value is assumed to fit in 16-bit, otherwise the result is undefined */ +#define EXTRACT16(x) ((opus_val16)(x)) +/** Change a 16-bit value into a 32-bit value */ +#define EXTEND32(x) ((opus_val32)(x)) + +/** Arithmetic shift-right of a 16-bit value */ +#define SHR16(a,shift) ((a) >> (shift)) +/** Arithmetic shift-left of a 16-bit value */ +#define SHL16(a,shift) ((opus_int16)((opus_uint16)(a)<<(shift))) +/** Arithmetic shift-right of a 32-bit value */ +#define SHR32(a,shift) ((a) >> (shift)) +/** Arithmetic shift-left of a 32-bit value */ +#define SHL32(a,shift) ((opus_int32)((opus_uint32)(a)<<(shift))) + +/** 32-bit arithmetic shift right with rounding-to-nearest instead of rounding down */ +#define PSHR32(a,shift) (SHR32((a)+((EXTEND32(1)<<((shift))>>1)),shift)) +/** 32-bit arithmetic shift right where the argument can be negative */ +#define VSHR32(a, shift) (((shift)>0) ? SHR32(a, shift) : SHL32(a, -(shift))) + +/** "RAW" macros, should not be used outside of this header file */ +#define SHR(a,shift) ((a) >> (shift)) +#define SHL(a,shift) SHL32(a,shift) +#define PSHR(a,shift) (SHR((a)+((EXTEND32(1)<<((shift))>>1)),shift)) +#define SATURATE(x,a) (((x)>(a) ? (a) : (x)<-(a) ? -(a) : (x))) + +#define SATURATE16(x) (EXTRACT16((x)>32767 ? 32767 : (x)<-32768 ? -32768 : (x))) + +/** Shift by a and round-to-neareast 32-bit value. Result is a 16-bit value */ +#define ROUND16(x,a) (EXTRACT16(PSHR32((x),(a)))) +/** Divide by two */ +#define HALF16(x) (SHR16(x,1)) +#define HALF32(x) (SHR32(x,1)) + +/** Add two 16-bit values */ +#define ADD16(a,b) ((opus_val16)((opus_val16)(a)+(opus_val16)(b))) +/** Subtract two 16-bit values */ +#define SUB16(a,b) ((opus_val16)(a)-(opus_val16)(b)) +/** Add two 32-bit values */ +#define ADD32(a,b) ((opus_val32)(a)+(opus_val32)(b)) +/** Subtract two 32-bit values */ +#define SUB32(a,b) ((opus_val32)(a)-(opus_val32)(b)) + +/** 16x16 multiplication where the result fits in 16 bits */ +#define MULT16_16_16(a,b) ((((opus_val16)(a))*((opus_val16)(b)))) + +/* (opus_val32)(opus_val16) gives TI compiler a hint that it's 16x16->32 multiply */ +/** 16x16 multiplication where the result fits in 32 bits */ +#define MULT16_16(a,b) (((opus_val32)(opus_val16)(a))*((opus_val32)(opus_val16)(b))) + +/** 16x16 multiply-add where the result fits in 32 bits */ +#define MAC16_16(c,a,b) (ADD32((c),MULT16_16((a),(b)))) +/** 16x32 multiply, followed by a 15-bit shift right and 32-bit add. + b must fit in 31 bits. + Result fits in 32 bits. */ +#define MAC16_32_Q15(c,a,b) ADD32(c,ADD32(MULT16_16((a),SHR((b),15)), SHR(MULT16_16((a),((b)&0x00007fff)),15))) + +#define MULT16_16_Q11_32(a,b) (SHR(MULT16_16((a),(b)),11)) +#define MULT16_16_Q11(a,b) (SHR(MULT16_16((a),(b)),11)) +#define MULT16_16_Q13(a,b) (SHR(MULT16_16((a),(b)),13)) +#define MULT16_16_Q14(a,b) (SHR(MULT16_16((a),(b)),14)) +#define MULT16_16_Q15(a,b) (SHR(MULT16_16((a),(b)),15)) + +#define MULT16_16_P13(a,b) (SHR(ADD32(4096,MULT16_16((a),(b))),13)) +#define MULT16_16_P14(a,b) (SHR(ADD32(8192,MULT16_16((a),(b))),14)) +#define MULT16_16_P15(a,b) (SHR(ADD32(16384,MULT16_16((a),(b))),15)) + +/** Divide a 32-bit value by a 16-bit value. Result fits in 16 bits */ +#define DIV32_16(a,b) ((opus_val16)(((opus_val32)(a))/((opus_val16)(b)))) + +/** Divide a 32-bit value by a 32-bit value. Result fits in 32 bits */ +#define DIV32(a,b) (((opus_val32)(a))/((opus_val32)(b))) + +#endif diff --git a/src/opus-1.1/celt/float_cast.h b/src/opus-1.1/celt/float_cast.h new file mode 100644 index 00000000..ede65748 --- /dev/null +++ b/src/opus-1.1/celt/float_cast.h @@ -0,0 +1,140 @@ +/* Copyright (C) 2001 Erik de Castro Lopo */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* Version 1.1 */ + +#ifndef FLOAT_CAST_H +#define FLOAT_CAST_H + + +#include "arch.h" + +/*============================================================================ +** On Intel Pentium processors (especially PIII and probably P4), converting +** from float to int is very slow. To meet the C specs, the code produced by +** most C compilers targeting Pentium needs to change the FPU rounding mode +** before the float to int conversion is performed. +** +** Changing the FPU rounding mode causes the FPU pipeline to be flushed. It +** is this flushing of the pipeline which is so slow. +** +** Fortunately the ISO C99 specifications define the functions lrint, lrintf, +** llrint and llrintf which fix this problem as a side effect. +** +** On Unix-like systems, the configure process should have detected the +** presence of these functions. If they weren't found we have to replace them +** here with a standard C cast. +*/ + +/* +** The C99 prototypes for lrint and lrintf are as follows: +** +** long int lrintf (float x) ; +** long int lrint (double x) ; +*/ + +/* The presence of the required functions are detected during the configure +** process and the values HAVE_LRINT and HAVE_LRINTF are set accordingly in +** the config.h file. +*/ + +#if (HAVE_LRINTF) + +/* These defines enable functionality introduced with the 1999 ISO C +** standard. They must be defined before the inclusion of math.h to +** engage them. If optimisation is enabled, these functions will be +** inlined. With optimisation switched off, you have to link in the +** maths library using -lm. +*/ + +#define _ISOC9X_SOURCE 1 +#define _ISOC99_SOURCE 1 + +#define __USE_ISOC9X 1 +#define __USE_ISOC99 1 + +#include +#define float2int(x) lrintf(x) + +#elif (defined(HAVE_LRINT)) + +#define _ISOC9X_SOURCE 1 +#define _ISOC99_SOURCE 1 + +#define __USE_ISOC9X 1 +#define __USE_ISOC99 1 + +#include +#define float2int(x) lrint(x) + +#elif (defined(_MSC_VER) && _MSC_VER >= 1400) && (defined (WIN64) || defined (_WIN64)) + #include + + __inline long int float2int(float value) + { + return _mm_cvtss_si32(_mm_load_ss(&value)); + } +#elif (defined(_MSC_VER) && _MSC_VER >= 1400) && (defined (WIN32) || defined (_WIN32)) + #include + + /* Win32 doesn't seem to have these functions. + ** Therefore implement OPUS_INLINE versions of these functions here. + */ + + __inline long int + float2int (float flt) + { int intgr; + + _asm + { fld flt + fistp intgr + } ; + + return intgr ; + } + +#else + +#if (defined(__GNUC__) && defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) + /* supported by gcc in C99 mode, but not by all other compilers */ + #warning "Don't have the functions lrint() and lrintf ()." + #warning "Replacing these functions with a standard C cast." +#endif /* __STDC_VERSION__ >= 199901L */ + #include + #define float2int(flt) ((int)(floor(.5+flt))) +#endif + +#ifndef DISABLE_FLOAT_API +static OPUS_INLINE opus_int16 FLOAT2INT16(float x) +{ + x = x*CELT_SIG_SCALE; + x = MAX32(x, -32768); + x = MIN32(x, 32767); + return (opus_int16)float2int(x); +} +#endif /* DISABLE_FLOAT_API */ + +#endif /* FLOAT_CAST_H */ diff --git a/src/opus-1.1/celt/kiss_fft.c b/src/opus-1.1/celt/kiss_fft.c new file mode 100644 index 00000000..ad706c73 --- /dev/null +++ b/src/opus-1.1/celt/kiss_fft.c @@ -0,0 +1,719 @@ +/*Copyright (c) 2003-2004, Mark Borgerding + Lots of modifications by Jean-Marc Valin + Copyright (c) 2005-2007, Xiph.Org Foundation + Copyright (c) 2008, Xiph.Org Foundation, CSIRO + + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE.*/ + +/* This code is originally from Mark Borgerding's KISS-FFT but has been + heavily modified to better suit Opus */ + +#ifndef SKIP_CONFIG_H +# ifdef HAVE_CONFIG_H +# include "config.h" +# endif +#endif + +#include "_kiss_fft_guts.h" +#include "arch.h" +#include "os_support.h" +#include "mathops.h" +#include "stack_alloc.h" + +/* The guts header contains all the multiplication and addition macros that are defined for + complex numbers. It also delares the kf_ internal functions. +*/ + +static void kf_bfly2( + kiss_fft_cpx * Fout, + const size_t fstride, + const kiss_fft_state *st, + int m, + int N, + int mm + ) +{ + kiss_fft_cpx * Fout2; + const kiss_twiddle_cpx * tw1; + int i,j; + kiss_fft_cpx * Fout_beg = Fout; + for (i=0;itwiddles; + for(j=0;jr = SHR32(Fout->r, 1);Fout->i = SHR32(Fout->i, 1); + Fout2->r = SHR32(Fout2->r, 1);Fout2->i = SHR32(Fout2->i, 1); + C_MUL (t, *Fout2 , *tw1); + tw1 += fstride; + C_SUB( *Fout2 , *Fout , t ); + C_ADDTO( *Fout , t ); + ++Fout2; + ++Fout; + } + } +} + +static void ki_bfly2( + kiss_fft_cpx * Fout, + const size_t fstride, + const kiss_fft_state *st, + int m, + int N, + int mm + ) +{ + kiss_fft_cpx * Fout2; + const kiss_twiddle_cpx * tw1; + kiss_fft_cpx t; + int i,j; + kiss_fft_cpx * Fout_beg = Fout; + for (i=0;itwiddles; + for(j=0;jtwiddles; + for (j=0;jr = PSHR32(Fout->r, 2); + Fout->i = PSHR32(Fout->i, 2); + C_SUB( scratch[5] , *Fout, scratch[1] ); + C_ADDTO(*Fout, scratch[1]); + C_ADD( scratch[3] , scratch[0] , scratch[2] ); + C_SUB( scratch[4] , scratch[0] , scratch[2] ); + C_SUB( Fout[m2], *Fout, scratch[3] ); + tw1 += fstride; + tw2 += fstride*2; + tw3 += fstride*3; + C_ADDTO( *Fout , scratch[3] ); + + Fout[m].r = scratch[5].r + scratch[4].i; + Fout[m].i = scratch[5].i - scratch[4].r; + Fout[m3].r = scratch[5].r - scratch[4].i; + Fout[m3].i = scratch[5].i + scratch[4].r; + ++Fout; + } + } +} + +static void ki_bfly4( + kiss_fft_cpx * Fout, + const size_t fstride, + const kiss_fft_state *st, + int m, + int N, + int mm + ) +{ + const kiss_twiddle_cpx *tw1,*tw2,*tw3; + kiss_fft_cpx scratch[6]; + const size_t m2=2*m; + const size_t m3=3*m; + int i, j; + + kiss_fft_cpx * Fout_beg = Fout; + for (i=0;itwiddles; + for (j=0;jtwiddles[fstride*m]; + for (i=0;itwiddles; + k=m; + do { + C_FIXDIV(*Fout,3); C_FIXDIV(Fout[m],3); C_FIXDIV(Fout[m2],3); + + C_MUL(scratch[1],Fout[m] , *tw1); + C_MUL(scratch[2],Fout[m2] , *tw2); + + C_ADD(scratch[3],scratch[1],scratch[2]); + C_SUB(scratch[0],scratch[1],scratch[2]); + tw1 += fstride; + tw2 += fstride*2; + + Fout[m].r = Fout->r - HALF_OF(scratch[3].r); + Fout[m].i = Fout->i - HALF_OF(scratch[3].i); + + C_MULBYSCALAR( scratch[0] , epi3.i ); + + C_ADDTO(*Fout,scratch[3]); + + Fout[m2].r = Fout[m].r + scratch[0].i; + Fout[m2].i = Fout[m].i - scratch[0].r; + + Fout[m].r -= scratch[0].i; + Fout[m].i += scratch[0].r; + + ++Fout; + } while(--k); + } +} + +static void ki_bfly3( + kiss_fft_cpx * Fout, + const size_t fstride, + const kiss_fft_state *st, + int m, + int N, + int mm + ) +{ + int i, k; + const size_t m2 = 2*m; + const kiss_twiddle_cpx *tw1,*tw2; + kiss_fft_cpx scratch[5]; + kiss_twiddle_cpx epi3; + + kiss_fft_cpx * Fout_beg = Fout; + epi3 = st->twiddles[fstride*m]; + for (i=0;itwiddles; + k=m; + do{ + + C_MULC(scratch[1],Fout[m] , *tw1); + C_MULC(scratch[2],Fout[m2] , *tw2); + + C_ADD(scratch[3],scratch[1],scratch[2]); + C_SUB(scratch[0],scratch[1],scratch[2]); + tw1 += fstride; + tw2 += fstride*2; + + Fout[m].r = Fout->r - HALF_OF(scratch[3].r); + Fout[m].i = Fout->i - HALF_OF(scratch[3].i); + + C_MULBYSCALAR( scratch[0] , -epi3.i ); + + C_ADDTO(*Fout,scratch[3]); + + Fout[m2].r = Fout[m].r + scratch[0].i; + Fout[m2].i = Fout[m].i - scratch[0].r; + + Fout[m].r -= scratch[0].i; + Fout[m].i += scratch[0].r; + + ++Fout; + }while(--k); + } +} + +static void kf_bfly5( + kiss_fft_cpx * Fout, + const size_t fstride, + const kiss_fft_state *st, + int m, + int N, + int mm + ) +{ + kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4; + int i, u; + kiss_fft_cpx scratch[13]; + const kiss_twiddle_cpx * twiddles = st->twiddles; + const kiss_twiddle_cpx *tw; + kiss_twiddle_cpx ya,yb; + kiss_fft_cpx * Fout_beg = Fout; + + ya = twiddles[fstride*m]; + yb = twiddles[fstride*2*m]; + tw=st->twiddles; + + for (i=0;ir += scratch[7].r + scratch[8].r; + Fout0->i += scratch[7].i + scratch[8].i; + + scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r); + scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r); + + scratch[6].r = S_MUL(scratch[10].i,ya.i) + S_MUL(scratch[9].i,yb.i); + scratch[6].i = -S_MUL(scratch[10].r,ya.i) - S_MUL(scratch[9].r,yb.i); + + C_SUB(*Fout1,scratch[5],scratch[6]); + C_ADD(*Fout4,scratch[5],scratch[6]); + + scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r); + scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r); + scratch[12].r = - S_MUL(scratch[10].i,yb.i) + S_MUL(scratch[9].i,ya.i); + scratch[12].i = S_MUL(scratch[10].r,yb.i) - S_MUL(scratch[9].r,ya.i); + + C_ADD(*Fout2,scratch[11],scratch[12]); + C_SUB(*Fout3,scratch[11],scratch[12]); + + ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4; + } + } +} + +static void ki_bfly5( + kiss_fft_cpx * Fout, + const size_t fstride, + const kiss_fft_state *st, + int m, + int N, + int mm + ) +{ + kiss_fft_cpx *Fout0,*Fout1,*Fout2,*Fout3,*Fout4; + int i, u; + kiss_fft_cpx scratch[13]; + const kiss_twiddle_cpx * twiddles = st->twiddles; + const kiss_twiddle_cpx *tw; + kiss_twiddle_cpx ya,yb; + kiss_fft_cpx * Fout_beg = Fout; + + ya = twiddles[fstride*m]; + yb = twiddles[fstride*2*m]; + tw=st->twiddles; + + for (i=0;ir += scratch[7].r + scratch[8].r; + Fout0->i += scratch[7].i + scratch[8].i; + + scratch[5].r = scratch[0].r + S_MUL(scratch[7].r,ya.r) + S_MUL(scratch[8].r,yb.r); + scratch[5].i = scratch[0].i + S_MUL(scratch[7].i,ya.r) + S_MUL(scratch[8].i,yb.r); + + scratch[6].r = -S_MUL(scratch[10].i,ya.i) - S_MUL(scratch[9].i,yb.i); + scratch[6].i = S_MUL(scratch[10].r,ya.i) + S_MUL(scratch[9].r,yb.i); + + C_SUB(*Fout1,scratch[5],scratch[6]); + C_ADD(*Fout4,scratch[5],scratch[6]); + + scratch[11].r = scratch[0].r + S_MUL(scratch[7].r,yb.r) + S_MUL(scratch[8].r,ya.r); + scratch[11].i = scratch[0].i + S_MUL(scratch[7].i,yb.r) + S_MUL(scratch[8].i,ya.r); + scratch[12].r = S_MUL(scratch[10].i,yb.i) - S_MUL(scratch[9].i,ya.i); + scratch[12].i = -S_MUL(scratch[10].r,yb.i) + S_MUL(scratch[9].r,ya.i); + + C_ADD(*Fout2,scratch[11],scratch[12]); + C_SUB(*Fout3,scratch[11],scratch[12]); + + ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4; + } + } +} + +#endif + + +#ifdef CUSTOM_MODES + +static +void compute_bitrev_table( + int Fout, + opus_int16 *f, + const size_t fstride, + int in_stride, + opus_int16 * factors, + const kiss_fft_state *st + ) +{ + const int p=*factors++; /* the radix */ + const int m=*factors++; /* stage's fft length/p */ + + /*printf ("fft %d %d %d %d %d %d\n", p*m, m, p, s2, fstride*in_stride, N);*/ + if (m==1) + { + int j; + for (j=0;j32000 || (opus_int32)p*(opus_int32)p > n) + p = n; /* no more factors, skip to end */ + } + n /= p; +#ifdef RADIX_TWO_ONLY + if (p!=2 && p != 4) +#else + if (p>5) +#endif + { + return 0; + } + *facbuf++ = p; + *facbuf++ = n; + } while (n > 1); + return 1; +} + +static void compute_twiddles(kiss_twiddle_cpx *twiddles, int nfft) +{ + int i; +#ifdef FIXED_POINT + for (i=0;i= memneeded) + st = (kiss_fft_state*)mem; + *lenmem = memneeded; + } + if (st) { + opus_int16 *bitrev; + kiss_twiddle_cpx *twiddles; + + st->nfft=nfft; +#ifndef FIXED_POINT + st->scale = 1.f/nfft; +#endif + if (base != NULL) + { + st->twiddles = base->twiddles; + st->shift = 0; + while (nfft<shift != base->nfft && st->shift < 32) + st->shift++; + if (st->shift>=32) + goto fail; + } else { + st->twiddles = twiddles = (kiss_twiddle_cpx*)KISS_FFT_MALLOC(sizeof(kiss_twiddle_cpx)*nfft); + compute_twiddles(twiddles, nfft); + st->shift = -1; + } + if (!kf_factor(nfft,st->factors)) + { + goto fail; + } + + /* bitrev */ + st->bitrev = bitrev = (opus_int16*)KISS_FFT_MALLOC(sizeof(opus_int16)*nfft); + if (st->bitrev==NULL) + goto fail; + compute_bitrev_table(0, bitrev, 1,1, st->factors,st); + } + return st; +fail: + opus_fft_free(st); + return NULL; +} + +kiss_fft_state *opus_fft_alloc(int nfft,void * mem,size_t * lenmem ) +{ + return opus_fft_alloc_twiddles(nfft, mem, lenmem, NULL); +} + +void opus_fft_free(const kiss_fft_state *cfg) +{ + if (cfg) + { + opus_free((opus_int16*)cfg->bitrev); + if (cfg->shift < 0) + opus_free((kiss_twiddle_cpx*)cfg->twiddles); + opus_free((kiss_fft_state*)cfg); + } +} + +#endif /* CUSTOM_MODES */ + +void opus_fft(const kiss_fft_state *st,const kiss_fft_cpx *fin,kiss_fft_cpx *fout) +{ + int m2, m; + int p; + int L; + int fstride[MAXFACTORS]; + int i; + int shift; + + /* st->shift can be -1 */ + shift = st->shift>0 ? st->shift : 0; + + celt_assert2 (fin != fout, "In-place FFT not supported"); + /* Bit-reverse the input */ + for (i=0;infft;i++) + { + fout[st->bitrev[i]] = fin[i]; +#ifndef FIXED_POINT + fout[st->bitrev[i]].r *= st->scale; + fout[st->bitrev[i]].i *= st->scale; +#endif + } + + fstride[0] = 1; + L=0; + do { + p = st->factors[2*L]; + m = st->factors[2*L+1]; + fstride[L+1] = fstride[L]*p; + L++; + } while(m!=1); + m = st->factors[2*L-1]; + for (i=L-1;i>=0;i--) + { + if (i!=0) + m2 = st->factors[2*i-1]; + else + m2 = 1; + switch (st->factors[2*i]) + { + case 2: + kf_bfly2(fout,fstride[i]<shift can be -1 */ + shift = st->shift>0 ? st->shift : 0; + celt_assert2 (fin != fout, "In-place FFT not supported"); + /* Bit-reverse the input */ + for (i=0;infft;i++) + fout[st->bitrev[i]] = fin[i]; + + fstride[0] = 1; + L=0; + do { + p = st->factors[2*L]; + m = st->factors[2*L+1]; + fstride[L+1] = fstride[L]*p; + L++; + } while(m!=1); + m = st->factors[2*L-1]; + for (i=L-1;i>=0;i--) + { + if (i!=0) + m2 = st->factors[2*i-1]; + else + m2 = 1; + switch (st->factors[2*i]) + { + case 2: + ki_bfly2(fout,fstride[i]< +#include +#include "arch.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef USE_SIMD +# include +# define kiss_fft_scalar __m128 +#define KISS_FFT_MALLOC(nbytes) memalign(16,nbytes) +#else +#define KISS_FFT_MALLOC opus_alloc +#endif + +#ifdef FIXED_POINT +#include "arch.h" + +# define kiss_fft_scalar opus_int32 +# define kiss_twiddle_scalar opus_int16 + + +#else +# ifndef kiss_fft_scalar +/* default is float */ +# define kiss_fft_scalar float +# define kiss_twiddle_scalar float +# define KF_SUFFIX _celt_single +# endif +#endif + +typedef struct { + kiss_fft_scalar r; + kiss_fft_scalar i; +}kiss_fft_cpx; + +typedef struct { + kiss_twiddle_scalar r; + kiss_twiddle_scalar i; +}kiss_twiddle_cpx; + +#define MAXFACTORS 8 +/* e.g. an fft of length 128 has 4 factors + as far as kissfft is concerned + 4*4*4*2 + */ + +typedef struct kiss_fft_state{ + int nfft; +#ifndef FIXED_POINT + kiss_fft_scalar scale; +#endif + int shift; + opus_int16 factors[2*MAXFACTORS]; + const opus_int16 *bitrev; + const kiss_twiddle_cpx *twiddles; +} kiss_fft_state; + +/*typedef struct kiss_fft_state* kiss_fft_cfg;*/ + +/** + * opus_fft_alloc + * + * Initialize a FFT (or IFFT) algorithm's cfg/state buffer. + * + * typical usage: kiss_fft_cfg mycfg=opus_fft_alloc(1024,0,NULL,NULL); + * + * The return value from fft_alloc is a cfg buffer used internally + * by the fft routine or NULL. + * + * If lenmem is NULL, then opus_fft_alloc will allocate a cfg buffer using malloc. + * The returned value should be free()d when done to avoid memory leaks. + * + * The state can be placed in a user supplied buffer 'mem': + * If lenmem is not NULL and mem is not NULL and *lenmem is large enough, + * then the function places the cfg in mem and the size used in *lenmem + * and returns mem. + * + * If lenmem is not NULL and ( mem is NULL or *lenmem is not large enough), + * then the function returns NULL and places the minimum cfg + * buffer size in *lenmem. + * */ + +kiss_fft_state *opus_fft_alloc_twiddles(int nfft,void * mem,size_t * lenmem, const kiss_fft_state *base); + +kiss_fft_state *opus_fft_alloc(int nfft,void * mem,size_t * lenmem); + +/** + * opus_fft(cfg,in_out_buf) + * + * Perform an FFT on a complex input buffer. + * for a forward FFT, + * fin should be f[0] , f[1] , ... ,f[nfft-1] + * fout will be F[0] , F[1] , ... ,F[nfft-1] + * Note that each element is complex and can be accessed like + f[k].r and f[k].i + * */ +void opus_fft(const kiss_fft_state *cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout); +void opus_ifft(const kiss_fft_state *cfg,const kiss_fft_cpx *fin,kiss_fft_cpx *fout); + +void opus_fft_free(const kiss_fft_state *cfg); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/opus-1.1/celt/laplace.c b/src/opus-1.1/celt/laplace.c new file mode 100644 index 00000000..a7bca874 --- /dev/null +++ b/src/opus-1.1/celt/laplace.c @@ -0,0 +1,134 @@ +/* Copyright (c) 2007 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation + Written by Jean-Marc Valin */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "laplace.h" +#include "mathops.h" + +/* The minimum probability of an energy delta (out of 32768). */ +#define LAPLACE_LOG_MINP (0) +#define LAPLACE_MINP (1<>15; +} + +void ec_laplace_encode(ec_enc *enc, int *value, unsigned fs, int decay) +{ + unsigned fl; + int val = *value; + fl = 0; + if (val) + { + int s; + int i; + s = -(val<0); + val = (val+s)^s; + fl = fs; + fs = ec_laplace_get_freq1(fs, decay); + /* Search the decaying part of the PDF.*/ + for (i=1; fs > 0 && i < val; i++) + { + fs *= 2; + fl += fs+2*LAPLACE_MINP; + fs = (fs*(opus_int32)decay)>>15; + } + /* Everything beyond that has probability LAPLACE_MINP. */ + if (!fs) + { + int di; + int ndi_max; + ndi_max = (32768-fl+LAPLACE_MINP-1)>>LAPLACE_LOG_MINP; + ndi_max = (ndi_max-s)>>1; + di = IMIN(val - i, ndi_max - 1); + fl += (2*di+1+s)*LAPLACE_MINP; + fs = IMIN(LAPLACE_MINP, 32768-fl); + *value = (i+di+s)^s; + } + else + { + fs += LAPLACE_MINP; + fl += fs&~s; + } + celt_assert(fl+fs<=32768); + celt_assert(fs>0); + } + ec_encode_bin(enc, fl, fl+fs, 15); +} + +int ec_laplace_decode(ec_dec *dec, unsigned fs, int decay) +{ + int val=0; + unsigned fl; + unsigned fm; + fm = ec_decode_bin(dec, 15); + fl = 0; + if (fm >= fs) + { + val++; + fl = fs; + fs = ec_laplace_get_freq1(fs, decay)+LAPLACE_MINP; + /* Search the decaying part of the PDF.*/ + while(fs > LAPLACE_MINP && fm >= fl+2*fs) + { + fs *= 2; + fl += fs; + fs = ((fs-2*LAPLACE_MINP)*(opus_int32)decay)>>15; + fs += LAPLACE_MINP; + val++; + } + /* Everything beyond that has probability LAPLACE_MINP. */ + if (fs <= LAPLACE_MINP) + { + int di; + di = (fm-fl)>>(LAPLACE_LOG_MINP+1); + val += di; + fl += 2*di*LAPLACE_MINP; + } + if (fm < fl+fs) + val = -val; + else + fl += fs; + } + celt_assert(fl<32768); + celt_assert(fs>0); + celt_assert(fl<=fm); + celt_assert(fm>1; + b=1U<>=1; + bshift--; + } + while(bshift>=0); + return g; +} + +#ifdef FIXED_POINT + +opus_val32 frac_div32(opus_val32 a, opus_val32 b) +{ + opus_val16 rcp; + opus_val32 result, rem; + int shift = celt_ilog2(b)-29; + a = VSHR32(a,shift); + b = VSHR32(b,shift); + /* 16-bit reciprocal */ + rcp = ROUND16(celt_rcp(ROUND16(b,16)),3); + result = MULT16_32_Q15(rcp, a); + rem = PSHR32(a,2)-MULT32_32_Q31(result, b); + result = ADD32(result, SHL32(MULT16_32_Q15(rcp, rem),2)); + if (result >= 536870912) /* 2^29 */ + return 2147483647; /* 2^31 - 1 */ + else if (result <= -536870912) /* -2^29 */ + return -2147483647; /* -2^31 */ + else + return SHL32(result, 2); +} + +/** Reciprocal sqrt approximation in the range [0.25,1) (Q16 in, Q14 out) */ +opus_val16 celt_rsqrt_norm(opus_val32 x) +{ + opus_val16 n; + opus_val16 r; + opus_val16 r2; + opus_val16 y; + /* Range of n is [-16384,32767] ([-0.5,1) in Q15). */ + n = x-32768; + /* Get a rough initial guess for the root. + The optimal minimax quadratic approximation (using relative error) is + r = 1.437799046117536+n*(-0.823394375837328+n*0.4096419668459485). + Coefficients here, and the final result r, are Q14.*/ + r = ADD16(23557, MULT16_16_Q15(n, ADD16(-13490, MULT16_16_Q15(n, 6713)))); + /* We want y = x*r*r-1 in Q15, but x is 32-bit Q16 and r is Q14. + We can compute the result from n and r using Q15 multiplies with some + adjustment, carefully done to avoid overflow. + Range of y is [-1564,1594]. */ + r2 = MULT16_16_Q15(r, r); + y = SHL16(SUB16(ADD16(MULT16_16_Q15(r2, n), r2), 16384), 1); + /* Apply a 2nd-order Householder iteration: r += r*y*(y*0.375-0.5). + This yields the Q14 reciprocal square root of the Q16 x, with a maximum + relative error of 1.04956E-4, a (relative) RMSE of 2.80979E-5, and a + peak absolute error of 2.26591/16384. */ + return ADD16(r, MULT16_16_Q15(r, MULT16_16_Q15(y, + SUB16(MULT16_16_Q15(y, 12288), 16384)))); +} + +/** Sqrt approximation (QX input, QX/2 output) */ +opus_val32 celt_sqrt(opus_val32 x) +{ + int k; + opus_val16 n; + opus_val32 rt; + static const opus_val16 C[5] = {23175, 11561, -3011, 1699, -664}; + if (x==0) + return 0; + else if (x>=1073741824) + return 32767; + k = (celt_ilog2(x)>>1)-7; + x = VSHR32(x, 2*k); + n = x-32768; + rt = ADD16(C[0], MULT16_16_Q15(n, ADD16(C[1], MULT16_16_Q15(n, ADD16(C[2], + MULT16_16_Q15(n, ADD16(C[3], MULT16_16_Q15(n, (C[4]))))))))); + rt = VSHR32(rt,7-k); + return rt; +} + +#define L1 32767 +#define L2 -7651 +#define L3 8277 +#define L4 -626 + +static OPUS_INLINE opus_val16 _celt_cos_pi_2(opus_val16 x) +{ + opus_val16 x2; + + x2 = MULT16_16_P15(x,x); + return ADD16(1,MIN16(32766,ADD32(SUB16(L1,x2), MULT16_16_P15(x2, ADD32(L2, MULT16_16_P15(x2, ADD32(L3, MULT16_16_P15(L4, x2 + )))))))); +} + +#undef L1 +#undef L2 +#undef L3 +#undef L4 + +opus_val16 celt_cos_norm(opus_val32 x) +{ + x = x&0x0001ffff; + if (x>SHL32(EXTEND32(1), 16)) + x = SUB32(SHL32(EXTEND32(1), 17),x); + if (x&0x00007fff) + { + if (x0, "celt_rcp() only defined for positive values"); + i = celt_ilog2(x); + /* n is Q15 with range [0,1). */ + n = VSHR32(x,i-15)-32768; + /* Start with a linear approximation: + r = 1.8823529411764706-0.9411764705882353*n. + The coefficients and the result are Q14 in the range [15420,30840].*/ + r = ADD16(30840, MULT16_16_Q15(-15420, n)); + /* Perform two Newton iterations: + r -= r*((r*n)-1.Q15) + = r*((r*n)+(r-1.Q15)). */ + r = SUB16(r, MULT16_16_Q15(r, + ADD16(MULT16_16_Q15(r, n), ADD16(r, -32768)))); + /* We subtract an extra 1 in the second iteration to avoid overflow; it also + neatly compensates for truncation error in the rest of the process. */ + r = SUB16(r, ADD16(1, MULT16_16_Q15(r, + ADD16(MULT16_16_Q15(r, n), ADD16(r, -32768))))); + /* r is now the Q15 solution to 2/(n+1), with a maximum relative error + of 7.05346E-5, a (relative) RMSE of 2.14418E-5, and a peak absolute + error of 1.24665/32768. */ + return VSHR32(EXTEND32(r),i-16); +} + +#endif diff --git a/src/opus-1.1/celt/mathops.h b/src/opus-1.1/celt/mathops.h new file mode 100644 index 00000000..a0525a96 --- /dev/null +++ b/src/opus-1.1/celt/mathops.h @@ -0,0 +1,258 @@ +/* Copyright (c) 2002-2008 Jean-Marc Valin + Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation + Written by Jean-Marc Valin */ +/** + @file mathops.h + @brief Various math functions +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef MATHOPS_H +#define MATHOPS_H + +#include "arch.h" +#include "entcode.h" +#include "os_support.h" + +/* Multiplies two 16-bit fractional values. Bit-exactness of this macro is important */ +#define FRAC_MUL16(a,b) ((16384+((opus_int32)(opus_int16)(a)*(opus_int16)(b)))>>15) + +unsigned isqrt32(opus_uint32 _val); + +#ifndef OVERRIDE_CELT_MAXABS16 +static OPUS_INLINE opus_val32 celt_maxabs16(const opus_val16 *x, int len) +{ + int i; + opus_val16 maxval = 0; + opus_val16 minval = 0; + for (i=0;i>23)-127; + in.i -= integer<<23; + frac = in.f - 1.5f; + frac = -0.41445418f + frac*(0.95909232f + + frac*(-0.33951290f + frac*0.16541097f)); + return 1+integer+frac; +} + +/** Base-2 exponential approximation (2^x). */ +static OPUS_INLINE float celt_exp2(float x) +{ + int integer; + float frac; + union { + float f; + opus_uint32 i; + } res; + integer = floor(x); + if (integer < -50) + return 0; + frac = x-integer; + /* K0 = 1, K1 = log(2), K2 = 3-4*log(2), K3 = 3*log(2) - 2 */ + res.f = 0.99992522f + frac * (0.69583354f + + frac * (0.22606716f + 0.078024523f*frac)); + res.i = (res.i + (integer<<23)) & 0x7fffffff; + return res.f; +} + +#else +#define celt_log2(x) ((float)(1.442695040888963387*log(x))) +#define celt_exp2(x) ((float)exp(0.6931471805599453094*(x))) +#endif + +#endif + +#ifdef FIXED_POINT + +#include "os_support.h" + +#ifndef OVERRIDE_CELT_ILOG2 +/** Integer log in base2. Undefined for zero and negative numbers */ +static OPUS_INLINE opus_int16 celt_ilog2(opus_int32 x) +{ + celt_assert2(x>0, "celt_ilog2() only defined for strictly positive numbers"); + return EC_ILOG(x)-1; +} +#endif + + +/** Integer log in base2. Defined for zero, but not for negative numbers */ +static OPUS_INLINE opus_int16 celt_zlog2(opus_val32 x) +{ + return x <= 0 ? 0 : celt_ilog2(x); +} + +opus_val16 celt_rsqrt_norm(opus_val32 x); + +opus_val32 celt_sqrt(opus_val32 x); + +opus_val16 celt_cos_norm(opus_val32 x); + +/** Base-2 logarithm approximation (log2(x)). (Q14 input, Q10 output) */ +static OPUS_INLINE opus_val16 celt_log2(opus_val32 x) +{ + int i; + opus_val16 n, frac; + /* -0.41509302963303146, 0.9609890551383969, -0.31836011537636605, + 0.15530808010959576, -0.08556153059057618 */ + static const opus_val16 C[5] = {-6801+(1<<(13-DB_SHIFT)), 15746, -5217, 2545, -1401}; + if (x==0) + return -32767; + i = celt_ilog2(x); + n = VSHR32(x,i-15)-32768-16384; + frac = ADD16(C[0], MULT16_16_Q15(n, ADD16(C[1], MULT16_16_Q15(n, ADD16(C[2], MULT16_16_Q15(n, ADD16(C[3], MULT16_16_Q15(n, C[4])))))))); + return SHL16(i-13,DB_SHIFT)+SHR16(frac,14-DB_SHIFT); +} + +/* + K0 = 1 + K1 = log(2) + K2 = 3-4*log(2) + K3 = 3*log(2) - 2 +*/ +#define D0 16383 +#define D1 22804 +#define D2 14819 +#define D3 10204 + +static OPUS_INLINE opus_val32 celt_exp2_frac(opus_val16 x) +{ + opus_val16 frac; + frac = SHL16(x, 4); + return ADD16(D0, MULT16_16_Q15(frac, ADD16(D1, MULT16_16_Q15(frac, ADD16(D2 , MULT16_16_Q15(D3,frac)))))); +} +/** Base-2 exponential approximation (2^x). (Q10 input, Q16 output) */ +static OPUS_INLINE opus_val32 celt_exp2(opus_val16 x) +{ + int integer; + opus_val16 frac; + integer = SHR16(x,10); + if (integer>14) + return 0x7f000000; + else if (integer < -15) + return 0; + frac = celt_exp2_frac(x-SHL16(integer,10)); + return VSHR32(EXTEND32(frac), -integer-2); +} + +opus_val32 celt_rcp(opus_val32 x); + +#define celt_div(a,b) MULT32_32_Q31((opus_val32)(a),celt_rcp(b)) + +opus_val32 frac_div32(opus_val32 a, opus_val32 b); + +#define M1 32767 +#define M2 -21 +#define M3 -11943 +#define M4 4936 + +/* Atan approximation using a 4th order polynomial. Input is in Q15 format + and normalized by pi/4. Output is in Q15 format */ +static OPUS_INLINE opus_val16 celt_atan01(opus_val16 x) +{ + return MULT16_16_P15(x, ADD32(M1, MULT16_16_P15(x, ADD32(M2, MULT16_16_P15(x, ADD32(M3, MULT16_16_P15(M4, x))))))); +} + +#undef M1 +#undef M2 +#undef M3 +#undef M4 + +/* atan2() approximation valid for positive input values */ +static OPUS_INLINE opus_val16 celt_atan2p(opus_val16 y, opus_val16 x) +{ + if (y < x) + { + opus_val32 arg; + arg = celt_div(SHL32(EXTEND32(y),15),x); + if (arg >= 32767) + arg = 32767; + return SHR16(celt_atan01(EXTRACT16(arg)),1); + } else { + opus_val32 arg; + arg = celt_div(SHL32(EXTEND32(x),15),y); + if (arg >= 32767) + arg = 32767; + return 25736-SHR16(celt_atan01(EXTRACT16(arg)),1); + } +} + +#endif /* FIXED_POINT */ +#endif /* MATHOPS_H */ diff --git a/src/opus-1.1/celt/mdct.c b/src/opus-1.1/celt/mdct.c new file mode 100644 index 00000000..90a214ad --- /dev/null +++ b/src/opus-1.1/celt/mdct.c @@ -0,0 +1,311 @@ +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2008 Xiph.Org Foundation + Written by Jean-Marc Valin */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* This is a simple MDCT implementation that uses a N/4 complex FFT + to do most of the work. It should be relatively straightforward to + plug in pretty much and FFT here. + + This replaces the Vorbis FFT (and uses the exact same API), which + was a bit too messy and that was ending up duplicating code + (might as well use the same FFT everywhere). + + The algorithm is similar to (and inspired from) Fabrice Bellard's + MDCT implementation in FFMPEG, but has differences in signs, ordering + and scaling in many places. +*/ + +#ifndef SKIP_CONFIG_H +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#endif + +#include "mdct.h" +#include "kiss_fft.h" +#include "_kiss_fft_guts.h" +#include +#include "os_support.h" +#include "mathops.h" +#include "stack_alloc.h" + +#ifdef CUSTOM_MODES + +int clt_mdct_init(mdct_lookup *l,int N, int maxshift) +{ + int i; + int N4; + kiss_twiddle_scalar *trig; +#if defined(FIXED_POINT) + int N2=N>>1; +#endif + l->n = N; + N4 = N>>2; + l->maxshift = maxshift; + for (i=0;i<=maxshift;i++) + { + if (i==0) + l->kfft[i] = opus_fft_alloc(N>>2>>i, 0, 0); + else + l->kfft[i] = opus_fft_alloc_twiddles(N>>2>>i, 0, 0, l->kfft[0]); +#ifndef ENABLE_TI_DSPLIB55 + if (l->kfft[i]==NULL) + return 0; +#endif + } + l->trig = trig = (kiss_twiddle_scalar*)opus_alloc((N4+1)*sizeof(kiss_twiddle_scalar)); + if (l->trig==NULL) + return 0; + /* We have enough points that sine isn't necessary */ +#if defined(FIXED_POINT) + for (i=0;i<=N4;i++) + trig[i] = TRIG_UPSCALE*celt_cos_norm(DIV32(ADD32(SHL32(EXTEND32(i),17),N2),N)); +#else + for (i=0;i<=N4;i++) + trig[i] = (kiss_twiddle_scalar)cos(2*PI*i/N); +#endif + return 1; +} + +void clt_mdct_clear(mdct_lookup *l) +{ + int i; + for (i=0;i<=l->maxshift;i++) + opus_fft_free(l->kfft[i]); + opus_free((kiss_twiddle_scalar*)l->trig); +} + +#endif /* CUSTOM_MODES */ + +/* Forward MDCT trashes the input array */ +void clt_mdct_forward(const mdct_lookup *l, kiss_fft_scalar *in, kiss_fft_scalar * OPUS_RESTRICT out, + const opus_val16 *window, int overlap, int shift, int stride) +{ + int i; + int N, N2, N4; + kiss_twiddle_scalar sine; + VARDECL(kiss_fft_scalar, f); + VARDECL(kiss_fft_scalar, f2); + SAVE_STACK; + N = l->n; + N >>= shift; + N2 = N>>1; + N4 = N>>2; + ALLOC(f, N2, kiss_fft_scalar); + ALLOC(f2, N2, kiss_fft_scalar); + /* sin(x) ~= x here */ +#ifdef FIXED_POINT + sine = TRIG_UPSCALE*(QCONST16(0.7853981f, 15)+N2)/N; +#else + sine = (kiss_twiddle_scalar)2*PI*(.125f)/N; +#endif + + /* Consider the input to be composed of four blocks: [a, b, c, d] */ + /* Window, shuffle, fold */ + { + /* Temp pointers to make it really clear to the compiler what we're doing */ + const kiss_fft_scalar * OPUS_RESTRICT xp1 = in+(overlap>>1); + const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+N2-1+(overlap>>1); + kiss_fft_scalar * OPUS_RESTRICT yp = f; + const opus_val16 * OPUS_RESTRICT wp1 = window+(overlap>>1); + const opus_val16 * OPUS_RESTRICT wp2 = window+(overlap>>1)-1; + for(i=0;i<((overlap+3)>>2);i++) + { + /* Real part arranged as -d-cR, Imag part arranged as -b+aR*/ + *yp++ = MULT16_32_Q15(*wp2, xp1[N2]) + MULT16_32_Q15(*wp1,*xp2); + *yp++ = MULT16_32_Q15(*wp1, *xp1) - MULT16_32_Q15(*wp2, xp2[-N2]); + xp1+=2; + xp2-=2; + wp1+=2; + wp2-=2; + } + wp1 = window; + wp2 = window+overlap-1; + for(;i>2);i++) + { + /* Real part arranged as a-bR, Imag part arranged as -c-dR */ + *yp++ = *xp2; + *yp++ = *xp1; + xp1+=2; + xp2-=2; + } + for(;itrig[0]; + for(i=0;ikfft[shift], (kiss_fft_cpx *)f, (kiss_fft_cpx *)f2); + + /* Post-rotate */ + { + /* Temp pointers to make it really clear to the compiler what we're doing */ + const kiss_fft_scalar * OPUS_RESTRICT fp = f2; + kiss_fft_scalar * OPUS_RESTRICT yp1 = out; + kiss_fft_scalar * OPUS_RESTRICT yp2 = out+stride*(N2-1); + const kiss_twiddle_scalar *t = &l->trig[0]; + /* Temp pointers to make it really clear to the compiler what we're doing */ + for(i=0;in; + N >>= shift; + N2 = N>>1; + N4 = N>>2; + ALLOC(f2, N2, kiss_fft_scalar); + /* sin(x) ~= x here */ +#ifdef FIXED_POINT + sine = TRIG_UPSCALE*(QCONST16(0.7853981f, 15)+N2)/N; +#else + sine = (kiss_twiddle_scalar)2*PI*(.125f)/N; +#endif + + /* Pre-rotate */ + { + /* Temp pointers to make it really clear to the compiler what we're doing */ + const kiss_fft_scalar * OPUS_RESTRICT xp1 = in; + const kiss_fft_scalar * OPUS_RESTRICT xp2 = in+stride*(N2-1); + kiss_fft_scalar * OPUS_RESTRICT yp = f2; + const kiss_twiddle_scalar *t = &l->trig[0]; + for(i=0;ikfft[shift], (kiss_fft_cpx *)f2, (kiss_fft_cpx *)(out+(overlap>>1))); + + /* Post-rotate and de-shuffle from both ends of the buffer at once to make + it in-place. */ + { + kiss_fft_scalar * OPUS_RESTRICT yp0 = out+(overlap>>1); + kiss_fft_scalar * OPUS_RESTRICT yp1 = out+(overlap>>1)+N2-2; + const kiss_twiddle_scalar *t = &l->trig[0]; + /* Loop to (N4+1)>>1 to handle odd N4. When N4 is odd, the + middle pair will be computed twice. */ + for(i=0;i<(N4+1)>>1;i++) + { + kiss_fft_scalar re, im, yr, yi; + kiss_twiddle_scalar t0, t1; + re = yp0[0]; + im = yp0[1]; + t0 = t[i<>EC_SYM_BITS) +/*The number of bits available for the last, partial symbol in the code field.*/ +# define EC_CODE_EXTRA ((EC_CODE_BITS-2)%EC_SYM_BITS+1) +#endif diff --git a/src/opus-1.1/celt/modes.c b/src/opus-1.1/celt/modes.c new file mode 100644 index 00000000..42e68e1c --- /dev/null +++ b/src/opus-1.1/celt/modes.c @@ -0,0 +1,438 @@ +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation + Copyright (c) 2008 Gregory Maxwell + Written by Jean-Marc Valin and Gregory Maxwell */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "celt.h" +#include "modes.h" +#include "rate.h" +#include "os_support.h" +#include "stack_alloc.h" +#include "quant_bands.h" + +static const opus_int16 eband5ms[] = { +/*0 200 400 600 800 1k 1.2 1.4 1.6 2k 2.4 2.8 3.2 4k 4.8 5.6 6.8 8k 9.6 12k 15.6 */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 34, 40, 48, 60, 78, 100 +}; + +/* Alternate tuning (partially derived from Vorbis) */ +#define BITALLOC_SIZE 11 +/* Bit allocation table in units of 1/32 bit/sample (0.1875 dB SNR) */ +static const unsigned char band_allocation[] = { +/*0 200 400 600 800 1k 1.2 1.4 1.6 2k 2.4 2.8 3.2 4k 4.8 5.6 6.8 8k 9.6 12k 15.6 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 90, 80, 75, 69, 63, 56, 49, 40, 34, 29, 20, 18, 10, 0, 0, 0, 0, 0, 0, 0, 0, +110,100, 90, 84, 78, 71, 65, 58, 51, 45, 39, 32, 26, 20, 12, 0, 0, 0, 0, 0, 0, +118,110,103, 93, 86, 80, 75, 70, 65, 59, 53, 47, 40, 31, 23, 15, 4, 0, 0, 0, 0, +126,119,112,104, 95, 89, 83, 78, 72, 66, 60, 54, 47, 39, 32, 25, 17, 12, 1, 0, 0, +134,127,120,114,103, 97, 91, 85, 78, 72, 66, 60, 54, 47, 41, 35, 29, 23, 16, 10, 1, +144,137,130,124,113,107,101, 95, 88, 82, 76, 70, 64, 57, 51, 45, 39, 33, 26, 15, 1, +152,145,138,132,123,117,111,105, 98, 92, 86, 80, 74, 67, 61, 55, 49, 43, 36, 20, 1, +162,155,148,142,133,127,121,115,108,102, 96, 90, 84, 77, 71, 65, 59, 53, 46, 30, 1, +172,165,158,152,143,137,131,125,118,112,106,100, 94, 87, 81, 75, 69, 63, 56, 45, 20, +200,200,200,200,200,200,200,200,198,193,188,183,178,173,168,163,158,153,148,129,104, +}; + +#ifndef CUSTOM_MODES_ONLY + #ifdef FIXED_POINT + #include "static_modes_fixed.h" + #else + #include "static_modes_float.h" + #endif +#endif /* CUSTOM_MODES_ONLY */ + +#ifndef M_PI +#define M_PI 3.141592653 +#endif + +#ifdef CUSTOM_MODES + +/* Defining 25 critical bands for the full 0-20 kHz audio bandwidth + Taken from http://ccrma.stanford.edu/~jos/bbt/Bark_Frequency_Scale.html */ +#define BARK_BANDS 25 +static const opus_int16 bark_freq[BARK_BANDS+1] = { + 0, 100, 200, 300, 400, + 510, 630, 770, 920, 1080, + 1270, 1480, 1720, 2000, 2320, + 2700, 3150, 3700, 4400, 5300, + 6400, 7700, 9500, 12000, 15500, + 20000}; + +static opus_int16 *compute_ebands(opus_int32 Fs, int frame_size, int res, int *nbEBands) +{ + opus_int16 *eBands; + int i, j, lin, low, high, nBark, offset=0; + + /* All modes that have 2.5 ms short blocks use the same definition */ + if (Fs == 400*(opus_int32)frame_size) + { + *nbEBands = sizeof(eband5ms)/sizeof(eband5ms[0])-1; + eBands = opus_alloc(sizeof(opus_int16)*(*nbEBands+1)); + for (i=0;i<*nbEBands+1;i++) + eBands[i] = eband5ms[i]; + return eBands; + } + /* Find the number of critical bands supported by our sampling rate */ + for (nBark=1;nBark= Fs) + break; + + /* Find where the linear part ends (i.e. where the spacing is more than min_width */ + for (lin=0;lin= res) + break; + + low = (bark_freq[lin]+res/2)/res; + high = nBark-lin; + *nbEBands = low+high; + eBands = opus_alloc(sizeof(opus_int16)*(*nbEBands+2)); + + if (eBands==NULL) + return NULL; + + /* Linear spacing (min_width) */ + for (i=0;i0) + offset = eBands[low-1]*res - bark_freq[lin-1]; + /* Spacing follows critical bands */ + for (i=0;i frame_size) + eBands[*nbEBands] = frame_size; + for (i=1;i<*nbEBands-1;i++) + { + if (eBands[i+1]-eBands[i] < eBands[i]-eBands[i-1]) + { + eBands[i] -= (2*eBands[i]-eBands[i-1]-eBands[i+1])/2; + } + } + /* Remove any empty bands. */ + for (i=j=0;i<*nbEBands;i++) + if(eBands[i+1]>eBands[j]) + eBands[++j]=eBands[i+1]; + *nbEBands=j; + + for (i=1;i<*nbEBands;i++) + { + /* Every band must be smaller than the last band. */ + celt_assert(eBands[i]-eBands[i-1]<=eBands[*nbEBands]-eBands[*nbEBands-1]); + /* Each band must be no larger than twice the size of the previous one. */ + celt_assert(eBands[i+1]-eBands[i]<=2*(eBands[i]-eBands[i-1])); + } + + return eBands; +} + +static void compute_allocation_table(CELTMode *mode) +{ + int i, j; + unsigned char *allocVectors; + int maxBands = sizeof(eband5ms)/sizeof(eband5ms[0])-1; + + mode->nbAllocVectors = BITALLOC_SIZE; + allocVectors = opus_alloc(sizeof(unsigned char)*(BITALLOC_SIZE*mode->nbEBands)); + if (allocVectors==NULL) + return; + + /* Check for standard mode */ + if (mode->Fs == 400*(opus_int32)mode->shortMdctSize) + { + for (i=0;inbEBands;i++) + allocVectors[i] = band_allocation[i]; + mode->allocVectors = allocVectors; + return; + } + /* If not the standard mode, interpolate */ + /* Compute per-codec-band allocation from per-critical-band matrix */ + for (i=0;inbEBands;j++) + { + int k; + for (k=0;k mode->eBands[j]*(opus_int32)mode->Fs/mode->shortMdctSize) + break; + } + if (k>maxBands-1) + allocVectors[i*mode->nbEBands+j] = band_allocation[i*maxBands + maxBands-1]; + else { + opus_int32 a0, a1; + a1 = mode->eBands[j]*(opus_int32)mode->Fs/mode->shortMdctSize - 400*(opus_int32)eband5ms[k-1]; + a0 = 400*(opus_int32)eband5ms[k] - mode->eBands[j]*(opus_int32)mode->Fs/mode->shortMdctSize; + allocVectors[i*mode->nbEBands+j] = (a0*band_allocation[i*maxBands+k-1] + + a1*band_allocation[i*maxBands+k])/(a0+a1); + } + } + } + + /*printf ("\n"); + for (i=0;inbEBands;j++) + printf ("%d ", allocVectors[i*mode->nbEBands+j]); + printf ("\n"); + } + exit(0);*/ + + mode->allocVectors = allocVectors; +} + +#endif /* CUSTOM_MODES */ + +CELTMode *opus_custom_mode_create(opus_int32 Fs, int frame_size, int *error) +{ + int i; +#ifdef CUSTOM_MODES + CELTMode *mode=NULL; + int res; + opus_val16 *window; + opus_int16 *logN; + int LM; + ALLOC_STACK; +#if !defined(VAR_ARRAYS) && !defined(USE_ALLOCA) + if (global_stack==NULL) + goto failure; +#endif +#endif + +#ifndef CUSTOM_MODES_ONLY + for (i=0;iFs && + (frame_size<shortMdctSize*static_mode_list[i]->nbShortMdcts) + { + if (error) + *error = OPUS_OK; + return (CELTMode*)static_mode_list[i]; + } + } + } +#endif /* CUSTOM_MODES_ONLY */ + +#ifndef CUSTOM_MODES + if (error) + *error = OPUS_BAD_ARG; + return NULL; +#else + + /* The good thing here is that permutation of the arguments will automatically be invalid */ + + if (Fs < 8000 || Fs > 96000) + { + if (error) + *error = OPUS_BAD_ARG; + return NULL; + } + if (frame_size < 40 || frame_size > 1024 || frame_size%2!=0) + { + if (error) + *error = OPUS_BAD_ARG; + return NULL; + } + /* Frames of less than 1ms are not supported. */ + if ((opus_int32)frame_size*1000 < Fs) + { + if (error) + *error = OPUS_BAD_ARG; + return NULL; + } + + if ((opus_int32)frame_size*75 >= Fs && (frame_size%16)==0) + { + LM = 3; + } else if ((opus_int32)frame_size*150 >= Fs && (frame_size%8)==0) + { + LM = 2; + } else if ((opus_int32)frame_size*300 >= Fs && (frame_size%4)==0) + { + LM = 1; + } else + { + LM = 0; + } + + /* Shorts longer than 3.3ms are not supported. */ + if ((opus_int32)(frame_size>>LM)*300 > Fs) + { + if (error) + *error = OPUS_BAD_ARG; + return NULL; + } + + mode = opus_alloc(sizeof(CELTMode)); + if (mode==NULL) + goto failure; + mode->Fs = Fs; + + /* Pre/de-emphasis depends on sampling rate. The "standard" pre-emphasis + is defined as A(z) = 1 - 0.85*z^-1 at 48 kHz. Other rates should + approximate that. */ + if(Fs < 12000) /* 8 kHz */ + { + mode->preemph[0] = QCONST16(0.3500061035f, 15); + mode->preemph[1] = -QCONST16(0.1799926758f, 15); + mode->preemph[2] = QCONST16(0.2719968125f, SIG_SHIFT); /* exact 1/preemph[3] */ + mode->preemph[3] = QCONST16(3.6765136719f, 13); + } else if(Fs < 24000) /* 16 kHz */ + { + mode->preemph[0] = QCONST16(0.6000061035f, 15); + mode->preemph[1] = -QCONST16(0.1799926758f, 15); + mode->preemph[2] = QCONST16(0.4424998650f, SIG_SHIFT); /* exact 1/preemph[3] */ + mode->preemph[3] = QCONST16(2.2598876953f, 13); + } else if(Fs < 40000) /* 32 kHz */ + { + mode->preemph[0] = QCONST16(0.7799987793f, 15); + mode->preemph[1] = -QCONST16(0.1000061035f, 15); + mode->preemph[2] = QCONST16(0.7499771125f, SIG_SHIFT); /* exact 1/preemph[3] */ + mode->preemph[3] = QCONST16(1.3333740234f, 13); + } else /* 48 kHz */ + { + mode->preemph[0] = QCONST16(0.8500061035f, 15); + mode->preemph[1] = QCONST16(0.0f, 15); + mode->preemph[2] = QCONST16(1.f, SIG_SHIFT); + mode->preemph[3] = QCONST16(1.f, 13); + } + + mode->maxLM = LM; + mode->nbShortMdcts = 1<shortMdctSize = frame_size/mode->nbShortMdcts; + res = (mode->Fs+mode->shortMdctSize)/(2*mode->shortMdctSize); + + mode->eBands = compute_ebands(Fs, mode->shortMdctSize, res, &mode->nbEBands); + if (mode->eBands==NULL) + goto failure; +#if !defined(SMALL_FOOTPRINT) + /* Make sure we don't allocate a band larger than our PVQ table. + 208 should be enough, but let's be paranoid. */ + if ((mode->eBands[mode->nbEBands] - mode->eBands[mode->nbEBands-1])< + 208) { + goto failure; + } +#endif + + mode->effEBands = mode->nbEBands; + while (mode->eBands[mode->effEBands] > mode->shortMdctSize) + mode->effEBands--; + + /* Overlap must be divisible by 4 */ + mode->overlap = ((mode->shortMdctSize>>2)<<2); + + compute_allocation_table(mode); + if (mode->allocVectors==NULL) + goto failure; + + window = (opus_val16*)opus_alloc(mode->overlap*sizeof(opus_val16)); + if (window==NULL) + goto failure; + +#ifndef FIXED_POINT + for (i=0;ioverlap;i++) + window[i] = Q15ONE*sin(.5*M_PI* sin(.5*M_PI*(i+.5)/mode->overlap) * sin(.5*M_PI*(i+.5)/mode->overlap)); +#else + for (i=0;ioverlap;i++) + window[i] = MIN32(32767,floor(.5+32768.*sin(.5*M_PI* sin(.5*M_PI*(i+.5)/mode->overlap) * sin(.5*M_PI*(i+.5)/mode->overlap)))); +#endif + mode->window = window; + + logN = (opus_int16*)opus_alloc(mode->nbEBands*sizeof(opus_int16)); + if (logN==NULL) + goto failure; + + for (i=0;inbEBands;i++) + logN[i] = log2_frac(mode->eBands[i+1]-mode->eBands[i], BITRES); + mode->logN = logN; + + compute_pulse_cache(mode, mode->maxLM); + + if (clt_mdct_init(&mode->mdct, 2*mode->shortMdctSize*mode->nbShortMdcts, + mode->maxLM) == 0) + goto failure; + + if (error) + *error = OPUS_OK; + + return mode; +failure: + if (error) + *error = OPUS_ALLOC_FAIL; + if (mode!=NULL) + opus_custom_mode_destroy(mode); + return NULL; +#endif /* !CUSTOM_MODES */ +} + +#ifdef CUSTOM_MODES +void opus_custom_mode_destroy(CELTMode *mode) +{ + if (mode == NULL) + return; +#ifndef CUSTOM_MODES_ONLY + { + int i; + for (i=0;ieBands); + opus_free((opus_int16*)mode->allocVectors); + + opus_free((opus_val16*)mode->window); + opus_free((opus_int16*)mode->logN); + + opus_free((opus_int16*)mode->cache.index); + opus_free((unsigned char*)mode->cache.bits); + opus_free((unsigned char*)mode->cache.caps); + clt_mdct_clear(&mode->mdct); + + opus_free((CELTMode *)mode); +} +#endif diff --git a/src/opus-1.1/celt/modes.h b/src/opus-1.1/celt/modes.h new file mode 100644 index 00000000..c8340f98 --- /dev/null +++ b/src/opus-1.1/celt/modes.h @@ -0,0 +1,83 @@ +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation + Copyright (c) 2008 Gregory Maxwell + Written by Jean-Marc Valin and Gregory Maxwell */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef MODES_H +#define MODES_H + +#include "opus_types.h" +#include "celt.h" +#include "arch.h" +#include "mdct.h" +#include "entenc.h" +#include "entdec.h" + +#define MAX_PERIOD 1024 + +#ifndef OVERLAP +#define OVERLAP(mode) ((mode)->overlap) +#endif + +#ifndef FRAMESIZE +#define FRAMESIZE(mode) ((mode)->mdctSize) +#endif + +typedef struct { + int size; + const opus_int16 *index; + const unsigned char *bits; + const unsigned char *caps; +} PulseCache; + +/** Mode definition (opaque) + @brief Mode definition + */ +struct OpusCustomMode { + opus_int32 Fs; + int overlap; + + int nbEBands; + int effEBands; + opus_val16 preemph[4]; + const opus_int16 *eBands; /**< Definition for each "pseudo-critical band" */ + + int maxLM; + int nbShortMdcts; + int shortMdctSize; + + int nbAllocVectors; /**< Number of lines in the matrix below */ + const unsigned char *allocVectors; /**< Number of bits in each band for several rates */ + const opus_int16 *logN; + + const opus_val16 *window; + mdct_lookup mdct; + PulseCache cache; +}; + + +#endif diff --git a/src/opus-1.1/celt/opus_custom_demo.c b/src/opus-1.1/celt/opus_custom_demo.c new file mode 100644 index 00000000..ae41c0de --- /dev/null +++ b/src/opus-1.1/celt/opus_custom_demo.c @@ -0,0 +1,210 @@ +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation + Written by Jean-Marc Valin */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "opus_custom.h" +#include "arch.h" +#include +#include +#include +#include + +#define MAX_PACKET 1275 + +int main(int argc, char *argv[]) +{ + int err; + char *inFile, *outFile; + FILE *fin, *fout; + OpusCustomMode *mode=NULL; + OpusCustomEncoder *enc; + OpusCustomDecoder *dec; + int len; + opus_int32 frame_size, channels, rate; + int bytes_per_packet; + unsigned char data[MAX_PACKET]; + int complexity; +#if !(defined (FIXED_POINT) && !defined(CUSTOM_MODES)) && defined(RESYNTH) + int i; + double rmsd = 0; +#endif + int count = 0; + opus_int32 skip; + opus_int16 *in, *out; + if (argc != 9 && argc != 8 && argc != 7) + { + fprintf (stderr, "Usage: test_opus_custom " + " [ [packet loss rate]] " + " \n"); + return 1; + } + + rate = (opus_int32)atol(argv[1]); + channels = atoi(argv[2]); + frame_size = atoi(argv[3]); + mode = opus_custom_mode_create(rate, frame_size, NULL); + if (mode == NULL) + { + fprintf(stderr, "failed to create a mode\n"); + return 1; + } + + bytes_per_packet = atoi(argv[4]); + if (bytes_per_packet < 0 || bytes_per_packet > MAX_PACKET) + { + fprintf (stderr, "bytes per packet must be between 0 and %d\n", + MAX_PACKET); + return 1; + } + + inFile = argv[argc-2]; + fin = fopen(inFile, "rb"); + if (!fin) + { + fprintf (stderr, "Could not open input file %s\n", argv[argc-2]); + return 1; + } + outFile = argv[argc-1]; + fout = fopen(outFile, "wb+"); + if (!fout) + { + fprintf (stderr, "Could not open output file %s\n", argv[argc-1]); + fclose(fin); + return 1; + } + + enc = opus_custom_encoder_create(mode, channels, &err); + if (err != 0) + { + fprintf(stderr, "Failed to create the encoder: %s\n", opus_strerror(err)); + fclose(fin); + fclose(fout); + return 1; + } + dec = opus_custom_decoder_create(mode, channels, &err); + if (err != 0) + { + fprintf(stderr, "Failed to create the decoder: %s\n", opus_strerror(err)); + fclose(fin); + fclose(fout); + return 1; + } + opus_custom_decoder_ctl(dec, OPUS_GET_LOOKAHEAD(&skip)); + + if (argc>7) + { + complexity=atoi(argv[5]); + opus_custom_encoder_ctl(enc,OPUS_SET_COMPLEXITY(complexity)); + } + + in = (opus_int16*)malloc(frame_size*channels*sizeof(opus_int16)); + out = (opus_int16*)malloc(frame_size*channels*sizeof(opus_int16)); + + while (!feof(fin)) + { + int ret; + err = fread(in, sizeof(short), frame_size*channels, fin); + if (feof(fin)) + break; + len = opus_custom_encode(enc, in, frame_size, data, bytes_per_packet); + if (len <= 0) + fprintf (stderr, "opus_custom_encode() failed: %s\n", opus_strerror(len)); + + /* This is for simulating bit errors */ +#if 0 + int errors = 0; + int eid = 0; + /* This simulates random bit error */ + for (i=0;i 0) + { + rmsd = sqrt(rmsd/(1.0*frame_size*channels*count)); + fprintf (stderr, "Error: encoder doesn't match decoder\n"); + fprintf (stderr, "RMS mismatch is %f\n", rmsd); + return 1; + } else { + fprintf (stderr, "Encoder matches decoder!!\n"); + } +#endif + return 0; +} + diff --git a/src/opus-1.1/celt/os_support.h b/src/opus-1.1/celt/os_support.h new file mode 100644 index 00000000..5e47e3cf --- /dev/null +++ b/src/opus-1.1/celt/os_support.h @@ -0,0 +1,92 @@ +/* Copyright (C) 2007 Jean-Marc Valin + + File: os_support.h + This is the (tiny) OS abstraction layer. Aside from math.h, this is the + only place where system headers are allowed. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef OS_SUPPORT_H +#define OS_SUPPORT_H + +#ifdef CUSTOM_SUPPORT +# include "custom_support.h" +#endif + +#include "opus_types.h" +#include "opus_defines.h" + +#include +#include +#include + +/** Opus wrapper for malloc(). To do your own dynamic allocation, all you need to do is replace this function and opus_free */ +#ifndef OVERRIDE_OPUS_ALLOC +static OPUS_INLINE void *opus_alloc (size_t size) +{ + return malloc(size); +} +#endif + +/** Same as celt_alloc(), except that the area is only needed inside a CELT call (might cause problem with wideband though) */ +#ifndef OVERRIDE_OPUS_ALLOC_SCRATCH +static OPUS_INLINE void *opus_alloc_scratch (size_t size) +{ + /* Scratch space doesn't need to be cleared */ + return opus_alloc(size); +} +#endif + +/** Opus wrapper for free(). To do your own dynamic allocation, all you need to do is replace this function and opus_alloc */ +#ifndef OVERRIDE_OPUS_FREE +static OPUS_INLINE void opus_free (void *ptr) +{ + free(ptr); +} +#endif + +/** Copy n bytes of memory from src to dst. The 0* term provides compile-time type checking */ +#ifndef OVERRIDE_OPUS_COPY +#define OPUS_COPY(dst, src, n) (memcpy((dst), (src), (n)*sizeof(*(dst)) + 0*((dst)-(src)) )) +#endif + +/** Copy n bytes of memory from src to dst, allowing overlapping regions. The 0* term + provides compile-time type checking */ +#ifndef OVERRIDE_OPUS_MOVE +#define OPUS_MOVE(dst, src, n) (memmove((dst), (src), (n)*sizeof(*(dst)) + 0*((dst)-(src)) )) +#endif + +/** Set n elements of dst to zero, starting at address s */ +#ifndef OVERRIDE_OPUS_CLEAR +#define OPUS_CLEAR(dst, n) (memset((dst), 0, (n)*sizeof(*(dst)))) +#endif + +/*#ifdef __GNUC__ +#pragma GCC poison printf sprintf +#pragma GCC poison malloc free realloc calloc +#endif*/ + +#endif /* OS_SUPPORT_H */ + diff --git a/src/opus-1.1/celt/pitch.c b/src/opus-1.1/celt/pitch.c new file mode 100644 index 00000000..d2b30544 --- /dev/null +++ b/src/opus-1.1/celt/pitch.c @@ -0,0 +1,537 @@ +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation + Written by Jean-Marc Valin */ +/** + @file pitch.c + @brief Pitch analysis + */ + +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "pitch.h" +#include "os_support.h" +#include "modes.h" +#include "stack_alloc.h" +#include "mathops.h" +#include "celt_lpc.h" + +static void find_best_pitch(opus_val32 *xcorr, opus_val16 *y, int len, + int max_pitch, int *best_pitch +#ifdef FIXED_POINT + , int yshift, opus_val32 maxcorr +#endif + ) +{ + int i, j; + opus_val32 Syy=1; + opus_val16 best_num[2]; + opus_val32 best_den[2]; +#ifdef FIXED_POINT + int xshift; + + xshift = celt_ilog2(maxcorr)-14; +#endif + + best_num[0] = -1; + best_num[1] = -1; + best_den[0] = 0; + best_den[1] = 0; + best_pitch[0] = 0; + best_pitch[1] = 1; + for (j=0;j0) + { + opus_val16 num; + opus_val32 xcorr16; + xcorr16 = EXTRACT16(VSHR32(xcorr[i], xshift)); +#ifndef FIXED_POINT + /* Considering the range of xcorr16, this should avoid both underflows + and overflows (inf) when squaring xcorr16 */ + xcorr16 *= 1e-12f; +#endif + num = MULT16_16_Q15(xcorr16,xcorr16); + if (MULT16_32_Q15(num,best_den[1]) > MULT16_32_Q15(best_num[1],Syy)) + { + if (MULT16_32_Q15(num,best_den[0]) > MULT16_32_Q15(best_num[0],Syy)) + { + best_num[1] = best_num[0]; + best_den[1] = best_den[0]; + best_pitch[1] = best_pitch[0]; + best_num[0] = num; + best_den[0] = Syy; + best_pitch[0] = i; + } else { + best_num[1] = num; + best_den[1] = Syy; + best_pitch[1] = i; + } + } + } + Syy += SHR32(MULT16_16(y[i+len],y[i+len]),yshift) - SHR32(MULT16_16(y[i],y[i]),yshift); + Syy = MAX32(1, Syy); + } +} + +static void celt_fir5(const opus_val16 *x, + const opus_val16 *num, + opus_val16 *y, + int N, + opus_val16 *mem) +{ + int i; + opus_val16 num0, num1, num2, num3, num4; + opus_val32 mem0, mem1, mem2, mem3, mem4; + num0=num[0]; + num1=num[1]; + num2=num[2]; + num3=num[3]; + num4=num[4]; + mem0=mem[0]; + mem1=mem[1]; + mem2=mem[2]; + mem3=mem[3]; + mem4=mem[4]; + for (i=0;i>1;i++) + x_lp[i] = SHR32(HALF32(HALF32(x[0][(2*i-1)]+x[0][(2*i+1)])+x[0][2*i]), shift); + x_lp[0] = SHR32(HALF32(HALF32(x[0][1])+x[0][0]), shift); + if (C==2) + { + for (i=1;i>1;i++) + x_lp[i] += SHR32(HALF32(HALF32(x[1][(2*i-1)]+x[1][(2*i+1)])+x[1][2*i]), shift); + x_lp[0] += SHR32(HALF32(HALF32(x[1][1])+x[1][0]), shift); + } + + _celt_autocorr(x_lp, ac, NULL, 0, + 4, len>>1, arch); + + /* Noise floor -40 dB */ +#ifdef FIXED_POINT + ac[0] += SHR32(ac[0],13); +#else + ac[0] *= 1.0001f; +#endif + /* Lag windowing */ + for (i=1;i<=4;i++) + { + /*ac[i] *= exp(-.5*(2*M_PI*.002*i)*(2*M_PI*.002*i));*/ +#ifdef FIXED_POINT + ac[i] -= MULT16_32_Q15(2*i*i, ac[i]); +#else + ac[i] -= ac[i]*(.008f*i)*(.008f*i); +#endif + } + + _celt_lpc(lpc, ac, 4); + for (i=0;i<4;i++) + { + tmp = MULT16_16_Q15(QCONST16(.9f,15), tmp); + lpc[i] = MULT16_16_Q15(lpc[i], tmp); + } + /* Add a zero */ + lpc2[0] = lpc[0] + QCONST16(.8f,SIG_SHIFT); + lpc2[1] = lpc[1] + MULT16_16_Q15(c1,lpc[0]); + lpc2[2] = lpc[2] + MULT16_16_Q15(c1,lpc[1]); + lpc2[3] = lpc[3] + MULT16_16_Q15(c1,lpc[2]); + lpc2[4] = MULT16_16_Q15(c1,lpc[3]); + celt_fir5(x_lp, lpc2, x_lp, len>>1, mem); +} + +#if 0 /* This is a simple version of the pitch correlation that should work + well on DSPs like Blackfin and TI C5x/C6x */ + +#ifdef FIXED_POINT +opus_val32 +#else +void +#endif +celt_pitch_xcorr(opus_val16 *x, opus_val16 *y, opus_val32 *xcorr, int len, int max_pitch) +{ + int i, j; +#ifdef FIXED_POINT + opus_val32 maxcorr=1; +#endif + for (i=0;i0); + celt_assert((((unsigned char *)_x-(unsigned char *)NULL)&3)==0); +#ifdef FIXED_POINT + opus_val32 maxcorr=1; +#endif + for (i=0;i0); + celt_assert(max_pitch>0); + lag = len+max_pitch; + + ALLOC(x_lp4, len>>2, opus_val16); + ALLOC(y_lp4, lag>>2, opus_val16); + ALLOC(xcorr, max_pitch>>1, opus_val32); + + /* Downsample by 2 again */ + for (j=0;j>2;j++) + x_lp4[j] = x_lp[2*j]; + for (j=0;j>2;j++) + y_lp4[j] = y[2*j]; + +#ifdef FIXED_POINT + xmax = celt_maxabs16(x_lp4, len>>2); + ymax = celt_maxabs16(y_lp4, lag>>2); + shift = celt_ilog2(MAX32(1, MAX32(xmax, ymax)))-11; + if (shift>0) + { + for (j=0;j>2;j++) + x_lp4[j] = SHR16(x_lp4[j], shift); + for (j=0;j>2;j++) + y_lp4[j] = SHR16(y_lp4[j], shift); + /* Use double the shift for a MAC */ + shift *= 2; + } else { + shift = 0; + } +#endif + + /* Coarse search with 4x decimation */ + +#ifdef FIXED_POINT + maxcorr = +#endif + celt_pitch_xcorr(x_lp4, y_lp4, xcorr, len>>2, max_pitch>>2, arch); + + find_best_pitch(xcorr, y_lp4, len>>2, max_pitch>>2, best_pitch +#ifdef FIXED_POINT + , 0, maxcorr +#endif + ); + + /* Finer search with 2x decimation */ +#ifdef FIXED_POINT + maxcorr=1; +#endif + for (i=0;i>1;i++) + { + opus_val32 sum=0; + xcorr[i] = 0; + if (abs(i-2*best_pitch[0])>2 && abs(i-2*best_pitch[1])>2) + continue; + for (j=0;j>1;j++) + sum += SHR32(MULT16_16(x_lp[j],y[i+j]), shift); + xcorr[i] = MAX32(-1, sum); +#ifdef FIXED_POINT + maxcorr = MAX32(maxcorr, sum); +#endif + } + find_best_pitch(xcorr, y, len>>1, max_pitch>>1, best_pitch +#ifdef FIXED_POINT + , shift+1, maxcorr +#endif + ); + + /* Refine by pseudo-interpolation */ + if (best_pitch[0]>0 && best_pitch[0]<(max_pitch>>1)-1) + { + opus_val32 a, b, c; + a = xcorr[best_pitch[0]-1]; + b = xcorr[best_pitch[0]]; + c = xcorr[best_pitch[0]+1]; + if ((c-a) > MULT16_32_Q15(QCONST16(.7f,15),b-a)) + offset = 1; + else if ((a-c) > MULT16_32_Q15(QCONST16(.7f,15),b-c)) + offset = -1; + else + offset = 0; + } else { + offset = 0; + } + *pitch = 2*best_pitch[0]-offset; + + RESTORE_STACK; +} + +static const int second_check[16] = {0, 0, 3, 2, 3, 2, 5, 2, 3, 2, 3, 2, 5, 2, 3, 2}; +opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod, + int N, int *T0_, int prev_period, opus_val16 prev_gain) +{ + int k, i, T, T0; + opus_val16 g, g0; + opus_val16 pg; + opus_val32 xy,xx,yy,xy2; + opus_val32 xcorr[3]; + opus_val32 best_xy, best_yy; + int offset; + int minperiod0; + VARDECL(opus_val32, yy_lookup); + SAVE_STACK; + + minperiod0 = minperiod; + maxperiod /= 2; + minperiod /= 2; + *T0_ /= 2; + prev_period /= 2; + N /= 2; + x += maxperiod; + if (*T0_>=maxperiod) + *T0_=maxperiod-1; + + T = T0 = *T0_; + ALLOC(yy_lookup, maxperiod+1, opus_val32); + dual_inner_prod(x, x, x-T0, N, &xx, &xy); + yy_lookup[0] = xx; + yy=xx; + for (i=1;i<=maxperiod;i++) + { + yy = yy+MULT16_16(x[-i],x[-i])-MULT16_16(x[N-i],x[N-i]); + yy_lookup[i] = MAX32(0, yy); + } + yy = yy_lookup[T0]; + best_xy = xy; + best_yy = yy; +#ifdef FIXED_POINT + { + opus_val32 x2y2; + int sh, t; + x2y2 = 1+HALF32(MULT32_32_Q31(xx,yy)); + sh = celt_ilog2(x2y2)>>1; + t = VSHR32(x2y2, 2*(sh-7)); + g = g0 = VSHR32(MULT16_32_Q15(celt_rsqrt_norm(t), xy),sh+1); + } +#else + g = g0 = xy/celt_sqrt(1+xx*yy); +#endif + /* Look for any pitch at T/k */ + for (k=2;k<=15;k++) + { + int T1, T1b; + opus_val16 g1; + opus_val16 cont=0; + opus_val16 thresh; + T1 = (2*T0+k)/(2*k); + if (T1 < minperiod) + break; + /* Look for another strong correlation at T1b */ + if (k==2) + { + if (T1+T0>maxperiod) + T1b = T0; + else + T1b = T0+T1; + } else + { + T1b = (2*second_check[k]*T0+k)/(2*k); + } + dual_inner_prod(x, &x[-T1], &x[-T1b], N, &xy, &xy2); + xy += xy2; + yy = yy_lookup[T1] + yy_lookup[T1b]; +#ifdef FIXED_POINT + { + opus_val32 x2y2; + int sh, t; + x2y2 = 1+MULT32_32_Q31(xx,yy); + sh = celt_ilog2(x2y2)>>1; + t = VSHR32(x2y2, 2*(sh-7)); + g1 = VSHR32(MULT16_32_Q15(celt_rsqrt_norm(t), xy),sh+1); + } +#else + g1 = xy/celt_sqrt(1+2.f*xx*1.f*yy); +#endif + if (abs(T1-prev_period)<=1) + cont = prev_gain; + else if (abs(T1-prev_period)<=2 && 5*k*k < T0) + cont = HALF32(prev_gain); + else + cont = 0; + thresh = MAX16(QCONST16(.3f,15), MULT16_16_Q15(QCONST16(.7f,15),g0)-cont); + /* Bias against very high pitch (very short period) to avoid false-positives + due to short-term correlation */ + if (T1<3*minperiod) + thresh = MAX16(QCONST16(.4f,15), MULT16_16_Q15(QCONST16(.85f,15),g0)-cont); + else if (T1<2*minperiod) + thresh = MAX16(QCONST16(.5f,15), MULT16_16_Q15(QCONST16(.9f,15),g0)-cont); + if (g1 > thresh) + { + best_xy = xy; + best_yy = yy; + T = T1; + g = g1; + } + } + best_xy = MAX32(0, best_xy); + if (best_yy <= best_xy) + pg = Q15ONE; + else + pg = SHR32(frac_div32(best_xy,best_yy+1),16); + + for (k=0;k<3;k++) + { + int T1 = T+k-1; + xy = 0; + for (i=0;i MULT16_32_Q15(QCONST16(.7f,15),xcorr[1]-xcorr[0])) + offset = 1; + else if ((xcorr[0]-xcorr[2]) > MULT16_32_Q15(QCONST16(.7f,15),xcorr[1]-xcorr[2])) + offset = -1; + else + offset = 0; + if (pg > g) + pg = g; + *T0_ = 2*T+offset; + + if (*T0_=3); + y_3=0; /* gcc doesn't realize that y_3 can't be used uninitialized */ + y_0=*y++; + y_1=*y++; + y_2=*y++; + for (j=0;j +#include "os_support.h" +#include "arch.h" +#include "mathops.h" +#include "stack_alloc.h" +#include "rate.h" + +#ifdef FIXED_POINT +/* Mean energy in each band quantized in Q4 */ +const signed char eMeans[25] = { + 103,100, 92, 85, 81, + 77, 72, 70, 78, 75, + 73, 71, 78, 74, 69, + 72, 70, 74, 76, 71, + 60, 60, 60, 60, 60 +}; +#else +/* Mean energy in each band quantized in Q4 and converted back to float */ +const opus_val16 eMeans[25] = { + 6.437500f, 6.250000f, 5.750000f, 5.312500f, 5.062500f, + 4.812500f, 4.500000f, 4.375000f, 4.875000f, 4.687500f, + 4.562500f, 4.437500f, 4.875000f, 4.625000f, 4.312500f, + 4.500000f, 4.375000f, 4.625000f, 4.750000f, 4.437500f, + 3.750000f, 3.750000f, 3.750000f, 3.750000f, 3.750000f +}; +#endif +/* prediction coefficients: 0.9, 0.8, 0.65, 0.5 */ +#ifdef FIXED_POINT +static const opus_val16 pred_coef[4] = {29440, 26112, 21248, 16384}; +static const opus_val16 beta_coef[4] = {30147, 22282, 12124, 6554}; +static const opus_val16 beta_intra = 4915; +#else +static const opus_val16 pred_coef[4] = {29440/32768., 26112/32768., 21248/32768., 16384/32768.}; +static const opus_val16 beta_coef[4] = {30147/32768., 22282/32768., 12124/32768., 6554/32768.}; +static const opus_val16 beta_intra = 4915/32768.; +#endif + +/*Parameters of the Laplace-like probability models used for the coarse energy. + There is one pair of parameters for each frame size, prediction type + (inter/intra), and band number. + The first number of each pair is the probability of 0, and the second is the + decay rate, both in Q8 precision.*/ +static const unsigned char e_prob_model[4][2][42] = { + /*120 sample frames.*/ + { + /*Inter*/ + { + 72, 127, 65, 129, 66, 128, 65, 128, 64, 128, 62, 128, 64, 128, + 64, 128, 92, 78, 92, 79, 92, 78, 90, 79, 116, 41, 115, 40, + 114, 40, 132, 26, 132, 26, 145, 17, 161, 12, 176, 10, 177, 11 + }, + /*Intra*/ + { + 24, 179, 48, 138, 54, 135, 54, 132, 53, 134, 56, 133, 55, 132, + 55, 132, 61, 114, 70, 96, 74, 88, 75, 88, 87, 74, 89, 66, + 91, 67, 100, 59, 108, 50, 120, 40, 122, 37, 97, 43, 78, 50 + } + }, + /*240 sample frames.*/ + { + /*Inter*/ + { + 83, 78, 84, 81, 88, 75, 86, 74, 87, 71, 90, 73, 93, 74, + 93, 74, 109, 40, 114, 36, 117, 34, 117, 34, 143, 17, 145, 18, + 146, 19, 162, 12, 165, 10, 178, 7, 189, 6, 190, 8, 177, 9 + }, + /*Intra*/ + { + 23, 178, 54, 115, 63, 102, 66, 98, 69, 99, 74, 89, 71, 91, + 73, 91, 78, 89, 86, 80, 92, 66, 93, 64, 102, 59, 103, 60, + 104, 60, 117, 52, 123, 44, 138, 35, 133, 31, 97, 38, 77, 45 + } + }, + /*480 sample frames.*/ + { + /*Inter*/ + { + 61, 90, 93, 60, 105, 42, 107, 41, 110, 45, 116, 38, 113, 38, + 112, 38, 124, 26, 132, 27, 136, 19, 140, 20, 155, 14, 159, 16, + 158, 18, 170, 13, 177, 10, 187, 8, 192, 6, 175, 9, 159, 10 + }, + /*Intra*/ + { + 21, 178, 59, 110, 71, 86, 75, 85, 84, 83, 91, 66, 88, 73, + 87, 72, 92, 75, 98, 72, 105, 58, 107, 54, 115, 52, 114, 55, + 112, 56, 129, 51, 132, 40, 150, 33, 140, 29, 98, 35, 77, 42 + } + }, + /*960 sample frames.*/ + { + /*Inter*/ + { + 42, 121, 96, 66, 108, 43, 111, 40, 117, 44, 123, 32, 120, 36, + 119, 33, 127, 33, 134, 34, 139, 21, 147, 23, 152, 20, 158, 25, + 154, 26, 166, 21, 173, 16, 184, 13, 184, 10, 150, 13, 139, 15 + }, + /*Intra*/ + { + 22, 178, 63, 114, 74, 82, 84, 83, 92, 82, 103, 62, 96, 72, + 96, 67, 101, 73, 107, 72, 113, 55, 118, 52, 125, 52, 118, 52, + 117, 55, 135, 49, 137, 39, 157, 32, 145, 29, 97, 33, 77, 40 + } + } +}; + +static const unsigned char small_energy_icdf[3]={2,1,0}; + +static opus_val32 loss_distortion(const opus_val16 *eBands, opus_val16 *oldEBands, int start, int end, int len, int C) +{ + int c, i; + opus_val32 dist = 0; + c=0; do { + for (i=start;inbEBands]; + oldE = MAX16(-QCONST16(9.f,DB_SHIFT), oldEBands[i+c*m->nbEBands]); +#ifdef FIXED_POINT + f = SHL32(EXTEND32(x),7) - PSHR32(MULT16_16(coef,oldE), 8) - prev[c]; + /* Rounding to nearest integer here is really important! */ + qi = (f+QCONST32(.5f,DB_SHIFT+7))>>(DB_SHIFT+7); + decay_bound = EXTRACT16(MAX32(-QCONST16(28.f,DB_SHIFT), + SUB32((opus_val32)oldEBands[i+c*m->nbEBands],max_decay))); +#else + f = x-coef*oldE-prev[c]; + /* Rounding to nearest integer here is really important! */ + qi = (int)floor(.5f+f); + decay_bound = MAX16(-QCONST16(28.f,DB_SHIFT), oldEBands[i+c*m->nbEBands]) - max_decay; +#endif + /* Prevent the energy from going down too quickly (e.g. for bands + that have just one bin) */ + if (qi < 0 && x < decay_bound) + { + qi += (int)SHR16(SUB16(decay_bound,x), DB_SHIFT); + if (qi > 0) + qi = 0; + } + qi0 = qi; + /* If we don't have enough bits to encode all the energy, just assume + something safe. */ + tell = ec_tell(enc); + bits_left = budget-tell-3*C*(end-i); + if (i!=start && bits_left < 30) + { + if (bits_left < 24) + qi = IMIN(1, qi); + if (bits_left < 16) + qi = IMAX(-1, qi); + } + if (lfe && i>=2) + qi = IMIN(qi, 0); + if (budget-tell >= 15) + { + int pi; + pi = 2*IMIN(i,20); + ec_laplace_encode(enc, &qi, + prob_model[pi]<<7, prob_model[pi+1]<<6); + } + else if(budget-tell >= 2) + { + qi = IMAX(-1, IMIN(qi, 1)); + ec_enc_icdf(enc, 2*qi^-(qi<0), small_energy_icdf, 2); + } + else if(budget-tell >= 1) + { + qi = IMIN(0, qi); + ec_enc_bit_logp(enc, -qi, 1); + } + else + qi = -1; + error[i+c*m->nbEBands] = PSHR32(f,7) - SHL16(qi,DB_SHIFT); + badness += abs(qi0-qi); + q = (opus_val32)SHL32(EXTEND32(qi),DB_SHIFT); + + tmp = PSHR32(MULT16_16(coef,oldE),8) + prev[c] + SHL32(q,7); +#ifdef FIXED_POINT + tmp = MAX32(-QCONST32(28.f, DB_SHIFT+7), tmp); +#endif + oldEBands[i+c*m->nbEBands] = PSHR32(tmp, 7); + prev[c] = prev[c] + SHL32(q,7) - MULT16_16(beta,PSHR32(q,8)); + } while (++c < C); + } + return lfe ? 0 : badness; +} + +void quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd, + const opus_val16 *eBands, opus_val16 *oldEBands, opus_uint32 budget, + opus_val16 *error, ec_enc *enc, int C, int LM, int nbAvailableBytes, + int force_intra, opus_val32 *delayedIntra, int two_pass, int loss_rate, int lfe) +{ + int intra; + opus_val16 max_decay; + VARDECL(opus_val16, oldEBands_intra); + VARDECL(opus_val16, error_intra); + ec_enc enc_start_state; + opus_uint32 tell; + int badness1=0; + opus_int32 intra_bias; + opus_val32 new_distortion; + SAVE_STACK; + + intra = force_intra || (!two_pass && *delayedIntra>2*C*(end-start) && nbAvailableBytes > (end-start)*C); + intra_bias = (opus_int32)((budget**delayedIntra*loss_rate)/(C*512)); + new_distortion = loss_distortion(eBands, oldEBands, start, effEnd, m->nbEBands, C); + + tell = ec_tell(enc); + if (tell+3 > budget) + two_pass = intra = 0; + + max_decay = QCONST16(16.f,DB_SHIFT); + if (end-start>10) + { +#ifdef FIXED_POINT + max_decay = MIN32(max_decay, SHL32(EXTEND32(nbAvailableBytes),DB_SHIFT-3)); +#else + max_decay = MIN32(max_decay, .125f*nbAvailableBytes); +#endif + } + if (lfe) + max_decay=3; + enc_start_state = *enc; + + ALLOC(oldEBands_intra, C*m->nbEBands, opus_val16); + ALLOC(error_intra, C*m->nbEBands, opus_val16); + OPUS_COPY(oldEBands_intra, oldEBands, C*m->nbEBands); + + if (two_pass || intra) + { + badness1 = quant_coarse_energy_impl(m, start, end, eBands, oldEBands_intra, budget, + tell, e_prob_model[LM][1], error_intra, enc, C, LM, 1, max_decay, lfe); + } + + if (!intra) + { + unsigned char *intra_buf; + ec_enc enc_intra_state; + opus_int32 tell_intra; + opus_uint32 nstart_bytes; + opus_uint32 nintra_bytes; + opus_uint32 save_bytes; + int badness2; + VARDECL(unsigned char, intra_bits); + + tell_intra = ec_tell_frac(enc); + + enc_intra_state = *enc; + + nstart_bytes = ec_range_bytes(&enc_start_state); + nintra_bytes = ec_range_bytes(&enc_intra_state); + intra_buf = ec_get_buffer(&enc_intra_state) + nstart_bytes; + save_bytes = nintra_bytes-nstart_bytes; + if (save_bytes == 0) + save_bytes = ALLOC_NONE; + ALLOC(intra_bits, save_bytes, unsigned char); + /* Copy bits from intra bit-stream */ + OPUS_COPY(intra_bits, intra_buf, nintra_bytes - nstart_bytes); + + *enc = enc_start_state; + + badness2 = quant_coarse_energy_impl(m, start, end, eBands, oldEBands, budget, + tell, e_prob_model[LM][intra], error, enc, C, LM, 0, max_decay, lfe); + + if (two_pass && (badness1 < badness2 || (badness1 == badness2 && ((opus_int32)ec_tell_frac(enc))+intra_bias > tell_intra))) + { + *enc = enc_intra_state; + /* Copy intra bits to bit-stream */ + OPUS_COPY(intra_buf, intra_bits, nintra_bytes - nstart_bytes); + OPUS_COPY(oldEBands, oldEBands_intra, C*m->nbEBands); + OPUS_COPY(error, error_intra, C*m->nbEBands); + intra = 1; + } + } else { + OPUS_COPY(oldEBands, oldEBands_intra, C*m->nbEBands); + OPUS_COPY(error, error_intra, C*m->nbEBands); + } + + if (intra) + *delayedIntra = new_distortion; + else + *delayedIntra = ADD32(MULT16_32_Q15(MULT16_16_Q15(pred_coef[LM], pred_coef[LM]),*delayedIntra), + new_distortion); + + RESTORE_STACK; +} + +void quant_fine_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, opus_val16 *error, int *fine_quant, ec_enc *enc, int C) +{ + int i, c; + + /* Encode finer resolution */ + for (i=start;inbEBands]+QCONST16(.5f,DB_SHIFT))>>(DB_SHIFT-fine_quant[i]); +#else + q2 = (int)floor((error[i+c*m->nbEBands]+.5f)*frac); +#endif + if (q2 > frac-1) + q2 = frac-1; + if (q2<0) + q2 = 0; + ec_enc_bits(enc, q2, fine_quant[i]); +#ifdef FIXED_POINT + offset = SUB16(SHR32(SHL32(EXTEND32(q2),DB_SHIFT)+QCONST16(.5f,DB_SHIFT),fine_quant[i]),QCONST16(.5f,DB_SHIFT)); +#else + offset = (q2+.5f)*(1<<(14-fine_quant[i]))*(1.f/16384) - .5f; +#endif + oldEBands[i+c*m->nbEBands] += offset; + error[i+c*m->nbEBands] -= offset; + /*printf ("%f ", error[i] - offset);*/ + } while (++c < C); + } +} + +void quant_energy_finalise(const CELTMode *m, int start, int end, opus_val16 *oldEBands, opus_val16 *error, int *fine_quant, int *fine_priority, int bits_left, ec_enc *enc, int C) +{ + int i, prio, c; + + /* Use up the remaining bits */ + for (prio=0;prio<2;prio++) + { + for (i=start;i=C ;i++) + { + if (fine_quant[i] >= MAX_FINE_BITS || fine_priority[i]!=prio) + continue; + c=0; + do { + int q2; + opus_val16 offset; + q2 = error[i+c*m->nbEBands]<0 ? 0 : 1; + ec_enc_bits(enc, q2, 1); +#ifdef FIXED_POINT + offset = SHR16(SHL16(q2,DB_SHIFT)-QCONST16(.5f,DB_SHIFT),fine_quant[i]+1); +#else + offset = (q2-.5f)*(1<<(14-fine_quant[i]-1))*(1.f/16384); +#endif + oldEBands[i+c*m->nbEBands] += offset; + bits_left--; + } while (++c < C); + } + } +} + +void unquant_coarse_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int intra, ec_dec *dec, int C, int LM) +{ + const unsigned char *prob_model = e_prob_model[LM][intra]; + int i, c; + opus_val32 prev[2] = {0, 0}; + opus_val16 coef; + opus_val16 beta; + opus_int32 budget; + opus_int32 tell; + + if (intra) + { + coef = 0; + beta = beta_intra; + } else { + beta = beta_coef[LM]; + coef = pred_coef[LM]; + } + + budget = dec->storage*8; + + /* Decode at a fixed coarse resolution */ + for (i=start;i=15) + { + int pi; + pi = 2*IMIN(i,20); + qi = ec_laplace_decode(dec, + prob_model[pi]<<7, prob_model[pi+1]<<6); + } + else if(budget-tell>=2) + { + qi = ec_dec_icdf(dec, small_energy_icdf, 2); + qi = (qi>>1)^-(qi&1); + } + else if(budget-tell>=1) + { + qi = -ec_dec_bit_logp(dec, 1); + } + else + qi = -1; + q = (opus_val32)SHL32(EXTEND32(qi),DB_SHIFT); + + oldEBands[i+c*m->nbEBands] = MAX16(-QCONST16(9.f,DB_SHIFT), oldEBands[i+c*m->nbEBands]); + tmp = PSHR32(MULT16_16(coef,oldEBands[i+c*m->nbEBands]),8) + prev[c] + SHL32(q,7); +#ifdef FIXED_POINT + tmp = MAX32(-QCONST32(28.f, DB_SHIFT+7), tmp); +#endif + oldEBands[i+c*m->nbEBands] = PSHR32(tmp, 7); + prev[c] = prev[c] + SHL32(q,7) - MULT16_16(beta,PSHR32(q,8)); + } while (++c < C); + } +} + +void unquant_fine_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int *fine_quant, ec_dec *dec, int C) +{ + int i, c; + /* Decode finer resolution */ + for (i=start;inbEBands] += offset; + } while (++c < C); + } +} + +void unquant_energy_finalise(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int *fine_quant, int *fine_priority, int bits_left, ec_dec *dec, int C) +{ + int i, prio, c; + + /* Use up the remaining bits */ + for (prio=0;prio<2;prio++) + { + for (i=start;i=C ;i++) + { + if (fine_quant[i] >= MAX_FINE_BITS || fine_priority[i]!=prio) + continue; + c=0; + do { + int q2; + opus_val16 offset; + q2 = ec_dec_bits(dec, 1); +#ifdef FIXED_POINT + offset = SHR16(SHL16(q2,DB_SHIFT)-QCONST16(.5f,DB_SHIFT),fine_quant[i]+1); +#else + offset = (q2-.5f)*(1<<(14-fine_quant[i]-1))*(1.f/16384); +#endif + oldEBands[i+c*m->nbEBands] += offset; + bits_left--; + } while (++c < C); + } + } +} + +void amp2Log2(const CELTMode *m, int effEnd, int end, + celt_ener *bandE, opus_val16 *bandLogE, int C) +{ + int c, i; + c=0; + do { + for (i=0;inbEBands] = + celt_log2(SHL32(bandE[i+c*m->nbEBands],2)) + - SHL16((opus_val16)eMeans[i],6); + for (i=effEnd;inbEBands+i] = -QCONST16(14.f,DB_SHIFT); + } while (++c < C); +} diff --git a/src/opus-1.1/celt/quant_bands.h b/src/opus-1.1/celt/quant_bands.h new file mode 100644 index 00000000..0490bca4 --- /dev/null +++ b/src/opus-1.1/celt/quant_bands.h @@ -0,0 +1,66 @@ +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation + Written by Jean-Marc Valin */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef QUANT_BANDS +#define QUANT_BANDS + +#include "arch.h" +#include "modes.h" +#include "entenc.h" +#include "entdec.h" +#include "mathops.h" + +#ifdef FIXED_POINT +extern const signed char eMeans[25]; +#else +extern const opus_val16 eMeans[25]; +#endif + +void amp2Log2(const CELTMode *m, int effEnd, int end, + celt_ener *bandE, opus_val16 *bandLogE, int C); + +void log2Amp(const CELTMode *m, int start, int end, + celt_ener *eBands, const opus_val16 *oldEBands, int C); + +void quant_coarse_energy(const CELTMode *m, int start, int end, int effEnd, + const opus_val16 *eBands, opus_val16 *oldEBands, opus_uint32 budget, + opus_val16 *error, ec_enc *enc, int C, int LM, + int nbAvailableBytes, int force_intra, opus_val32 *delayedIntra, + int two_pass, int loss_rate, int lfe); + +void quant_fine_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, opus_val16 *error, int *fine_quant, ec_enc *enc, int C); + +void quant_energy_finalise(const CELTMode *m, int start, int end, opus_val16 *oldEBands, opus_val16 *error, int *fine_quant, int *fine_priority, int bits_left, ec_enc *enc, int C); + +void unquant_coarse_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int intra, ec_dec *dec, int C, int LM); + +void unquant_fine_energy(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int *fine_quant, ec_dec *dec, int C); + +void unquant_energy_finalise(const CELTMode *m, int start, int end, opus_val16 *oldEBands, int *fine_quant, int *fine_priority, int bits_left, ec_dec *dec, int C); + +#endif /* QUANT_BANDS */ diff --git a/src/opus-1.1/celt/rate.c b/src/opus-1.1/celt/rate.c new file mode 100644 index 00000000..e13d839d --- /dev/null +++ b/src/opus-1.1/celt/rate.c @@ -0,0 +1,638 @@ +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation + Written by Jean-Marc Valin */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "modes.h" +#include "cwrs.h" +#include "arch.h" +#include "os_support.h" + +#include "entcode.h" +#include "rate.h" + +static const unsigned char LOG2_FRAC_TABLE[24]={ + 0, + 8,13, + 16,19,21,23, + 24,26,27,28,29,30,31,32, + 32,33,34,34,35,36,36,37,37 +}; + +#ifdef CUSTOM_MODES + +/*Determines if V(N,K) fits in a 32-bit unsigned integer. + N and K are themselves limited to 15 bits.*/ +static int fits_in32(int _n, int _k) +{ + static const opus_int16 maxN[15] = { + 32767, 32767, 32767, 1476, 283, 109, 60, 40, + 29, 24, 20, 18, 16, 14, 13}; + static const opus_int16 maxK[15] = { + 32767, 32767, 32767, 32767, 1172, 238, 95, 53, + 36, 27, 22, 18, 16, 15, 13}; + if (_n>=14) + { + if (_k>=14) + return 0; + else + return _n <= maxN[_k]; + } else { + return _k <= maxK[_n]; + } +} + +void compute_pulse_cache(CELTMode *m, int LM) +{ + int C; + int i; + int j; + int curr=0; + int nbEntries=0; + int entryN[100], entryK[100], entryI[100]; + const opus_int16 *eBands = m->eBands; + PulseCache *cache = &m->cache; + opus_int16 *cindex; + unsigned char *bits; + unsigned char *cap; + + cindex = (opus_int16 *)opus_alloc(sizeof(cache->index[0])*m->nbEBands*(LM+2)); + cache->index = cindex; + + /* Scan for all unique band sizes */ + for (i=0;i<=LM+1;i++) + { + for (j=0;jnbEBands;j++) + { + int k; + int N = (eBands[j+1]-eBands[j])<>1; + cindex[i*m->nbEBands+j] = -1; + /* Find other bands that have the same size */ + for (k=0;k<=i;k++) + { + int n; + for (n=0;nnbEBands && (k!=i || n>1) + { + cindex[i*m->nbEBands+j] = cindex[k*m->nbEBands+n]; + break; + } + } + } + if (cache->index[i*m->nbEBands+j] == -1 && N!=0) + { + int K; + entryN[nbEntries] = N; + K = 0; + while (fits_in32(N,get_pulses(K+1)) && KnbEBands+j] = curr; + entryI[nbEntries] = curr; + + curr += K+1; + nbEntries++; + } + } + } + bits = (unsigned char *)opus_alloc(sizeof(unsigned char)*curr); + cache->bits = bits; + cache->size = curr; + /* Compute the cache for all unique sizes */ + for (i=0;icaps = cap = (unsigned char *)opus_alloc(sizeof(cache->caps[0])*(LM+1)*2*m->nbEBands); + for (i=0;i<=LM;i++) + { + for (C=1;C<=2;C++) + { + for (j=0;jnbEBands;j++) + { + int N0; + int max_bits; + N0 = m->eBands[j+1]-m->eBands[j]; + /* N=1 bands only have a sign bit and fine bits. */ + if (N0<1 are even, including custom modes.*/ + if (N0 > 2) + { + N0>>=1; + LM0--; + } + /* N0=1 bands can't be split down to N<2. */ + else if (N0 <= 1) + { + LM0=IMIN(i,1); + N0<<=LM0; + } + /* Compute the cost for the lowest-level PVQ of a fully split + band. */ + pcache = bits + cindex[(LM0+1)*m->nbEBands+j]; + max_bits = pcache[pcache[0]]+1; + /* Add in the cost of coding regular splits. */ + N = N0; + for(k=0;klogN[j]+((LM0+k)<>1)-QTHETA_OFFSET; + /* The number of qtheta bits we'll allocate if the remainder + is to be max_bits. + The average measured cost for theta is 0.89701 times qb, + approximated here as 459/512. */ + num=459*(opus_int32)((2*N-1)*offset+max_bits); + den=((opus_int32)(2*N-1)<<9)-459; + qb = IMIN((num+(den>>1))/den, 57); + celt_assert(qb >= 0); + max_bits += qb; + N <<= 1; + } + /* Add in the cost of a stereo split, if necessary. */ + if (C==2) + { + max_bits <<= 1; + offset = ((m->logN[j]+(i<>1)-(N==2?QTHETA_OFFSET_TWOPHASE:QTHETA_OFFSET); + ndof = 2*N-1-(N==2); + /* The average measured cost for theta with the step PDF is + 0.95164 times qb, approximated here as 487/512. */ + num = (N==2?512:487)*(opus_int32)(max_bits+ndof*offset); + den = ((opus_int32)ndof<<9)-(N==2?512:487); + qb = IMIN((num+(den>>1))/den, (N==2?64:61)); + celt_assert(qb >= 0); + max_bits += qb; + } + /* Add the fine bits we'll use. */ + /* Compensate for the extra DoF in stereo */ + ndof = C*N + ((C==2 && N>2) ? 1 : 0); + /* Offset the number of fine bits by log2(N)/2 + FINE_OFFSET + compared to their "fair share" of total/N */ + offset = ((m->logN[j] + (i<>1)-FINE_OFFSET; + /* N=2 is the only point that doesn't match the curve */ + if (N==2) + offset += 1<>2; + /* The number of fine bits we'll allocate if the remainder is + to be max_bits. */ + num = max_bits+ndof*offset; + den = (ndof-1)<>1))/den, MAX_FINE_BITS); + celt_assert(qb >= 0); + max_bits += C*qb<eBands[j+1]-m->eBands[j])<= 0); + celt_assert(max_bits < 256); + *cap++ = (unsigned char)max_bits; + } + } + } +} + +#endif /* CUSTOM_MODES */ + +#define ALLOC_STEPS 6 + +static OPUS_INLINE int interp_bits2pulses(const CELTMode *m, int start, int end, int skip_start, + const int *bits1, const int *bits2, const int *thresh, const int *cap, opus_int32 total, opus_int32 *_balance, + int skip_rsv, int *intensity, int intensity_rsv, int *dual_stereo, int dual_stereo_rsv, int *bits, + int *ebits, int *fine_priority, int C, int LM, ec_ctx *ec, int encode, int prev, int signalBandwidth) +{ + opus_int32 psum; + int lo, hi; + int i, j; + int logM; + int stereo; + int codedBands=-1; + int alloc_floor; + opus_int32 left, percoeff; + int done; + opus_int32 balance; + SAVE_STACK; + + alloc_floor = C<1; + + logM = LM<>1; + psum = 0; + done = 0; + for (j=end;j-->start;) + { + int tmp = bits1[j] + (mid*(opus_int32)bits2[j]>>ALLOC_STEPS); + if (tmp >= thresh[j] || done) + { + done = 1; + /* Don't allocate more than we can actually use */ + psum += IMIN(tmp, cap[j]); + } else { + if (tmp >= alloc_floor) + psum += alloc_floor; + } + } + if (psum > total) + hi = mid; + else + lo = mid; + } + psum = 0; + /*printf ("interp bisection gave %d\n", lo);*/ + done = 0; + for (j=end;j-->start;) + { + int tmp = bits1[j] + (lo*bits2[j]>>ALLOC_STEPS); + if (tmp < thresh[j] && !done) + { + if (tmp >= alloc_floor) + tmp = alloc_floor; + else + tmp = 0; + } else + done = 1; + /* Don't allocate more than we can actually use */ + tmp = IMIN(tmp, cap[j]); + bits[j] = tmp; + psum += tmp; + } + + /* Decide which bands to skip, working backwards from the end. */ + for (codedBands=end;;codedBands--) + { + int band_width; + int band_bits; + int rem; + j = codedBands-1; + /* Never skip the first band, nor a band that has been boosted by + dynalloc. + In the first case, we'd be coding a bit to signal we're going to waste + all the other bits. + In the second case, we'd be coding a bit to redistribute all the bits + we just signaled should be cocentrated in this band. */ + if (j<=skip_start) + { + /* Give the bit we reserved to end skipping back. */ + total += skip_rsv; + break; + } + /*Figure out how many left-over bits we would be adding to this band. + This can include bits we've stolen back from higher, skipped bands.*/ + left = total-psum; + percoeff = left/(m->eBands[codedBands]-m->eBands[start]); + left -= (m->eBands[codedBands]-m->eBands[start])*percoeff; + rem = IMAX(left-(m->eBands[j]-m->eBands[start]),0); + band_width = m->eBands[codedBands]-m->eBands[j]; + band_bits = (int)(bits[j] + percoeff*band_width + rem); + /*Only code a skip decision if we're above the threshold for this band. + Otherwise it is force-skipped. + This ensures that we have enough bits to code the skip flag.*/ + if (band_bits >= IMAX(thresh[j], alloc_floor+(1< ((j>4 && j<=signalBandwidth)) +#endif + { + ec_enc_bit_logp(ec, 1, 1); + break; + } + ec_enc_bit_logp(ec, 0, 1); + } else if (ec_dec_bit_logp(ec, 1)) { + break; + } + /*We used a bit to skip this band.*/ + psum += 1< 0) + intensity_rsv = LOG2_FRAC_TABLE[j-start]; + psum += intensity_rsv; + if (band_bits >= alloc_floor) + { + /*If we have enough for a fine energy bit per channel, use it.*/ + psum += alloc_floor; + bits[j] = alloc_floor; + } else { + /*Otherwise this band gets nothing at all.*/ + bits[j] = 0; + } + } + + celt_assert(codedBands > start); + /* Code the intensity and dual stereo parameters. */ + if (intensity_rsv > 0) + { + if (encode) + { + *intensity = IMIN(*intensity, codedBands); + ec_enc_uint(ec, *intensity-start, codedBands+1-start); + } + else + *intensity = start+ec_dec_uint(ec, codedBands+1-start); + } + else + *intensity = 0; + if (*intensity <= start) + { + total += dual_stereo_rsv; + dual_stereo_rsv = 0; + } + if (dual_stereo_rsv > 0) + { + if (encode) + ec_enc_bit_logp(ec, *dual_stereo, 1); + else + *dual_stereo = ec_dec_bit_logp(ec, 1); + } + else + *dual_stereo = 0; + + /* Allocate the remaining bits */ + left = total-psum; + percoeff = left/(m->eBands[codedBands]-m->eBands[start]); + left -= (m->eBands[codedBands]-m->eBands[start])*percoeff; + for (j=start;jeBands[j+1]-m->eBands[j])); + for (j=start;jeBands[j+1]-m->eBands[j]); + bits[j] += tmp; + left -= tmp; + } + /*for (j=0;j= 0); + N0 = m->eBands[j+1]-m->eBands[j]; + N=N0<1) + { + excess = MAX32(bit-cap[j],0); + bits[j] = bit-excess; + + /* Compensate for the extra DoF in stereo */ + den=(C*N+ ((C==2 && N>2 && !*dual_stereo && j<*intensity) ? 1 : 0)); + + NClogN = den*(m->logN[j] + logM); + + /* Offset for the number of fine bits by log2(N)/2 + FINE_OFFSET + compared to their "fair share" of total/N */ + offset = (NClogN>>1)-den*FINE_OFFSET; + + /* N=2 is the only point that doesn't match the curve */ + if (N==2) + offset += den<>2; + + /* Changing the offset for allocating the second and third + fine energy bit */ + if (bits[j] + offset < den*2<>2; + else if (bits[j] + offset < den*3<>3; + + /* Divide with rounding */ + ebits[j] = IMAX(0, (bits[j] + offset + (den<<(BITRES-1))) / (den< (bits[j]>>BITRES)) + ebits[j] = bits[j] >> stereo >> BITRES; + + /* More than that is useless because that's about as far as PVQ can go */ + ebits[j] = IMIN(ebits[j], MAX_FINE_BITS); + + /* If we rounded down or capped this band, make it a candidate for the + final fine energy pass */ + fine_priority[j] = ebits[j]*(den<= bits[j]+offset; + + /* Remove the allocated fine bits; the rest are assigned to PVQ */ + bits[j] -= C*ebits[j]< 0) + { + int extra_fine; + int extra_bits; + extra_fine = IMIN(excess>>(stereo+BITRES),MAX_FINE_BITS-ebits[j]); + ebits[j] += extra_fine; + extra_bits = extra_fine*C<= excess-balance; + excess -= extra_bits; + } + balance = excess; + + celt_assert(bits[j] >= 0); + celt_assert(ebits[j] >= 0); + } + /* Save any remaining bits over the cap for the rebalancing in + quant_all_bands(). */ + *_balance = balance; + + /* The skipped bands use all their bits for fine energy. */ + for (;j> stereo >> BITRES; + celt_assert(C*ebits[j]<nbEBands; + skip_start = start; + /* Reserve a bit to signal the end of manually skipped bands. */ + skip_rsv = total >= 1<total) + intensity_rsv = 0; + else + { + total -= intensity_rsv; + dual_stereo_rsv = total>=1<eBands[j+1]-m->eBands[j])<>4); + /* Tilt of the allocation curve */ + trim_offset[j] = C*(m->eBands[j+1]-m->eBands[j])*(alloc_trim-5-LM)*(end-j-1) + *(1<<(LM+BITRES))>>6; + /* Giving less resolution to single-coefficient bands because they get + more benefit from having one coarse value per coefficient*/ + if ((m->eBands[j+1]-m->eBands[j])<nbAllocVectors - 1; + do + { + int done = 0; + int psum = 0; + int mid = (lo+hi) >> 1; + for (j=end;j-->start;) + { + int bitsj; + int N = m->eBands[j+1]-m->eBands[j]; + bitsj = C*N*m->allocVectors[mid*len+j]<>2; + if (bitsj > 0) + bitsj = IMAX(0, bitsj + trim_offset[j]); + bitsj += offsets[j]; + if (bitsj >= thresh[j] || done) + { + done = 1; + /* Don't allocate more than we can actually use */ + psum += IMIN(bitsj, cap[j]); + } else { + if (bitsj >= C< total) + hi = mid - 1; + else + lo = mid + 1; + /*printf ("lo = %d, hi = %d\n", lo, hi);*/ + } + while (lo <= hi); + hi = lo--; + /*printf ("interp between %d and %d\n", lo, hi);*/ + for (j=start;jeBands[j+1]-m->eBands[j]; + bits1j = C*N*m->allocVectors[lo*len+j]<>2; + bits2j = hi>=m->nbAllocVectors ? + cap[j] : C*N*m->allocVectors[hi*len+j]<>2; + if (bits1j > 0) + bits1j = IMAX(0, bits1j + trim_offset[j]); + if (bits2j > 0) + bits2j = IMAX(0, bits2j + trim_offset[j]); + if (lo > 0) + bits1j += offsets[j]; + bits2j += offsets[j]; + if (offsets[j]>0) + skip_start = j; + bits2j = IMAX(0,bits2j-bits1j); + bits1[j] = bits1j; + bits2[j] = bits2j; + } + codedBands = interp_bits2pulses(m, start, end, skip_start, bits1, bits2, thresh, cap, + total, balance, skip_rsv, intensity, intensity_rsv, dual_stereo, dual_stereo_rsv, + pulses, ebits, fine_priority, C, LM, ec, encode, prev, signalBandwidth); + RESTORE_STACK; + return codedBands; +} + diff --git a/src/opus-1.1/celt/rate.h b/src/opus-1.1/celt/rate.h new file mode 100644 index 00000000..f1e06611 --- /dev/null +++ b/src/opus-1.1/celt/rate.h @@ -0,0 +1,101 @@ +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation + Written by Jean-Marc Valin */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef RATE_H +#define RATE_H + +#define MAX_PSEUDO 40 +#define LOG_MAX_PSEUDO 6 + +#define MAX_PULSES 128 + +#define MAX_FINE_BITS 8 + +#define FINE_OFFSET 21 +#define QTHETA_OFFSET 4 +#define QTHETA_OFFSET_TWOPHASE 16 + +#include "cwrs.h" +#include "modes.h" + +void compute_pulse_cache(CELTMode *m, int LM); + +static OPUS_INLINE int get_pulses(int i) +{ + return i<8 ? i : (8 + (i&7)) << ((i>>3)-1); +} + +static OPUS_INLINE int bits2pulses(const CELTMode *m, int band, int LM, int bits) +{ + int i; + int lo, hi; + const unsigned char *cache; + + LM++; + cache = m->cache.bits + m->cache.index[LM*m->nbEBands+band]; + + lo = 0; + hi = cache[0]; + bits--; + for (i=0;i>1; + /* OPT: Make sure this is implemented with a conditional move */ + if ((int)cache[mid] >= bits) + hi = mid; + else + lo = mid; + } + if (bits- (lo == 0 ? -1 : (int)cache[lo]) <= (int)cache[hi]-bits) + return lo; + else + return hi; +} + +static OPUS_INLINE int pulses2bits(const CELTMode *m, int band, int LM, int pulses) +{ + const unsigned char *cache; + + LM++; + cache = m->cache.bits + m->cache.index[LM*m->nbEBands+band]; + return pulses == 0 ? 0 : cache[pulses]+1; +} + +/** Compute the pulse allocation, i.e. how many pulses will go in each + * band. + @param m mode + @param offsets Requested increase or decrease in the number of bits for + each band + @param total Number of bands + @param pulses Number of pulses per band (returned) + @return Total number of bits allocated +*/ +int compute_allocation(const CELTMode *m, int start, int end, const int *offsets, const int *cap, int alloc_trim, int *intensity, int *dual_stero, + opus_int32 total, opus_int32 *balance, int *pulses, int *ebits, int *fine_priority, int C, int LM, ec_ctx *ec, int encode, int prev, int signalBandwidth); + +#endif diff --git a/src/opus-1.1/celt/stack_alloc.h b/src/opus-1.1/celt/stack_alloc.h new file mode 100644 index 00000000..316a6ce1 --- /dev/null +++ b/src/opus-1.1/celt/stack_alloc.h @@ -0,0 +1,178 @@ +/* Copyright (C) 2002-2003 Jean-Marc Valin + Copyright (C) 2007-2009 Xiph.Org Foundation */ +/** + @file stack_alloc.h + @brief Temporary memory allocation on stack +*/ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef STACK_ALLOC_H +#define STACK_ALLOC_H + +#include "opus_types.h" +#include "opus_defines.h" + +#if (!defined (VAR_ARRAYS) && !defined (USE_ALLOCA) && !defined (NONTHREADSAFE_PSEUDOSTACK)) +#error "Opus requires one of VAR_ARRAYS, USE_ALLOCA, or NONTHREADSAFE_PSEUDOSTACK be defined to select the temporary allocation mode." +#endif + +#ifdef USE_ALLOCA +# ifdef WIN32 +# include +# else +# ifdef HAVE_ALLOCA_H +# include +# else +# include +# endif +# endif +#endif + +/** + * @def ALIGN(stack, size) + * + * Aligns the stack to a 'size' boundary + * + * @param stack Stack + * @param size New size boundary + */ + +/** + * @def PUSH(stack, size, type) + * + * Allocates 'size' elements of type 'type' on the stack + * + * @param stack Stack + * @param size Number of elements + * @param type Type of element + */ + +/** + * @def VARDECL(var) + * + * Declare variable on stack + * + * @param var Variable to declare + */ + +/** + * @def ALLOC(var, size, type) + * + * Allocate 'size' elements of 'type' on stack + * + * @param var Name of variable to allocate + * @param size Number of elements + * @param type Type of element + */ + +#if defined(VAR_ARRAYS) + +#define VARDECL(type, var) +#define ALLOC(var, size, type) type var[size] +#define SAVE_STACK +#define RESTORE_STACK +#define ALLOC_STACK +/* C99 does not allow VLAs of size zero */ +#define ALLOC_NONE 1 + +#elif defined(USE_ALLOCA) + +#define VARDECL(type, var) type *var + +# ifdef WIN32 +# define ALLOC(var, size, type) var = ((type*)_alloca(sizeof(type)*(size))) +# else +# define ALLOC(var, size, type) var = ((type*)alloca(sizeof(type)*(size))) +# endif + +#define SAVE_STACK +#define RESTORE_STACK +#define ALLOC_STACK +#define ALLOC_NONE 0 + +#else + +#ifdef CELT_C +char *global_stack=0; +#else +extern char *global_stack; +#endif /* CELT_C */ + +#ifdef ENABLE_VALGRIND + +#include + +#ifdef CELT_C +char *global_stack_top=0; +#else +extern char *global_stack_top; +#endif /* CELT_C */ + +#define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1)) +#define PUSH(stack, size, type) (VALGRIND_MAKE_MEM_NOACCESS(stack, global_stack_top-stack),ALIGN((stack),sizeof(type)/sizeof(char)),VALGRIND_MAKE_MEM_UNDEFINED(stack, ((size)*sizeof(type)/sizeof(char))),(stack)+=(2*(size)*sizeof(type)/sizeof(char)),(type*)((stack)-(2*(size)*sizeof(type)/sizeof(char)))) +#define RESTORE_STACK ((global_stack = _saved_stack),VALGRIND_MAKE_MEM_NOACCESS(global_stack, global_stack_top-global_stack)) +#define ALLOC_STACK char *_saved_stack; ((global_stack = (global_stack==0) ? ((global_stack_top=opus_alloc_scratch(GLOBAL_STACK_SIZE*2)+(GLOBAL_STACK_SIZE*2))-(GLOBAL_STACK_SIZE*2)) : global_stack),VALGRIND_MAKE_MEM_NOACCESS(global_stack, global_stack_top-global_stack)); _saved_stack = global_stack; + +#else + +#define ALIGN(stack, size) ((stack) += ((size) - (long)(stack)) & ((size) - 1)) +#define PUSH(stack, size, type) (ALIGN((stack),sizeof(type)/sizeof(char)),(stack)+=(size)*(sizeof(type)/sizeof(char)),(type*)((stack)-(size)*(sizeof(type)/sizeof(char)))) +#define RESTORE_STACK (global_stack = _saved_stack) +#define ALLOC_STACK char *_saved_stack; (global_stack = (global_stack==0) ? opus_alloc_scratch(GLOBAL_STACK_SIZE) : global_stack); _saved_stack = global_stack; + +#endif /* ENABLE_VALGRIND */ + +#include "os_support.h" +#define VARDECL(type, var) type *var +#define ALLOC(var, size, type) var = PUSH(global_stack, size, type) +#define SAVE_STACK char *_saved_stack = global_stack; +#define ALLOC_NONE 0 + +#endif /* VAR_ARRAYS */ + + +#ifdef ENABLE_VALGRIND + +#include +#define OPUS_CHECK_ARRAY(ptr, len) VALGRIND_CHECK_MEM_IS_DEFINED(ptr, len*sizeof(*ptr)) +#define OPUS_CHECK_VALUE(value) VALGRIND_CHECK_VALUE_IS_DEFINED(value) +#define OPUS_CHECK_ARRAY_COND(ptr, len) VALGRIND_CHECK_MEM_IS_DEFINED(ptr, len*sizeof(*ptr)) +#define OPUS_CHECK_VALUE_COND(value) VALGRIND_CHECK_VALUE_IS_DEFINED(value) +#define OPUS_PRINT_INT(value) do {fprintf(stderr, #value " = %d at %s:%d\n", value, __FILE__, __LINE__);}while(0) +#define OPUS_FPRINTF fprintf + +#else + +static OPUS_INLINE int _opus_false(void) {return 0;} +#define OPUS_CHECK_ARRAY(ptr, len) _opus_false() +#define OPUS_CHECK_VALUE(value) _opus_false() +#define OPUS_PRINT_INT(value) do{}while(0) +#define OPUS_FPRINTF (void) + +#endif + + +#endif /* STACK_ALLOC_H */ diff --git a/src/opus-1.1/celt/static_modes_fixed.h b/src/opus-1.1/celt/static_modes_fixed.h new file mode 100644 index 00000000..216df9e6 --- /dev/null +++ b/src/opus-1.1/celt/static_modes_fixed.h @@ -0,0 +1,595 @@ +/* The contents of this file was automatically generated by dump_modes.c + with arguments: 48000 960 + It contains static definitions for some pre-defined modes. */ +#include "modes.h" +#include "rate.h" + +#ifndef DEF_WINDOW120 +#define DEF_WINDOW120 +static const opus_val16 window120[120] = { +2, 20, 55, 108, 178, +266, 372, 494, 635, 792, +966, 1157, 1365, 1590, 1831, +2089, 2362, 2651, 2956, 3276, +3611, 3961, 4325, 4703, 5094, +5499, 5916, 6346, 6788, 7241, +7705, 8179, 8663, 9156, 9657, +10167, 10684, 11207, 11736, 12271, +12810, 13353, 13899, 14447, 14997, +15547, 16098, 16648, 17197, 17744, +18287, 18827, 19363, 19893, 20418, +20936, 21447, 21950, 22445, 22931, +23407, 23874, 24330, 24774, 25208, +25629, 26039, 26435, 26819, 27190, +27548, 27893, 28224, 28541, 28845, +29135, 29411, 29674, 29924, 30160, +30384, 30594, 30792, 30977, 31151, +31313, 31463, 31602, 31731, 31849, +31958, 32057, 32148, 32229, 32303, +32370, 32429, 32481, 32528, 32568, +32604, 32634, 32661, 32683, 32701, +32717, 32729, 32740, 32748, 32754, +32758, 32762, 32764, 32766, 32767, +32767, 32767, 32767, 32767, 32767, +}; +#endif + +#ifndef DEF_LOGN400 +#define DEF_LOGN400 +static const opus_int16 logN400[21] = { +0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 16, 16, 16, 21, 21, 24, 29, 34, 36, }; +#endif + +#ifndef DEF_PULSE_CACHE50 +#define DEF_PULSE_CACHE50 +static const opus_int16 cache_index50[105] = { +-1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 41, 41, 41, +82, 82, 123, 164, 200, 222, 0, 0, 0, 0, 0, 0, 0, 0, 41, +41, 41, 41, 123, 123, 123, 164, 164, 240, 266, 283, 295, 41, 41, 41, +41, 41, 41, 41, 41, 123, 123, 123, 123, 240, 240, 240, 266, 266, 305, +318, 328, 336, 123, 123, 123, 123, 123, 123, 123, 123, 240, 240, 240, 240, +305, 305, 305, 318, 318, 343, 351, 358, 364, 240, 240, 240, 240, 240, 240, +240, 240, 305, 305, 305, 305, 343, 343, 343, 351, 351, 370, 376, 382, 387, +}; +static const unsigned char cache_bits50[392] = { +40, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, +7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, +7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 40, 15, 23, 28, +31, 34, 36, 38, 39, 41, 42, 43, 44, 45, 46, 47, 47, 49, 50, +51, 52, 53, 54, 55, 55, 57, 58, 59, 60, 61, 62, 63, 63, 65, +66, 67, 68, 69, 70, 71, 71, 40, 20, 33, 41, 48, 53, 57, 61, +64, 66, 69, 71, 73, 75, 76, 78, 80, 82, 85, 87, 89, 91, 92, +94, 96, 98, 101, 103, 105, 107, 108, 110, 112, 114, 117, 119, 121, 123, +124, 126, 128, 40, 23, 39, 51, 60, 67, 73, 79, 83, 87, 91, 94, +97, 100, 102, 105, 107, 111, 115, 118, 121, 124, 126, 129, 131, 135, 139, +142, 145, 148, 150, 153, 155, 159, 163, 166, 169, 172, 174, 177, 179, 35, +28, 49, 65, 78, 89, 99, 107, 114, 120, 126, 132, 136, 141, 145, 149, +153, 159, 165, 171, 176, 180, 185, 189, 192, 199, 205, 211, 216, 220, 225, +229, 232, 239, 245, 251, 21, 33, 58, 79, 97, 112, 125, 137, 148, 157, +166, 174, 182, 189, 195, 201, 207, 217, 227, 235, 243, 251, 17, 35, 63, +86, 106, 123, 139, 152, 165, 177, 187, 197, 206, 214, 222, 230, 237, 250, +25, 31, 55, 75, 91, 105, 117, 128, 138, 146, 154, 161, 168, 174, 180, +185, 190, 200, 208, 215, 222, 229, 235, 240, 245, 255, 16, 36, 65, 89, +110, 128, 144, 159, 173, 185, 196, 207, 217, 226, 234, 242, 250, 11, 41, +74, 103, 128, 151, 172, 191, 209, 225, 241, 255, 9, 43, 79, 110, 138, +163, 186, 207, 227, 246, 12, 39, 71, 99, 123, 144, 164, 182, 198, 214, +228, 241, 253, 9, 44, 81, 113, 142, 168, 192, 214, 235, 255, 7, 49, +90, 127, 160, 191, 220, 247, 6, 51, 95, 134, 170, 203, 234, 7, 47, +87, 123, 155, 184, 212, 237, 6, 52, 97, 137, 174, 208, 240, 5, 57, +106, 151, 192, 231, 5, 59, 111, 158, 202, 243, 5, 55, 103, 147, 187, +224, 5, 60, 113, 161, 206, 248, 4, 65, 122, 175, 224, 4, 67, 127, +182, 234, }; +static const unsigned char cache_caps50[168] = { +224, 224, 224, 224, 224, 224, 224, 224, 160, 160, 160, 160, 185, 185, 185, +178, 178, 168, 134, 61, 37, 224, 224, 224, 224, 224, 224, 224, 224, 240, +240, 240, 240, 207, 207, 207, 198, 198, 183, 144, 66, 40, 160, 160, 160, +160, 160, 160, 160, 160, 185, 185, 185, 185, 193, 193, 193, 183, 183, 172, +138, 64, 38, 240, 240, 240, 240, 240, 240, 240, 240, 207, 207, 207, 207, +204, 204, 204, 193, 193, 180, 143, 66, 40, 185, 185, 185, 185, 185, 185, +185, 185, 193, 193, 193, 193, 193, 193, 193, 183, 183, 172, 138, 65, 39, +207, 207, 207, 207, 207, 207, 207, 207, 204, 204, 204, 204, 201, 201, 201, +188, 188, 176, 141, 66, 40, 193, 193, 193, 193, 193, 193, 193, 193, 193, +193, 193, 193, 194, 194, 194, 184, 184, 173, 139, 65, 39, 204, 204, 204, +204, 204, 204, 204, 204, 201, 201, 201, 201, 198, 198, 198, 187, 187, 175, +140, 66, 40, }; +#endif + +#ifndef FFT_TWIDDLES48000_960 +#define FFT_TWIDDLES48000_960 +static const kiss_twiddle_cpx fft_twiddles48000_960[480] = { +{32767, 0}, {32766, -429}, +{32757, -858}, {32743, -1287}, +{32724, -1715}, {32698, -2143}, +{32667, -2570}, {32631, -2998}, +{32588, -3425}, {32541, -3851}, +{32488, -4277}, {32429, -4701}, +{32364, -5125}, {32295, -5548}, +{32219, -5971}, {32138, -6393}, +{32051, -6813}, {31960, -7231}, +{31863, -7650}, {31760, -8067}, +{31652, -8481}, {31539, -8895}, +{31419, -9306}, {31294, -9716}, +{31165, -10126}, {31030, -10532}, +{30889, -10937}, {30743, -11340}, +{30592, -11741}, {30436, -12141}, +{30274, -12540}, {30107, -12935}, +{29936, -13328}, {29758, -13718}, +{29577, -14107}, {29390, -14493}, +{29197, -14875}, {29000, -15257}, +{28797, -15635}, {28590, -16010}, +{28379, -16384}, {28162, -16753}, +{27940, -17119}, {27714, -17484}, +{27482, -17845}, {27246, -18205}, +{27006, -18560}, {26760, -18911}, +{26510, -19260}, {26257, -19606}, +{25997, -19947}, {25734, -20286}, +{25466, -20621}, {25194, -20952}, +{24918, -21281}, {24637, -21605}, +{24353, -21926}, {24063, -22242}, +{23770, -22555}, {23473, -22865}, +{23171, -23171}, {22866, -23472}, +{22557, -23769}, {22244, -24063}, +{21927, -24352}, {21606, -24636}, +{21282, -24917}, {20954, -25194}, +{20622, -25465}, {20288, -25733}, +{19949, -25997}, {19607, -26255}, +{19261, -26509}, {18914, -26760}, +{18561, -27004}, {18205, -27246}, +{17846, -27481}, {17485, -27713}, +{17122, -27940}, {16755, -28162}, +{16385, -28378}, {16012, -28590}, +{15636, -28797}, {15258, -28999}, +{14878, -29197}, {14494, -29389}, +{14108, -29576}, {13720, -29757}, +{13329, -29934}, {12937, -30107}, +{12540, -30274}, {12142, -30435}, +{11744, -30592}, {11342, -30743}, +{10939, -30889}, {10534, -31030}, +{10127, -31164}, {9718, -31294}, +{9307, -31418}, {8895, -31537}, +{8482, -31652}, {8067, -31759}, +{7650, -31862}, {7233, -31960}, +{6815, -32051}, {6393, -32138}, +{5973, -32219}, {5549, -32294}, +{5127, -32364}, {4703, -32429}, +{4278, -32487}, {3852, -32541}, +{3426, -32588}, {2999, -32630}, +{2572, -32667}, {2144, -32698}, +{1716, -32724}, {1287, -32742}, +{860, -32757}, {430, -32766}, +{0, -32767}, {-429, -32766}, +{-858, -32757}, {-1287, -32743}, +{-1715, -32724}, {-2143, -32698}, +{-2570, -32667}, {-2998, -32631}, +{-3425, -32588}, {-3851, -32541}, +{-4277, -32488}, {-4701, -32429}, +{-5125, -32364}, {-5548, -32295}, +{-5971, -32219}, {-6393, -32138}, +{-6813, -32051}, {-7231, -31960}, +{-7650, -31863}, {-8067, -31760}, +{-8481, -31652}, {-8895, -31539}, +{-9306, -31419}, {-9716, -31294}, +{-10126, -31165}, {-10532, -31030}, +{-10937, -30889}, {-11340, -30743}, +{-11741, -30592}, {-12141, -30436}, +{-12540, -30274}, {-12935, -30107}, +{-13328, -29936}, {-13718, -29758}, +{-14107, -29577}, {-14493, -29390}, +{-14875, -29197}, {-15257, -29000}, +{-15635, -28797}, {-16010, -28590}, +{-16384, -28379}, {-16753, -28162}, +{-17119, -27940}, {-17484, -27714}, +{-17845, -27482}, {-18205, -27246}, +{-18560, -27006}, {-18911, -26760}, +{-19260, -26510}, {-19606, -26257}, +{-19947, -25997}, {-20286, -25734}, +{-20621, -25466}, {-20952, -25194}, +{-21281, -24918}, {-21605, -24637}, +{-21926, -24353}, {-22242, -24063}, +{-22555, -23770}, {-22865, -23473}, +{-23171, -23171}, {-23472, -22866}, +{-23769, -22557}, {-24063, -22244}, +{-24352, -21927}, {-24636, -21606}, +{-24917, -21282}, {-25194, -20954}, +{-25465, -20622}, {-25733, -20288}, +{-25997, -19949}, {-26255, -19607}, +{-26509, -19261}, {-26760, -18914}, +{-27004, -18561}, {-27246, -18205}, +{-27481, -17846}, {-27713, -17485}, +{-27940, -17122}, {-28162, -16755}, +{-28378, -16385}, {-28590, -16012}, +{-28797, -15636}, {-28999, -15258}, +{-29197, -14878}, {-29389, -14494}, +{-29576, -14108}, {-29757, -13720}, +{-29934, -13329}, {-30107, -12937}, +{-30274, -12540}, {-30435, -12142}, +{-30592, -11744}, {-30743, -11342}, +{-30889, -10939}, {-31030, -10534}, +{-31164, -10127}, {-31294, -9718}, +{-31418, -9307}, {-31537, -8895}, +{-31652, -8482}, {-31759, -8067}, +{-31862, -7650}, {-31960, -7233}, +{-32051, -6815}, {-32138, -6393}, +{-32219, -5973}, {-32294, -5549}, +{-32364, -5127}, {-32429, -4703}, +{-32487, -4278}, {-32541, -3852}, +{-32588, -3426}, {-32630, -2999}, +{-32667, -2572}, {-32698, -2144}, +{-32724, -1716}, {-32742, -1287}, +{-32757, -860}, {-32766, -430}, +{-32767, 0}, {-32766, 429}, +{-32757, 858}, {-32743, 1287}, +{-32724, 1715}, {-32698, 2143}, +{-32667, 2570}, {-32631, 2998}, +{-32588, 3425}, {-32541, 3851}, +{-32488, 4277}, {-32429, 4701}, +{-32364, 5125}, {-32295, 5548}, +{-32219, 5971}, {-32138, 6393}, +{-32051, 6813}, {-31960, 7231}, +{-31863, 7650}, {-31760, 8067}, +{-31652, 8481}, {-31539, 8895}, +{-31419, 9306}, {-31294, 9716}, +{-31165, 10126}, {-31030, 10532}, +{-30889, 10937}, {-30743, 11340}, +{-30592, 11741}, {-30436, 12141}, +{-30274, 12540}, {-30107, 12935}, +{-29936, 13328}, {-29758, 13718}, +{-29577, 14107}, {-29390, 14493}, +{-29197, 14875}, {-29000, 15257}, +{-28797, 15635}, {-28590, 16010}, +{-28379, 16384}, {-28162, 16753}, +{-27940, 17119}, {-27714, 17484}, +{-27482, 17845}, {-27246, 18205}, +{-27006, 18560}, {-26760, 18911}, +{-26510, 19260}, {-26257, 19606}, +{-25997, 19947}, {-25734, 20286}, +{-25466, 20621}, {-25194, 20952}, +{-24918, 21281}, {-24637, 21605}, +{-24353, 21926}, {-24063, 22242}, +{-23770, 22555}, {-23473, 22865}, +{-23171, 23171}, {-22866, 23472}, +{-22557, 23769}, {-22244, 24063}, +{-21927, 24352}, {-21606, 24636}, +{-21282, 24917}, {-20954, 25194}, +{-20622, 25465}, {-20288, 25733}, +{-19949, 25997}, {-19607, 26255}, +{-19261, 26509}, {-18914, 26760}, +{-18561, 27004}, {-18205, 27246}, +{-17846, 27481}, {-17485, 27713}, +{-17122, 27940}, {-16755, 28162}, +{-16385, 28378}, {-16012, 28590}, +{-15636, 28797}, {-15258, 28999}, +{-14878, 29197}, {-14494, 29389}, +{-14108, 29576}, {-13720, 29757}, +{-13329, 29934}, {-12937, 30107}, +{-12540, 30274}, {-12142, 30435}, +{-11744, 30592}, {-11342, 30743}, +{-10939, 30889}, {-10534, 31030}, +{-10127, 31164}, {-9718, 31294}, +{-9307, 31418}, {-8895, 31537}, +{-8482, 31652}, {-8067, 31759}, +{-7650, 31862}, {-7233, 31960}, +{-6815, 32051}, {-6393, 32138}, +{-5973, 32219}, {-5549, 32294}, +{-5127, 32364}, {-4703, 32429}, +{-4278, 32487}, {-3852, 32541}, +{-3426, 32588}, {-2999, 32630}, +{-2572, 32667}, {-2144, 32698}, +{-1716, 32724}, {-1287, 32742}, +{-860, 32757}, {-430, 32766}, +{0, 32767}, {429, 32766}, +{858, 32757}, {1287, 32743}, +{1715, 32724}, {2143, 32698}, +{2570, 32667}, {2998, 32631}, +{3425, 32588}, {3851, 32541}, +{4277, 32488}, {4701, 32429}, +{5125, 32364}, {5548, 32295}, +{5971, 32219}, {6393, 32138}, +{6813, 32051}, {7231, 31960}, +{7650, 31863}, {8067, 31760}, +{8481, 31652}, {8895, 31539}, +{9306, 31419}, {9716, 31294}, +{10126, 31165}, {10532, 31030}, +{10937, 30889}, {11340, 30743}, +{11741, 30592}, {12141, 30436}, +{12540, 30274}, {12935, 30107}, +{13328, 29936}, {13718, 29758}, +{14107, 29577}, {14493, 29390}, +{14875, 29197}, {15257, 29000}, +{15635, 28797}, {16010, 28590}, +{16384, 28379}, {16753, 28162}, +{17119, 27940}, {17484, 27714}, +{17845, 27482}, {18205, 27246}, +{18560, 27006}, {18911, 26760}, +{19260, 26510}, {19606, 26257}, +{19947, 25997}, {20286, 25734}, +{20621, 25466}, {20952, 25194}, +{21281, 24918}, {21605, 24637}, +{21926, 24353}, {22242, 24063}, +{22555, 23770}, {22865, 23473}, +{23171, 23171}, {23472, 22866}, +{23769, 22557}, {24063, 22244}, +{24352, 21927}, {24636, 21606}, +{24917, 21282}, {25194, 20954}, +{25465, 20622}, {25733, 20288}, +{25997, 19949}, {26255, 19607}, +{26509, 19261}, {26760, 18914}, +{27004, 18561}, {27246, 18205}, +{27481, 17846}, {27713, 17485}, +{27940, 17122}, {28162, 16755}, +{28378, 16385}, {28590, 16012}, +{28797, 15636}, {28999, 15258}, +{29197, 14878}, {29389, 14494}, +{29576, 14108}, {29757, 13720}, +{29934, 13329}, {30107, 12937}, +{30274, 12540}, {30435, 12142}, +{30592, 11744}, {30743, 11342}, +{30889, 10939}, {31030, 10534}, +{31164, 10127}, {31294, 9718}, +{31418, 9307}, {31537, 8895}, +{31652, 8482}, {31759, 8067}, +{31862, 7650}, {31960, 7233}, +{32051, 6815}, {32138, 6393}, +{32219, 5973}, {32294, 5549}, +{32364, 5127}, {32429, 4703}, +{32487, 4278}, {32541, 3852}, +{32588, 3426}, {32630, 2999}, +{32667, 2572}, {32698, 2144}, +{32724, 1716}, {32742, 1287}, +{32757, 860}, {32766, 430}, +}; +#ifndef FFT_BITREV480 +#define FFT_BITREV480 +static const opus_int16 fft_bitrev480[480] = { +0, 120, 240, 360, 30, 150, 270, 390, 60, 180, 300, 420, 90, 210, 330, +450, 15, 135, 255, 375, 45, 165, 285, 405, 75, 195, 315, 435, 105, 225, +345, 465, 5, 125, 245, 365, 35, 155, 275, 395, 65, 185, 305, 425, 95, +215, 335, 455, 20, 140, 260, 380, 50, 170, 290, 410, 80, 200, 320, 440, +110, 230, 350, 470, 10, 130, 250, 370, 40, 160, 280, 400, 70, 190, 310, +430, 100, 220, 340, 460, 25, 145, 265, 385, 55, 175, 295, 415, 85, 205, +325, 445, 115, 235, 355, 475, 1, 121, 241, 361, 31, 151, 271, 391, 61, +181, 301, 421, 91, 211, 331, 451, 16, 136, 256, 376, 46, 166, 286, 406, +76, 196, 316, 436, 106, 226, 346, 466, 6, 126, 246, 366, 36, 156, 276, +396, 66, 186, 306, 426, 96, 216, 336, 456, 21, 141, 261, 381, 51, 171, +291, 411, 81, 201, 321, 441, 111, 231, 351, 471, 11, 131, 251, 371, 41, +161, 281, 401, 71, 191, 311, 431, 101, 221, 341, 461, 26, 146, 266, 386, +56, 176, 296, 416, 86, 206, 326, 446, 116, 236, 356, 476, 2, 122, 242, +362, 32, 152, 272, 392, 62, 182, 302, 422, 92, 212, 332, 452, 17, 137, +257, 377, 47, 167, 287, 407, 77, 197, 317, 437, 107, 227, 347, 467, 7, +127, 247, 367, 37, 157, 277, 397, 67, 187, 307, 427, 97, 217, 337, 457, +22, 142, 262, 382, 52, 172, 292, 412, 82, 202, 322, 442, 112, 232, 352, +472, 12, 132, 252, 372, 42, 162, 282, 402, 72, 192, 312, 432, 102, 222, +342, 462, 27, 147, 267, 387, 57, 177, 297, 417, 87, 207, 327, 447, 117, +237, 357, 477, 3, 123, 243, 363, 33, 153, 273, 393, 63, 183, 303, 423, +93, 213, 333, 453, 18, 138, 258, 378, 48, 168, 288, 408, 78, 198, 318, +438, 108, 228, 348, 468, 8, 128, 248, 368, 38, 158, 278, 398, 68, 188, +308, 428, 98, 218, 338, 458, 23, 143, 263, 383, 53, 173, 293, 413, 83, +203, 323, 443, 113, 233, 353, 473, 13, 133, 253, 373, 43, 163, 283, 403, +73, 193, 313, 433, 103, 223, 343, 463, 28, 148, 268, 388, 58, 178, 298, +418, 88, 208, 328, 448, 118, 238, 358, 478, 4, 124, 244, 364, 34, 154, +274, 394, 64, 184, 304, 424, 94, 214, 334, 454, 19, 139, 259, 379, 49, +169, 289, 409, 79, 199, 319, 439, 109, 229, 349, 469, 9, 129, 249, 369, +39, 159, 279, 399, 69, 189, 309, 429, 99, 219, 339, 459, 24, 144, 264, +384, 54, 174, 294, 414, 84, 204, 324, 444, 114, 234, 354, 474, 14, 134, +254, 374, 44, 164, 284, 404, 74, 194, 314, 434, 104, 224, 344, 464, 29, +149, 269, 389, 59, 179, 299, 419, 89, 209, 329, 449, 119, 239, 359, 479, +}; +#endif + +#ifndef FFT_BITREV240 +#define FFT_BITREV240 +static const opus_int16 fft_bitrev240[240] = { +0, 60, 120, 180, 15, 75, 135, 195, 30, 90, 150, 210, 45, 105, 165, +225, 5, 65, 125, 185, 20, 80, 140, 200, 35, 95, 155, 215, 50, 110, +170, 230, 10, 70, 130, 190, 25, 85, 145, 205, 40, 100, 160, 220, 55, +115, 175, 235, 1, 61, 121, 181, 16, 76, 136, 196, 31, 91, 151, 211, +46, 106, 166, 226, 6, 66, 126, 186, 21, 81, 141, 201, 36, 96, 156, +216, 51, 111, 171, 231, 11, 71, 131, 191, 26, 86, 146, 206, 41, 101, +161, 221, 56, 116, 176, 236, 2, 62, 122, 182, 17, 77, 137, 197, 32, +92, 152, 212, 47, 107, 167, 227, 7, 67, 127, 187, 22, 82, 142, 202, +37, 97, 157, 217, 52, 112, 172, 232, 12, 72, 132, 192, 27, 87, 147, +207, 42, 102, 162, 222, 57, 117, 177, 237, 3, 63, 123, 183, 18, 78, +138, 198, 33, 93, 153, 213, 48, 108, 168, 228, 8, 68, 128, 188, 23, +83, 143, 203, 38, 98, 158, 218, 53, 113, 173, 233, 13, 73, 133, 193, +28, 88, 148, 208, 43, 103, 163, 223, 58, 118, 178, 238, 4, 64, 124, +184, 19, 79, 139, 199, 34, 94, 154, 214, 49, 109, 169, 229, 9, 69, +129, 189, 24, 84, 144, 204, 39, 99, 159, 219, 54, 114, 174, 234, 14, +74, 134, 194, 29, 89, 149, 209, 44, 104, 164, 224, 59, 119, 179, 239, +}; +#endif + +#ifndef FFT_BITREV120 +#define FFT_BITREV120 +static const opus_int16 fft_bitrev120[120] = { +0, 30, 60, 90, 15, 45, 75, 105, 5, 35, 65, 95, 20, 50, 80, +110, 10, 40, 70, 100, 25, 55, 85, 115, 1, 31, 61, 91, 16, 46, +76, 106, 6, 36, 66, 96, 21, 51, 81, 111, 11, 41, 71, 101, 26, +56, 86, 116, 2, 32, 62, 92, 17, 47, 77, 107, 7, 37, 67, 97, +22, 52, 82, 112, 12, 42, 72, 102, 27, 57, 87, 117, 3, 33, 63, +93, 18, 48, 78, 108, 8, 38, 68, 98, 23, 53, 83, 113, 13, 43, +73, 103, 28, 58, 88, 118, 4, 34, 64, 94, 19, 49, 79, 109, 9, +39, 69, 99, 24, 54, 84, 114, 14, 44, 74, 104, 29, 59, 89, 119, +}; +#endif + +#ifndef FFT_BITREV60 +#define FFT_BITREV60 +static const opus_int16 fft_bitrev60[60] = { +0, 15, 30, 45, 5, 20, 35, 50, 10, 25, 40, 55, 1, 16, 31, +46, 6, 21, 36, 51, 11, 26, 41, 56, 2, 17, 32, 47, 7, 22, +37, 52, 12, 27, 42, 57, 3, 18, 33, 48, 8, 23, 38, 53, 13, +28, 43, 58, 4, 19, 34, 49, 9, 24, 39, 54, 14, 29, 44, 59, +}; +#endif + +#ifndef FFT_STATE48000_960_0 +#define FFT_STATE48000_960_0 +static const kiss_fft_state fft_state48000_960_0 = { +480, /* nfft */ +-1, /* shift */ +{4, 120, 4, 30, 2, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, }, /* factors */ +fft_bitrev480, /* bitrev */ +fft_twiddles48000_960, /* bitrev */ +}; +#endif + +#ifndef FFT_STATE48000_960_1 +#define FFT_STATE48000_960_1 +static const kiss_fft_state fft_state48000_960_1 = { +240, /* nfft */ +1, /* shift */ +{4, 60, 4, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */ +fft_bitrev240, /* bitrev */ +fft_twiddles48000_960, /* bitrev */ +}; +#endif + +#ifndef FFT_STATE48000_960_2 +#define FFT_STATE48000_960_2 +static const kiss_fft_state fft_state48000_960_2 = { +120, /* nfft */ +2, /* shift */ +{4, 30, 2, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */ +fft_bitrev120, /* bitrev */ +fft_twiddles48000_960, /* bitrev */ +}; +#endif + +#ifndef FFT_STATE48000_960_3 +#define FFT_STATE48000_960_3 +static const kiss_fft_state fft_state48000_960_3 = { +60, /* nfft */ +3, /* shift */ +{4, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */ +fft_bitrev60, /* bitrev */ +fft_twiddles48000_960, /* bitrev */ +}; +#endif + +#endif + +#ifndef MDCT_TWIDDLES960 +#define MDCT_TWIDDLES960 +static const opus_val16 mdct_twiddles960[481] = { +32767, 32767, 32767, 32767, 32766, +32763, 32762, 32759, 32757, 32753, +32751, 32747, 32743, 32738, 32733, +32729, 32724, 32717, 32711, 32705, +32698, 32690, 32683, 32676, 32667, +32658, 32650, 32640, 32631, 32620, +32610, 32599, 32588, 32577, 32566, +32554, 32541, 32528, 32515, 32502, +32487, 32474, 32459, 32444, 32429, +32413, 32397, 32381, 32364, 32348, +32331, 32313, 32294, 32277, 32257, +32239, 32219, 32200, 32180, 32159, +32138, 32118, 32096, 32074, 32051, +32029, 32006, 31984, 31960, 31936, +31912, 31888, 31863, 31837, 31812, +31786, 31760, 31734, 31707, 31679, +31652, 31624, 31596, 31567, 31539, +31508, 31479, 31450, 31419, 31388, +31357, 31326, 31294, 31262, 31230, +31198, 31164, 31131, 31097, 31063, +31030, 30994, 30959, 30924, 30889, +30853, 30816, 30779, 30743, 30705, +30668, 30629, 30592, 30553, 30515, +30475, 30435, 30396, 30356, 30315, +30274, 30233, 30191, 30149, 30107, +30065, 30022, 29979, 29936, 29891, +29847, 29803, 29758, 29713, 29668, +29622, 29577, 29529, 29483, 29436, +29390, 29341, 29293, 29246, 29197, +29148, 29098, 29050, 29000, 28949, +28899, 28848, 28797, 28746, 28694, +28642, 28590, 28537, 28485, 28432, +28378, 28324, 28271, 28217, 28162, +28106, 28051, 27995, 27940, 27884, +27827, 27770, 27713, 27657, 27598, +27540, 27481, 27423, 27365, 27305, +27246, 27187, 27126, 27066, 27006, +26945, 26883, 26822, 26760, 26698, +26636, 26574, 26510, 26448, 26383, +26320, 26257, 26191, 26127, 26062, +25997, 25931, 25866, 25800, 25734, +25667, 25601, 25533, 25466, 25398, +25330, 25262, 25194, 25125, 25056, +24987, 24917, 24848, 24778, 24707, +24636, 24566, 24495, 24424, 24352, +24280, 24208, 24135, 24063, 23990, +23917, 23842, 23769, 23695, 23622, +23546, 23472, 23398, 23322, 23246, +23171, 23095, 23018, 22942, 22866, +22788, 22711, 22634, 22557, 22478, +22400, 22322, 22244, 22165, 22085, +22006, 21927, 21846, 21766, 21687, +21606, 21524, 21443, 21363, 21282, +21199, 21118, 21035, 20954, 20870, +20788, 20705, 20621, 20538, 20455, +20371, 20286, 20202, 20118, 20034, +19947, 19863, 19777, 19692, 19606, +19520, 19434, 19347, 19260, 19174, +19088, 18999, 18911, 18825, 18737, +18648, 18560, 18472, 18384, 18294, +18205, 18116, 18025, 17936, 17846, +17757, 17666, 17576, 17485, 17395, +17303, 17212, 17122, 17030, 16937, +16846, 16755, 16662, 16569, 16477, +16385, 16291, 16198, 16105, 16012, +15917, 15824, 15730, 15636, 15541, +15447, 15352, 15257, 15162, 15067, +14973, 14875, 14781, 14685, 14589, +14493, 14396, 14300, 14204, 14107, +14010, 13914, 13815, 13718, 13621, +13524, 13425, 13328, 13230, 13133, +13033, 12935, 12836, 12738, 12638, +12540, 12441, 12341, 12241, 12142, +12044, 11943, 11843, 11744, 11643, +11542, 11442, 11342, 11241, 11139, +11039, 10939, 10836, 10736, 10635, +10534, 10431, 10330, 10228, 10127, +10024, 9921, 9820, 9718, 9614, +9512, 9410, 9306, 9204, 9101, +8998, 8895, 8791, 8689, 8585, +8481, 8377, 8274, 8171, 8067, +7962, 7858, 7753, 7650, 7545, +7441, 7336, 7231, 7129, 7023, +6917, 6813, 6709, 6604, 6498, +6393, 6288, 6182, 6077, 5973, +5867, 5760, 5656, 5549, 5445, +5339, 5232, 5127, 5022, 4914, +4809, 4703, 4596, 4490, 4384, +4278, 4171, 4065, 3958, 3852, +3745, 3640, 3532, 3426, 3318, +3212, 3106, 2998, 2891, 2786, +2679, 2570, 2465, 2358, 2251, +2143, 2037, 1929, 1823, 1715, +1609, 1501, 1393, 1287, 1180, +1073, 964, 858, 751, 644, +535, 429, 322, 214, 107, +0, }; +#endif + +static const CELTMode mode48000_960_120 = { +48000, /* Fs */ +120, /* overlap */ +21, /* nbEBands */ +21, /* effEBands */ +{27853, 0, 4096, 8192, }, /* preemph */ +eband5ms, /* eBands */ +3, /* maxLM */ +8, /* nbShortMdcts */ +120, /* shortMdctSize */ +11, /* nbAllocVectors */ +band_allocation, /* allocVectors */ +logN400, /* logN */ +window120, /* window */ +{1920, 3, {&fft_state48000_960_0, &fft_state48000_960_1, &fft_state48000_960_2, &fft_state48000_960_3, }, mdct_twiddles960}, /* mdct */ +{392, cache_index50, cache_bits50, cache_caps50}, /* cache */ +}; + +/* List of all the available modes */ +#define TOTAL_MODES 1 +static const CELTMode * const static_mode_list[TOTAL_MODES] = { +&mode48000_960_120, +}; diff --git a/src/opus-1.1/celt/static_modes_float.h b/src/opus-1.1/celt/static_modes_float.h new file mode 100644 index 00000000..5d7e7b8e --- /dev/null +++ b/src/opus-1.1/celt/static_modes_float.h @@ -0,0 +1,599 @@ +/* The contents of this file was automatically generated by dump_modes.c + with arguments: 48000 960 + It contains static definitions for some pre-defined modes. */ +#include "modes.h" +#include "rate.h" + +#ifndef DEF_WINDOW120 +#define DEF_WINDOW120 +static const opus_val16 window120[120] = { +6.7286966e-05f, 0.00060551348f, 0.0016815970f, 0.0032947962f, 0.0054439943f, +0.0081276923f, 0.011344001f, 0.015090633f, 0.019364886f, 0.024163635f, +0.029483315f, 0.035319905f, 0.041668911f, 0.048525347f, 0.055883718f, +0.063737999f, 0.072081616f, 0.080907428f, 0.090207705f, 0.099974111f, +0.11019769f, 0.12086883f, 0.13197729f, 0.14351214f, 0.15546177f, +0.16781389f, 0.18055550f, 0.19367290f, 0.20715171f, 0.22097682f, +0.23513243f, 0.24960208f, 0.26436860f, 0.27941419f, 0.29472040f, +0.31026818f, 0.32603788f, 0.34200931f, 0.35816177f, 0.37447407f, +0.39092462f, 0.40749142f, 0.42415215f, 0.44088423f, 0.45766484f, +0.47447104f, 0.49127978f, 0.50806798f, 0.52481261f, 0.54149077f, +0.55807973f, 0.57455701f, 0.59090049f, 0.60708841f, 0.62309951f, +0.63891306f, 0.65450896f, 0.66986776f, 0.68497077f, 0.69980010f, +0.71433873f, 0.72857055f, 0.74248043f, 0.75605424f, 0.76927895f, +0.78214257f, 0.79463430f, 0.80674445f, 0.81846456f, 0.82978733f, +0.84070669f, 0.85121779f, 0.86131698f, 0.87100183f, 0.88027111f, +0.88912479f, 0.89756398f, 0.90559094f, 0.91320904f, 0.92042270f, +0.92723738f, 0.93365955f, 0.93969656f, 0.94535671f, 0.95064907f, +0.95558353f, 0.96017067f, 0.96442171f, 0.96834849f, 0.97196334f, +0.97527906f, 0.97830883f, 0.98106616f, 0.98356480f, 0.98581869f, +0.98784191f, 0.98964856f, 0.99125274f, 0.99266849f, 0.99390969f, +0.99499004f, 0.99592297f, 0.99672162f, 0.99739874f, 0.99796667f, +0.99843728f, 0.99882195f, 0.99913147f, 0.99937606f, 0.99956527f, +0.99970802f, 0.99981248f, 0.99988613f, 0.99993565f, 0.99996697f, +0.99998518f, 0.99999457f, 0.99999859f, 0.99999982f, 1.0000000f, +}; +#endif + +#ifndef DEF_LOGN400 +#define DEF_LOGN400 +static const opus_int16 logN400[21] = { +0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 16, 16, 16, 21, 21, 24, 29, 34, 36, }; +#endif + +#ifndef DEF_PULSE_CACHE50 +#define DEF_PULSE_CACHE50 +static const opus_int16 cache_index50[105] = { +-1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 41, 41, 41, +82, 82, 123, 164, 200, 222, 0, 0, 0, 0, 0, 0, 0, 0, 41, +41, 41, 41, 123, 123, 123, 164, 164, 240, 266, 283, 295, 41, 41, 41, +41, 41, 41, 41, 41, 123, 123, 123, 123, 240, 240, 240, 266, 266, 305, +318, 328, 336, 123, 123, 123, 123, 123, 123, 123, 123, 240, 240, 240, 240, +305, 305, 305, 318, 318, 343, 351, 358, 364, 240, 240, 240, 240, 240, 240, +240, 240, 305, 305, 305, 305, 343, 343, 343, 351, 351, 370, 376, 382, 387, +}; +static const unsigned char cache_bits50[392] = { +40, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, +7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, +7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 40, 15, 23, 28, +31, 34, 36, 38, 39, 41, 42, 43, 44, 45, 46, 47, 47, 49, 50, +51, 52, 53, 54, 55, 55, 57, 58, 59, 60, 61, 62, 63, 63, 65, +66, 67, 68, 69, 70, 71, 71, 40, 20, 33, 41, 48, 53, 57, 61, +64, 66, 69, 71, 73, 75, 76, 78, 80, 82, 85, 87, 89, 91, 92, +94, 96, 98, 101, 103, 105, 107, 108, 110, 112, 114, 117, 119, 121, 123, +124, 126, 128, 40, 23, 39, 51, 60, 67, 73, 79, 83, 87, 91, 94, +97, 100, 102, 105, 107, 111, 115, 118, 121, 124, 126, 129, 131, 135, 139, +142, 145, 148, 150, 153, 155, 159, 163, 166, 169, 172, 174, 177, 179, 35, +28, 49, 65, 78, 89, 99, 107, 114, 120, 126, 132, 136, 141, 145, 149, +153, 159, 165, 171, 176, 180, 185, 189, 192, 199, 205, 211, 216, 220, 225, +229, 232, 239, 245, 251, 21, 33, 58, 79, 97, 112, 125, 137, 148, 157, +166, 174, 182, 189, 195, 201, 207, 217, 227, 235, 243, 251, 17, 35, 63, +86, 106, 123, 139, 152, 165, 177, 187, 197, 206, 214, 222, 230, 237, 250, +25, 31, 55, 75, 91, 105, 117, 128, 138, 146, 154, 161, 168, 174, 180, +185, 190, 200, 208, 215, 222, 229, 235, 240, 245, 255, 16, 36, 65, 89, +110, 128, 144, 159, 173, 185, 196, 207, 217, 226, 234, 242, 250, 11, 41, +74, 103, 128, 151, 172, 191, 209, 225, 241, 255, 9, 43, 79, 110, 138, +163, 186, 207, 227, 246, 12, 39, 71, 99, 123, 144, 164, 182, 198, 214, +228, 241, 253, 9, 44, 81, 113, 142, 168, 192, 214, 235, 255, 7, 49, +90, 127, 160, 191, 220, 247, 6, 51, 95, 134, 170, 203, 234, 7, 47, +87, 123, 155, 184, 212, 237, 6, 52, 97, 137, 174, 208, 240, 5, 57, +106, 151, 192, 231, 5, 59, 111, 158, 202, 243, 5, 55, 103, 147, 187, +224, 5, 60, 113, 161, 206, 248, 4, 65, 122, 175, 224, 4, 67, 127, +182, 234, }; +static const unsigned char cache_caps50[168] = { +224, 224, 224, 224, 224, 224, 224, 224, 160, 160, 160, 160, 185, 185, 185, +178, 178, 168, 134, 61, 37, 224, 224, 224, 224, 224, 224, 224, 224, 240, +240, 240, 240, 207, 207, 207, 198, 198, 183, 144, 66, 40, 160, 160, 160, +160, 160, 160, 160, 160, 185, 185, 185, 185, 193, 193, 193, 183, 183, 172, +138, 64, 38, 240, 240, 240, 240, 240, 240, 240, 240, 207, 207, 207, 207, +204, 204, 204, 193, 193, 180, 143, 66, 40, 185, 185, 185, 185, 185, 185, +185, 185, 193, 193, 193, 193, 193, 193, 193, 183, 183, 172, 138, 65, 39, +207, 207, 207, 207, 207, 207, 207, 207, 204, 204, 204, 204, 201, 201, 201, +188, 188, 176, 141, 66, 40, 193, 193, 193, 193, 193, 193, 193, 193, 193, +193, 193, 193, 194, 194, 194, 184, 184, 173, 139, 65, 39, 204, 204, 204, +204, 204, 204, 204, 204, 201, 201, 201, 201, 198, 198, 198, 187, 187, 175, +140, 66, 40, }; +#endif + +#ifndef FFT_TWIDDLES48000_960 +#define FFT_TWIDDLES48000_960 +static const kiss_twiddle_cpx fft_twiddles48000_960[480] = { +{1.0000000f, -0.0000000f}, {0.99991433f, -0.013089596f}, +{0.99965732f, -0.026176948f}, {0.99922904f, -0.039259816f}, +{0.99862953f, -0.052335956f}, {0.99785892f, -0.065403129f}, +{0.99691733f, -0.078459096f}, {0.99580493f, -0.091501619f}, +{0.99452190f, -0.10452846f}, {0.99306846f, -0.11753740f}, +{0.99144486f, -0.13052619f}, {0.98965139f, -0.14349262f}, +{0.98768834f, -0.15643447f}, {0.98555606f, -0.16934950f}, +{0.98325491f, -0.18223553f}, {0.98078528f, -0.19509032f}, +{0.97814760f, -0.20791169f}, {0.97534232f, -0.22069744f}, +{0.97236992f, -0.23344536f}, {0.96923091f, -0.24615329f}, +{0.96592583f, -0.25881905f}, {0.96245524f, -0.27144045f}, +{0.95881973f, -0.28401534f}, {0.95501994f, -0.29654157f}, +{0.95105652f, -0.30901699f}, {0.94693013f, -0.32143947f}, +{0.94264149f, -0.33380686f}, {0.93819134f, -0.34611706f}, +{0.93358043f, -0.35836795f}, {0.92880955f, -0.37055744f}, +{0.92387953f, -0.38268343f}, {0.91879121f, -0.39474386f}, +{0.91354546f, -0.40673664f}, {0.90814317f, -0.41865974f}, +{0.90258528f, -0.43051110f}, {0.89687274f, -0.44228869f}, +{0.89100652f, -0.45399050f}, {0.88498764f, -0.46561452f}, +{0.87881711f, -0.47715876f}, {0.87249601f, -0.48862124f}, +{0.86602540f, -0.50000000f}, {0.85940641f, -0.51129309f}, +{0.85264016f, -0.52249856f}, {0.84572782f, -0.53361452f}, +{0.83867057f, -0.54463904f}, {0.83146961f, -0.55557023f}, +{0.82412619f, -0.56640624f}, {0.81664156f, -0.57714519f}, +{0.80901699f, -0.58778525f}, {0.80125381f, -0.59832460f}, +{0.79335334f, -0.60876143f}, {0.78531693f, -0.61909395f}, +{0.77714596f, -0.62932039f}, {0.76884183f, -0.63943900f}, +{0.76040597f, -0.64944805f}, {0.75183981f, -0.65934582f}, +{0.74314483f, -0.66913061f}, {0.73432251f, -0.67880075f}, +{0.72537437f, -0.68835458f}, {0.71630194f, -0.69779046f}, +{0.70710678f, -0.70710678f}, {0.69779046f, -0.71630194f}, +{0.68835458f, -0.72537437f}, {0.67880075f, -0.73432251f}, +{0.66913061f, -0.74314483f}, {0.65934582f, -0.75183981f}, +{0.64944805f, -0.76040597f}, {0.63943900f, -0.76884183f}, +{0.62932039f, -0.77714596f}, {0.61909395f, -0.78531693f}, +{0.60876143f, -0.79335334f}, {0.59832460f, -0.80125381f}, +{0.58778525f, -0.80901699f}, {0.57714519f, -0.81664156f}, +{0.56640624f, -0.82412619f}, {0.55557023f, -0.83146961f}, +{0.54463904f, -0.83867057f}, {0.53361452f, -0.84572782f}, +{0.52249856f, -0.85264016f}, {0.51129309f, -0.85940641f}, +{0.50000000f, -0.86602540f}, {0.48862124f, -0.87249601f}, +{0.47715876f, -0.87881711f}, {0.46561452f, -0.88498764f}, +{0.45399050f, -0.89100652f}, {0.44228869f, -0.89687274f}, +{0.43051110f, -0.90258528f}, {0.41865974f, -0.90814317f}, +{0.40673664f, -0.91354546f}, {0.39474386f, -0.91879121f}, +{0.38268343f, -0.92387953f}, {0.37055744f, -0.92880955f}, +{0.35836795f, -0.93358043f}, {0.34611706f, -0.93819134f}, +{0.33380686f, -0.94264149f}, {0.32143947f, -0.94693013f}, +{0.30901699f, -0.95105652f}, {0.29654157f, -0.95501994f}, +{0.28401534f, -0.95881973f}, {0.27144045f, -0.96245524f}, +{0.25881905f, -0.96592583f}, {0.24615329f, -0.96923091f}, +{0.23344536f, -0.97236992f}, {0.22069744f, -0.97534232f}, +{0.20791169f, -0.97814760f}, {0.19509032f, -0.98078528f}, +{0.18223553f, -0.98325491f}, {0.16934950f, -0.98555606f}, +{0.15643447f, -0.98768834f}, {0.14349262f, -0.98965139f}, +{0.13052619f, -0.99144486f}, {0.11753740f, -0.99306846f}, +{0.10452846f, -0.99452190f}, {0.091501619f, -0.99580493f}, +{0.078459096f, -0.99691733f}, {0.065403129f, -0.99785892f}, +{0.052335956f, -0.99862953f}, {0.039259816f, -0.99922904f}, +{0.026176948f, -0.99965732f}, {0.013089596f, -0.99991433f}, +{6.1230318e-17f, -1.0000000f}, {-0.013089596f, -0.99991433f}, +{-0.026176948f, -0.99965732f}, {-0.039259816f, -0.99922904f}, +{-0.052335956f, -0.99862953f}, {-0.065403129f, -0.99785892f}, +{-0.078459096f, -0.99691733f}, {-0.091501619f, -0.99580493f}, +{-0.10452846f, -0.99452190f}, {-0.11753740f, -0.99306846f}, +{-0.13052619f, -0.99144486f}, {-0.14349262f, -0.98965139f}, +{-0.15643447f, -0.98768834f}, {-0.16934950f, -0.98555606f}, +{-0.18223553f, -0.98325491f}, {-0.19509032f, -0.98078528f}, +{-0.20791169f, -0.97814760f}, {-0.22069744f, -0.97534232f}, +{-0.23344536f, -0.97236992f}, {-0.24615329f, -0.96923091f}, +{-0.25881905f, -0.96592583f}, {-0.27144045f, -0.96245524f}, +{-0.28401534f, -0.95881973f}, {-0.29654157f, -0.95501994f}, +{-0.30901699f, -0.95105652f}, {-0.32143947f, -0.94693013f}, +{-0.33380686f, -0.94264149f}, {-0.34611706f, -0.93819134f}, +{-0.35836795f, -0.93358043f}, {-0.37055744f, -0.92880955f}, +{-0.38268343f, -0.92387953f}, {-0.39474386f, -0.91879121f}, +{-0.40673664f, -0.91354546f}, {-0.41865974f, -0.90814317f}, +{-0.43051110f, -0.90258528f}, {-0.44228869f, -0.89687274f}, +{-0.45399050f, -0.89100652f}, {-0.46561452f, -0.88498764f}, +{-0.47715876f, -0.87881711f}, {-0.48862124f, -0.87249601f}, +{-0.50000000f, -0.86602540f}, {-0.51129309f, -0.85940641f}, +{-0.52249856f, -0.85264016f}, {-0.53361452f, -0.84572782f}, +{-0.54463904f, -0.83867057f}, {-0.55557023f, -0.83146961f}, +{-0.56640624f, -0.82412619f}, {-0.57714519f, -0.81664156f}, +{-0.58778525f, -0.80901699f}, {-0.59832460f, -0.80125381f}, +{-0.60876143f, -0.79335334f}, {-0.61909395f, -0.78531693f}, +{-0.62932039f, -0.77714596f}, {-0.63943900f, -0.76884183f}, +{-0.64944805f, -0.76040597f}, {-0.65934582f, -0.75183981f}, +{-0.66913061f, -0.74314483f}, {-0.67880075f, -0.73432251f}, +{-0.68835458f, -0.72537437f}, {-0.69779046f, -0.71630194f}, +{-0.70710678f, -0.70710678f}, {-0.71630194f, -0.69779046f}, +{-0.72537437f, -0.68835458f}, {-0.73432251f, -0.67880075f}, +{-0.74314483f, -0.66913061f}, {-0.75183981f, -0.65934582f}, +{-0.76040597f, -0.64944805f}, {-0.76884183f, -0.63943900f}, +{-0.77714596f, -0.62932039f}, {-0.78531693f, -0.61909395f}, +{-0.79335334f, -0.60876143f}, {-0.80125381f, -0.59832460f}, +{-0.80901699f, -0.58778525f}, {-0.81664156f, -0.57714519f}, +{-0.82412619f, -0.56640624f}, {-0.83146961f, -0.55557023f}, +{-0.83867057f, -0.54463904f}, {-0.84572782f, -0.53361452f}, +{-0.85264016f, -0.52249856f}, {-0.85940641f, -0.51129309f}, +{-0.86602540f, -0.50000000f}, {-0.87249601f, -0.48862124f}, +{-0.87881711f, -0.47715876f}, {-0.88498764f, -0.46561452f}, +{-0.89100652f, -0.45399050f}, {-0.89687274f, -0.44228869f}, +{-0.90258528f, -0.43051110f}, {-0.90814317f, -0.41865974f}, +{-0.91354546f, -0.40673664f}, {-0.91879121f, -0.39474386f}, +{-0.92387953f, -0.38268343f}, {-0.92880955f, -0.37055744f}, +{-0.93358043f, -0.35836795f}, {-0.93819134f, -0.34611706f}, +{-0.94264149f, -0.33380686f}, {-0.94693013f, -0.32143947f}, +{-0.95105652f, -0.30901699f}, {-0.95501994f, -0.29654157f}, +{-0.95881973f, -0.28401534f}, {-0.96245524f, -0.27144045f}, +{-0.96592583f, -0.25881905f}, {-0.96923091f, -0.24615329f}, +{-0.97236992f, -0.23344536f}, {-0.97534232f, -0.22069744f}, +{-0.97814760f, -0.20791169f}, {-0.98078528f, -0.19509032f}, +{-0.98325491f, -0.18223553f}, {-0.98555606f, -0.16934950f}, +{-0.98768834f, -0.15643447f}, {-0.98965139f, -0.14349262f}, +{-0.99144486f, -0.13052619f}, {-0.99306846f, -0.11753740f}, +{-0.99452190f, -0.10452846f}, {-0.99580493f, -0.091501619f}, +{-0.99691733f, -0.078459096f}, {-0.99785892f, -0.065403129f}, +{-0.99862953f, -0.052335956f}, {-0.99922904f, -0.039259816f}, +{-0.99965732f, -0.026176948f}, {-0.99991433f, -0.013089596f}, +{-1.0000000f, -1.2246064e-16f}, {-0.99991433f, 0.013089596f}, +{-0.99965732f, 0.026176948f}, {-0.99922904f, 0.039259816f}, +{-0.99862953f, 0.052335956f}, {-0.99785892f, 0.065403129f}, +{-0.99691733f, 0.078459096f}, {-0.99580493f, 0.091501619f}, +{-0.99452190f, 0.10452846f}, {-0.99306846f, 0.11753740f}, +{-0.99144486f, 0.13052619f}, {-0.98965139f, 0.14349262f}, +{-0.98768834f, 0.15643447f}, {-0.98555606f, 0.16934950f}, +{-0.98325491f, 0.18223553f}, {-0.98078528f, 0.19509032f}, +{-0.97814760f, 0.20791169f}, {-0.97534232f, 0.22069744f}, +{-0.97236992f, 0.23344536f}, {-0.96923091f, 0.24615329f}, +{-0.96592583f, 0.25881905f}, {-0.96245524f, 0.27144045f}, +{-0.95881973f, 0.28401534f}, {-0.95501994f, 0.29654157f}, +{-0.95105652f, 0.30901699f}, {-0.94693013f, 0.32143947f}, +{-0.94264149f, 0.33380686f}, {-0.93819134f, 0.34611706f}, +{-0.93358043f, 0.35836795f}, {-0.92880955f, 0.37055744f}, +{-0.92387953f, 0.38268343f}, {-0.91879121f, 0.39474386f}, +{-0.91354546f, 0.40673664f}, {-0.90814317f, 0.41865974f}, +{-0.90258528f, 0.43051110f}, {-0.89687274f, 0.44228869f}, +{-0.89100652f, 0.45399050f}, {-0.88498764f, 0.46561452f}, +{-0.87881711f, 0.47715876f}, {-0.87249601f, 0.48862124f}, +{-0.86602540f, 0.50000000f}, {-0.85940641f, 0.51129309f}, +{-0.85264016f, 0.52249856f}, {-0.84572782f, 0.53361452f}, +{-0.83867057f, 0.54463904f}, {-0.83146961f, 0.55557023f}, +{-0.82412619f, 0.56640624f}, {-0.81664156f, 0.57714519f}, +{-0.80901699f, 0.58778525f}, {-0.80125381f, 0.59832460f}, +{-0.79335334f, 0.60876143f}, {-0.78531693f, 0.61909395f}, +{-0.77714596f, 0.62932039f}, {-0.76884183f, 0.63943900f}, +{-0.76040597f, 0.64944805f}, {-0.75183981f, 0.65934582f}, +{-0.74314483f, 0.66913061f}, {-0.73432251f, 0.67880075f}, +{-0.72537437f, 0.68835458f}, {-0.71630194f, 0.69779046f}, +{-0.70710678f, 0.70710678f}, {-0.69779046f, 0.71630194f}, +{-0.68835458f, 0.72537437f}, {-0.67880075f, 0.73432251f}, +{-0.66913061f, 0.74314483f}, {-0.65934582f, 0.75183981f}, +{-0.64944805f, 0.76040597f}, {-0.63943900f, 0.76884183f}, +{-0.62932039f, 0.77714596f}, {-0.61909395f, 0.78531693f}, +{-0.60876143f, 0.79335334f}, {-0.59832460f, 0.80125381f}, +{-0.58778525f, 0.80901699f}, {-0.57714519f, 0.81664156f}, +{-0.56640624f, 0.82412619f}, {-0.55557023f, 0.83146961f}, +{-0.54463904f, 0.83867057f}, {-0.53361452f, 0.84572782f}, +{-0.52249856f, 0.85264016f}, {-0.51129309f, 0.85940641f}, +{-0.50000000f, 0.86602540f}, {-0.48862124f, 0.87249601f}, +{-0.47715876f, 0.87881711f}, {-0.46561452f, 0.88498764f}, +{-0.45399050f, 0.89100652f}, {-0.44228869f, 0.89687274f}, +{-0.43051110f, 0.90258528f}, {-0.41865974f, 0.90814317f}, +{-0.40673664f, 0.91354546f}, {-0.39474386f, 0.91879121f}, +{-0.38268343f, 0.92387953f}, {-0.37055744f, 0.92880955f}, +{-0.35836795f, 0.93358043f}, {-0.34611706f, 0.93819134f}, +{-0.33380686f, 0.94264149f}, {-0.32143947f, 0.94693013f}, +{-0.30901699f, 0.95105652f}, {-0.29654157f, 0.95501994f}, +{-0.28401534f, 0.95881973f}, {-0.27144045f, 0.96245524f}, +{-0.25881905f, 0.96592583f}, {-0.24615329f, 0.96923091f}, +{-0.23344536f, 0.97236992f}, {-0.22069744f, 0.97534232f}, +{-0.20791169f, 0.97814760f}, {-0.19509032f, 0.98078528f}, +{-0.18223553f, 0.98325491f}, {-0.16934950f, 0.98555606f}, +{-0.15643447f, 0.98768834f}, {-0.14349262f, 0.98965139f}, +{-0.13052619f, 0.99144486f}, {-0.11753740f, 0.99306846f}, +{-0.10452846f, 0.99452190f}, {-0.091501619f, 0.99580493f}, +{-0.078459096f, 0.99691733f}, {-0.065403129f, 0.99785892f}, +{-0.052335956f, 0.99862953f}, {-0.039259816f, 0.99922904f}, +{-0.026176948f, 0.99965732f}, {-0.013089596f, 0.99991433f}, +{-1.8369095e-16f, 1.0000000f}, {0.013089596f, 0.99991433f}, +{0.026176948f, 0.99965732f}, {0.039259816f, 0.99922904f}, +{0.052335956f, 0.99862953f}, {0.065403129f, 0.99785892f}, +{0.078459096f, 0.99691733f}, {0.091501619f, 0.99580493f}, +{0.10452846f, 0.99452190f}, {0.11753740f, 0.99306846f}, +{0.13052619f, 0.99144486f}, {0.14349262f, 0.98965139f}, +{0.15643447f, 0.98768834f}, {0.16934950f, 0.98555606f}, +{0.18223553f, 0.98325491f}, {0.19509032f, 0.98078528f}, +{0.20791169f, 0.97814760f}, {0.22069744f, 0.97534232f}, +{0.23344536f, 0.97236992f}, {0.24615329f, 0.96923091f}, +{0.25881905f, 0.96592583f}, {0.27144045f, 0.96245524f}, +{0.28401534f, 0.95881973f}, {0.29654157f, 0.95501994f}, +{0.30901699f, 0.95105652f}, {0.32143947f, 0.94693013f}, +{0.33380686f, 0.94264149f}, {0.34611706f, 0.93819134f}, +{0.35836795f, 0.93358043f}, {0.37055744f, 0.92880955f}, +{0.38268343f, 0.92387953f}, {0.39474386f, 0.91879121f}, +{0.40673664f, 0.91354546f}, {0.41865974f, 0.90814317f}, +{0.43051110f, 0.90258528f}, {0.44228869f, 0.89687274f}, +{0.45399050f, 0.89100652f}, {0.46561452f, 0.88498764f}, +{0.47715876f, 0.87881711f}, {0.48862124f, 0.87249601f}, +{0.50000000f, 0.86602540f}, {0.51129309f, 0.85940641f}, +{0.52249856f, 0.85264016f}, {0.53361452f, 0.84572782f}, +{0.54463904f, 0.83867057f}, {0.55557023f, 0.83146961f}, +{0.56640624f, 0.82412619f}, {0.57714519f, 0.81664156f}, +{0.58778525f, 0.80901699f}, {0.59832460f, 0.80125381f}, +{0.60876143f, 0.79335334f}, {0.61909395f, 0.78531693f}, +{0.62932039f, 0.77714596f}, {0.63943900f, 0.76884183f}, +{0.64944805f, 0.76040597f}, {0.65934582f, 0.75183981f}, +{0.66913061f, 0.74314483f}, {0.67880075f, 0.73432251f}, +{0.68835458f, 0.72537437f}, {0.69779046f, 0.71630194f}, +{0.70710678f, 0.70710678f}, {0.71630194f, 0.69779046f}, +{0.72537437f, 0.68835458f}, {0.73432251f, 0.67880075f}, +{0.74314483f, 0.66913061f}, {0.75183981f, 0.65934582f}, +{0.76040597f, 0.64944805f}, {0.76884183f, 0.63943900f}, +{0.77714596f, 0.62932039f}, {0.78531693f, 0.61909395f}, +{0.79335334f, 0.60876143f}, {0.80125381f, 0.59832460f}, +{0.80901699f, 0.58778525f}, {0.81664156f, 0.57714519f}, +{0.82412619f, 0.56640624f}, {0.83146961f, 0.55557023f}, +{0.83867057f, 0.54463904f}, {0.84572782f, 0.53361452f}, +{0.85264016f, 0.52249856f}, {0.85940641f, 0.51129309f}, +{0.86602540f, 0.50000000f}, {0.87249601f, 0.48862124f}, +{0.87881711f, 0.47715876f}, {0.88498764f, 0.46561452f}, +{0.89100652f, 0.45399050f}, {0.89687274f, 0.44228869f}, +{0.90258528f, 0.43051110f}, {0.90814317f, 0.41865974f}, +{0.91354546f, 0.40673664f}, {0.91879121f, 0.39474386f}, +{0.92387953f, 0.38268343f}, {0.92880955f, 0.37055744f}, +{0.93358043f, 0.35836795f}, {0.93819134f, 0.34611706f}, +{0.94264149f, 0.33380686f}, {0.94693013f, 0.32143947f}, +{0.95105652f, 0.30901699f}, {0.95501994f, 0.29654157f}, +{0.95881973f, 0.28401534f}, {0.96245524f, 0.27144045f}, +{0.96592583f, 0.25881905f}, {0.96923091f, 0.24615329f}, +{0.97236992f, 0.23344536f}, {0.97534232f, 0.22069744f}, +{0.97814760f, 0.20791169f}, {0.98078528f, 0.19509032f}, +{0.98325491f, 0.18223553f}, {0.98555606f, 0.16934950f}, +{0.98768834f, 0.15643447f}, {0.98965139f, 0.14349262f}, +{0.99144486f, 0.13052619f}, {0.99306846f, 0.11753740f}, +{0.99452190f, 0.10452846f}, {0.99580493f, 0.091501619f}, +{0.99691733f, 0.078459096f}, {0.99785892f, 0.065403129f}, +{0.99862953f, 0.052335956f}, {0.99922904f, 0.039259816f}, +{0.99965732f, 0.026176948f}, {0.99991433f, 0.013089596f}, +}; +#ifndef FFT_BITREV480 +#define FFT_BITREV480 +static const opus_int16 fft_bitrev480[480] = { +0, 120, 240, 360, 30, 150, 270, 390, 60, 180, 300, 420, 90, 210, 330, +450, 15, 135, 255, 375, 45, 165, 285, 405, 75, 195, 315, 435, 105, 225, +345, 465, 5, 125, 245, 365, 35, 155, 275, 395, 65, 185, 305, 425, 95, +215, 335, 455, 20, 140, 260, 380, 50, 170, 290, 410, 80, 200, 320, 440, +110, 230, 350, 470, 10, 130, 250, 370, 40, 160, 280, 400, 70, 190, 310, +430, 100, 220, 340, 460, 25, 145, 265, 385, 55, 175, 295, 415, 85, 205, +325, 445, 115, 235, 355, 475, 1, 121, 241, 361, 31, 151, 271, 391, 61, +181, 301, 421, 91, 211, 331, 451, 16, 136, 256, 376, 46, 166, 286, 406, +76, 196, 316, 436, 106, 226, 346, 466, 6, 126, 246, 366, 36, 156, 276, +396, 66, 186, 306, 426, 96, 216, 336, 456, 21, 141, 261, 381, 51, 171, +291, 411, 81, 201, 321, 441, 111, 231, 351, 471, 11, 131, 251, 371, 41, +161, 281, 401, 71, 191, 311, 431, 101, 221, 341, 461, 26, 146, 266, 386, +56, 176, 296, 416, 86, 206, 326, 446, 116, 236, 356, 476, 2, 122, 242, +362, 32, 152, 272, 392, 62, 182, 302, 422, 92, 212, 332, 452, 17, 137, +257, 377, 47, 167, 287, 407, 77, 197, 317, 437, 107, 227, 347, 467, 7, +127, 247, 367, 37, 157, 277, 397, 67, 187, 307, 427, 97, 217, 337, 457, +22, 142, 262, 382, 52, 172, 292, 412, 82, 202, 322, 442, 112, 232, 352, +472, 12, 132, 252, 372, 42, 162, 282, 402, 72, 192, 312, 432, 102, 222, +342, 462, 27, 147, 267, 387, 57, 177, 297, 417, 87, 207, 327, 447, 117, +237, 357, 477, 3, 123, 243, 363, 33, 153, 273, 393, 63, 183, 303, 423, +93, 213, 333, 453, 18, 138, 258, 378, 48, 168, 288, 408, 78, 198, 318, +438, 108, 228, 348, 468, 8, 128, 248, 368, 38, 158, 278, 398, 68, 188, +308, 428, 98, 218, 338, 458, 23, 143, 263, 383, 53, 173, 293, 413, 83, +203, 323, 443, 113, 233, 353, 473, 13, 133, 253, 373, 43, 163, 283, 403, +73, 193, 313, 433, 103, 223, 343, 463, 28, 148, 268, 388, 58, 178, 298, +418, 88, 208, 328, 448, 118, 238, 358, 478, 4, 124, 244, 364, 34, 154, +274, 394, 64, 184, 304, 424, 94, 214, 334, 454, 19, 139, 259, 379, 49, +169, 289, 409, 79, 199, 319, 439, 109, 229, 349, 469, 9, 129, 249, 369, +39, 159, 279, 399, 69, 189, 309, 429, 99, 219, 339, 459, 24, 144, 264, +384, 54, 174, 294, 414, 84, 204, 324, 444, 114, 234, 354, 474, 14, 134, +254, 374, 44, 164, 284, 404, 74, 194, 314, 434, 104, 224, 344, 464, 29, +149, 269, 389, 59, 179, 299, 419, 89, 209, 329, 449, 119, 239, 359, 479, +}; +#endif + +#ifndef FFT_BITREV240 +#define FFT_BITREV240 +static const opus_int16 fft_bitrev240[240] = { +0, 60, 120, 180, 15, 75, 135, 195, 30, 90, 150, 210, 45, 105, 165, +225, 5, 65, 125, 185, 20, 80, 140, 200, 35, 95, 155, 215, 50, 110, +170, 230, 10, 70, 130, 190, 25, 85, 145, 205, 40, 100, 160, 220, 55, +115, 175, 235, 1, 61, 121, 181, 16, 76, 136, 196, 31, 91, 151, 211, +46, 106, 166, 226, 6, 66, 126, 186, 21, 81, 141, 201, 36, 96, 156, +216, 51, 111, 171, 231, 11, 71, 131, 191, 26, 86, 146, 206, 41, 101, +161, 221, 56, 116, 176, 236, 2, 62, 122, 182, 17, 77, 137, 197, 32, +92, 152, 212, 47, 107, 167, 227, 7, 67, 127, 187, 22, 82, 142, 202, +37, 97, 157, 217, 52, 112, 172, 232, 12, 72, 132, 192, 27, 87, 147, +207, 42, 102, 162, 222, 57, 117, 177, 237, 3, 63, 123, 183, 18, 78, +138, 198, 33, 93, 153, 213, 48, 108, 168, 228, 8, 68, 128, 188, 23, +83, 143, 203, 38, 98, 158, 218, 53, 113, 173, 233, 13, 73, 133, 193, +28, 88, 148, 208, 43, 103, 163, 223, 58, 118, 178, 238, 4, 64, 124, +184, 19, 79, 139, 199, 34, 94, 154, 214, 49, 109, 169, 229, 9, 69, +129, 189, 24, 84, 144, 204, 39, 99, 159, 219, 54, 114, 174, 234, 14, +74, 134, 194, 29, 89, 149, 209, 44, 104, 164, 224, 59, 119, 179, 239, +}; +#endif + +#ifndef FFT_BITREV120 +#define FFT_BITREV120 +static const opus_int16 fft_bitrev120[120] = { +0, 30, 60, 90, 15, 45, 75, 105, 5, 35, 65, 95, 20, 50, 80, +110, 10, 40, 70, 100, 25, 55, 85, 115, 1, 31, 61, 91, 16, 46, +76, 106, 6, 36, 66, 96, 21, 51, 81, 111, 11, 41, 71, 101, 26, +56, 86, 116, 2, 32, 62, 92, 17, 47, 77, 107, 7, 37, 67, 97, +22, 52, 82, 112, 12, 42, 72, 102, 27, 57, 87, 117, 3, 33, 63, +93, 18, 48, 78, 108, 8, 38, 68, 98, 23, 53, 83, 113, 13, 43, +73, 103, 28, 58, 88, 118, 4, 34, 64, 94, 19, 49, 79, 109, 9, +39, 69, 99, 24, 54, 84, 114, 14, 44, 74, 104, 29, 59, 89, 119, +}; +#endif + +#ifndef FFT_BITREV60 +#define FFT_BITREV60 +static const opus_int16 fft_bitrev60[60] = { +0, 15, 30, 45, 5, 20, 35, 50, 10, 25, 40, 55, 1, 16, 31, +46, 6, 21, 36, 51, 11, 26, 41, 56, 2, 17, 32, 47, 7, 22, +37, 52, 12, 27, 42, 57, 3, 18, 33, 48, 8, 23, 38, 53, 13, +28, 43, 58, 4, 19, 34, 49, 9, 24, 39, 54, 14, 29, 44, 59, +}; +#endif + +#ifndef FFT_STATE48000_960_0 +#define FFT_STATE48000_960_0 +static const kiss_fft_state fft_state48000_960_0 = { +480, /* nfft */ +0.002083333f, /* scale */ +-1, /* shift */ +{4, 120, 4, 30, 2, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, }, /* factors */ +fft_bitrev480, /* bitrev */ +fft_twiddles48000_960, /* bitrev */ +}; +#endif + +#ifndef FFT_STATE48000_960_1 +#define FFT_STATE48000_960_1 +static const kiss_fft_state fft_state48000_960_1 = { +240, /* nfft */ +0.004166667f, /* scale */ +1, /* shift */ +{4, 60, 4, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */ +fft_bitrev240, /* bitrev */ +fft_twiddles48000_960, /* bitrev */ +}; +#endif + +#ifndef FFT_STATE48000_960_2 +#define FFT_STATE48000_960_2 +static const kiss_fft_state fft_state48000_960_2 = { +120, /* nfft */ +0.008333333f, /* scale */ +2, /* shift */ +{4, 30, 2, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */ +fft_bitrev120, /* bitrev */ +fft_twiddles48000_960, /* bitrev */ +}; +#endif + +#ifndef FFT_STATE48000_960_3 +#define FFT_STATE48000_960_3 +static const kiss_fft_state fft_state48000_960_3 = { +60, /* nfft */ +0.016666667f, /* scale */ +3, /* shift */ +{4, 15, 3, 5, 5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, /* factors */ +fft_bitrev60, /* bitrev */ +fft_twiddles48000_960, /* bitrev */ +}; +#endif + +#endif + +#ifndef MDCT_TWIDDLES960 +#define MDCT_TWIDDLES960 +static const opus_val16 mdct_twiddles960[481] = { +1.0000000f, 0.99999465f, 0.99997858f, 0.99995181f, 0.99991433f, +0.99986614f, 0.99980724f, 0.99973764f, 0.99965732f, 0.99956631f, +0.99946459f, 0.99935216f, 0.99922904f, 0.99909521f, 0.99895068f, +0.99879546f, 0.99862953f, 0.99845292f, 0.99826561f, 0.99806761f, +0.99785892f, 0.99763955f, 0.99740949f, 0.99716875f, 0.99691733f, +0.99665524f, 0.99638247f, 0.99609903f, 0.99580493f, 0.99550016f, +0.99518473f, 0.99485864f, 0.99452190f, 0.99417450f, 0.99381646f, +0.99344778f, 0.99306846f, 0.99267850f, 0.99227791f, 0.99186670f, +0.99144486f, 0.99101241f, 0.99056934f, 0.99011566f, 0.98965139f, +0.98917651f, 0.98869104f, 0.98819498f, 0.98768834f, 0.98717112f, +0.98664333f, 0.98610497f, 0.98555606f, 0.98499659f, 0.98442657f, +0.98384600f, 0.98325491f, 0.98265328f, 0.98204113f, 0.98141846f, +0.98078528f, 0.98014159f, 0.97948742f, 0.97882275f, 0.97814760f, +0.97746197f, 0.97676588f, 0.97605933f, 0.97534232f, 0.97461487f, +0.97387698f, 0.97312866f, 0.97236992f, 0.97160077f, 0.97082121f, +0.97003125f, 0.96923091f, 0.96842019f, 0.96759909f, 0.96676764f, +0.96592582f, 0.96507367f, 0.96421118f, 0.96333837f, 0.96245523f, +0.96156180f, 0.96065806f, 0.95974403f, 0.95881973f, 0.95788517f, +0.95694034f, 0.95598526f, 0.95501995f, 0.95404440f, 0.95305864f, +0.95206267f, 0.95105651f, 0.95004016f, 0.94901364f, 0.94797697f, +0.94693013f, 0.94587315f, 0.94480604f, 0.94372882f, 0.94264149f, +0.94154406f, 0.94043656f, 0.93931897f, 0.93819133f, 0.93705365f, +0.93590592f, 0.93474818f, 0.93358042f, 0.93240268f, 0.93121493f, +0.93001722f, 0.92880955f, 0.92759193f, 0.92636438f, 0.92512690f, +0.92387953f, 0.92262225f, 0.92135509f, 0.92007809f, 0.91879121f, +0.91749449f, 0.91618795f, 0.91487161f, 0.91354545f, 0.91220952f, +0.91086382f, 0.90950836f, 0.90814316f, 0.90676824f, 0.90538363f, +0.90398929f, 0.90258528f, 0.90117161f, 0.89974828f, 0.89831532f, +0.89687273f, 0.89542055f, 0.89395877f, 0.89248742f, 0.89100652f, +0.88951606f, 0.88801610f, 0.88650661f, 0.88498764f, 0.88345918f, +0.88192125f, 0.88037390f, 0.87881711f, 0.87725090f, 0.87567531f, +0.87409035f, 0.87249599f, 0.87089232f, 0.86927933f, 0.86765699f, +0.86602540f, 0.86438453f, 0.86273437f, 0.86107503f, 0.85940641f, +0.85772862f, 0.85604161f, 0.85434547f, 0.85264014f, 0.85092572f, +0.84920218f, 0.84746955f, 0.84572781f, 0.84397704f, 0.84221721f, +0.84044838f, 0.83867056f, 0.83688375f, 0.83508799f, 0.83328325f, +0.83146961f, 0.82964704f, 0.82781562f, 0.82597530f, 0.82412620f, +0.82226820f, 0.82040144f, 0.81852589f, 0.81664154f, 0.81474847f, +0.81284665f, 0.81093620f, 0.80901698f, 0.80708914f, 0.80515262f, +0.80320752f, 0.80125378f, 0.79929149f, 0.79732067f, 0.79534125f, +0.79335335f, 0.79135691f, 0.78935204f, 0.78733867f, 0.78531691f, +0.78328674f, 0.78124818f, 0.77920122f, 0.77714595f, 0.77508232f, +0.77301043f, 0.77093026f, 0.76884183f, 0.76674517f, 0.76464026f, +0.76252720f, 0.76040593f, 0.75827656f, 0.75613907f, 0.75399349f, +0.75183978f, 0.74967807f, 0.74750833f, 0.74533054f, 0.74314481f, +0.74095112f, 0.73874950f, 0.73653993f, 0.73432251f, 0.73209718f, +0.72986405f, 0.72762307f, 0.72537438f, 0.72311787f, 0.72085359f, +0.71858162f, 0.71630192f, 0.71401459f, 0.71171956f, 0.70941701f, +0.70710677f, 0.70478900f, 0.70246363f, 0.70013079f, 0.69779041f, +0.69544260f, 0.69308738f, 0.69072466f, 0.68835458f, 0.68597709f, +0.68359229f, 0.68120013f, 0.67880072f, 0.67639404f, 0.67398011f, +0.67155892f, 0.66913059f, 0.66669509f, 0.66425240f, 0.66180265f, +0.65934581f, 0.65688191f, 0.65441092f, 0.65193298f, 0.64944801f, +0.64695613f, 0.64445727f, 0.64195160f, 0.63943902f, 0.63691954f, +0.63439328f, 0.63186019f, 0.62932037f, 0.62677377f, 0.62422055f, +0.62166055f, 0.61909394f, 0.61652065f, 0.61394081f, 0.61135435f, +0.60876139f, 0.60616195f, 0.60355593f, 0.60094349f, 0.59832457f, +0.59569929f, 0.59306758f, 0.59042957f, 0.58778523f, 0.58513460f, +0.58247766f, 0.57981452f, 0.57714518f, 0.57446961f, 0.57178793f, +0.56910013f, 0.56640624f, 0.56370623f, 0.56100023f, 0.55828818f, +0.55557020f, 0.55284627f, 0.55011641f, 0.54738067f, 0.54463901f, +0.54189157f, 0.53913828f, 0.53637921f, 0.53361450f, 0.53084398f, +0.52806787f, 0.52528601f, 0.52249852f, 0.51970543f, 0.51690688f, +0.51410279f, 0.51129310f, 0.50847793f, 0.50565732f, 0.50283139f, +0.49999997f, 0.49716321f, 0.49432122f, 0.49147383f, 0.48862118f, +0.48576340f, 0.48290042f, 0.48003216f, 0.47715876f, 0.47428025f, +0.47139677f, 0.46850813f, 0.46561448f, 0.46271584f, 0.45981235f, +0.45690383f, 0.45399042f, 0.45107214f, 0.44814915f, 0.44522124f, +0.44228868f, 0.43935137f, 0.43640926f, 0.43346247f, 0.43051104f, +0.42755511f, 0.42459449f, 0.42162932f, 0.41865964f, 0.41568558f, +0.41270697f, 0.40972393f, 0.40673661f, 0.40374494f, 0.40074884f, +0.39774844f, 0.39474390f, 0.39173501f, 0.38872193f, 0.38570469f, +0.38268343f, 0.37965796f, 0.37662842f, 0.37359496f, 0.37055739f, +0.36751585f, 0.36447038f, 0.36142122f, 0.35836797f, 0.35531089f, +0.35225000f, 0.34918544f, 0.34611704f, 0.34304493f, 0.33996926f, +0.33688983f, 0.33380680f, 0.33072019f, 0.32763015f, 0.32453650f, +0.32143936f, 0.31833890f, 0.31523503f, 0.31212767f, 0.30901696f, +0.30590306f, 0.30278577f, 0.29966524f, 0.29654150f, 0.29341470f, +0.29028464f, 0.28715147f, 0.28401522f, 0.28087605f, 0.27773376f, +0.27458861f, 0.27144052f, 0.26828940f, 0.26513541f, 0.26197859f, +0.25881907f, 0.25565666f, 0.25249152f, 0.24932367f, 0.24615327f, +0.24298012f, 0.23980436f, 0.23662604f, 0.23344530f, 0.23026206f, +0.22707623f, 0.22388809f, 0.22069744f, 0.21750443f, 0.21430908f, +0.21111156f, 0.20791165f, 0.20470953f, 0.20150520f, 0.19829884f, +0.19509024f, 0.19187955f, 0.18866692f, 0.18545227f, 0.18223552f, +0.17901681f, 0.17579631f, 0.17257380f, 0.16934945f, 0.16612328f, +0.16289546f, 0.15966577f, 0.15643437f, 0.15320141f, 0.14996669f, +0.14673037f, 0.14349260f, 0.14025329f, 0.13701235f, 0.13376995f, +0.13052612f, 0.12728101f, 0.12403442f, 0.12078650f, 0.11753740f, +0.11428693f, 0.11103523f, 0.10778234f, 0.10452842f, 0.10127326f, +0.098017137f, 0.094759842f, 0.091501652f, 0.088242363f, 0.084982129f, +0.081721103f, 0.078459084f, 0.075196224f, 0.071932560f, 0.068668243f, +0.065403073f, 0.062137201f, 0.058870665f, 0.055603617f, 0.052335974f, +0.049067651f, 0.045798921f, 0.042529582f, 0.039259788f, 0.035989573f, +0.032719092f, 0.029448142f, 0.026176876f, 0.022905329f, 0.019633657f, +0.016361655f, 0.013089478f, 0.0098171604f, 0.0065449764f, 0.0032724839f, +-4.3711390e-08f, }; +#endif + +static const CELTMode mode48000_960_120 = { +48000, /* Fs */ +120, /* overlap */ +21, /* nbEBands */ +21, /* effEBands */ +{0.85000610f, 0.0000000f, 1.0000000f, 1.0000000f, }, /* preemph */ +eband5ms, /* eBands */ +3, /* maxLM */ +8, /* nbShortMdcts */ +120, /* shortMdctSize */ +11, /* nbAllocVectors */ +band_allocation, /* allocVectors */ +logN400, /* logN */ +window120, /* window */ +{1920, 3, {&fft_state48000_960_0, &fft_state48000_960_1, &fft_state48000_960_2, &fft_state48000_960_3, }, mdct_twiddles960}, /* mdct */ +{392, cache_index50, cache_bits50, cache_caps50}, /* cache */ +}; + +/* List of all the available modes */ +#define TOTAL_MODES 1 +static const CELTMode * const static_mode_list[TOTAL_MODES] = { +&mode48000_960_120, +}; diff --git a/src/opus-1.1/celt/vq.c b/src/opus-1.1/celt/vq.c new file mode 100644 index 00000000..98a0f36c --- /dev/null +++ b/src/opus-1.1/celt/vq.c @@ -0,0 +1,415 @@ +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation + Written by Jean-Marc Valin */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "mathops.h" +#include "cwrs.h" +#include "vq.h" +#include "arch.h" +#include "os_support.h" +#include "bands.h" +#include "rate.h" + +static void exp_rotation1(celt_norm *X, int len, int stride, opus_val16 c, opus_val16 s) +{ + int i; + celt_norm *Xptr; + Xptr = X; + for (i=0;i=0;i--) + { + celt_norm x1, x2; + x1 = Xptr[0]; + x2 = Xptr[stride]; + Xptr[stride] = EXTRACT16(SHR32(MULT16_16(c,x2) + MULT16_16(s,x1), 15)); + *Xptr-- = EXTRACT16(SHR32(MULT16_16(c,x1) - MULT16_16(s,x2), 15)); + } +} + +static void exp_rotation(celt_norm *X, int len, int dir, int stride, int K, int spread) +{ + static const int SPREAD_FACTOR[3]={15,10,5}; + int i; + opus_val16 c, s; + opus_val16 gain, theta; + int stride2=0; + int factor; + + if (2*K>=len || spread==SPREAD_NONE) + return; + factor = SPREAD_FACTOR[spread-1]; + + gain = celt_div((opus_val32)MULT16_16(Q15_ONE,len),(opus_val32)(len+factor*K)); + theta = HALF16(MULT16_16_Q15(gain,gain)); + + c = celt_cos_norm(EXTEND32(theta)); + s = celt_cos_norm(EXTEND32(SUB16(Q15ONE,theta))); /* sin(theta) */ + + if (len>=8*stride) + { + stride2 = 1; + /* This is just a simple (equivalent) way of computing sqrt(len/stride) with rounding. + It's basically incrementing long as (stride2+0.5)^2 < len/stride. */ + while ((stride2*stride2+stride2)*stride + (stride>>2) < len) + stride2++; + } + /*NOTE: As a minor optimization, we could be passing around log2(B), not B, for both this and for + extract_collapse_mask().*/ + len /= stride; + for (i=0;i>1; +#endif + t = VSHR32(Ryy, 2*(k-7)); + g = MULT16_16_P15(celt_rsqrt_norm(t),gain); + + i=0; + do + X[i] = EXTRACT16(PSHR32(MULT16_16(g, iy[i]), k+1)); + while (++i < N); +} + +static unsigned extract_collapse_mask(int *iy, int N, int B) +{ + unsigned collapse_mask; + int N0; + int i; + if (B<=1) + return 1; + /*NOTE: As a minor optimization, we could be passing around log2(B), not B, for both this and for + exp_rotation().*/ + N0 = N/B; + collapse_mask = 0; + i=0; do { + int j; + j=0; do { + collapse_mask |= (iy[i*N0+j]!=0)<0, "alg_quant() needs at least one pulse"); + celt_assert2(N>1, "alg_quant() needs at least two dimensions"); + + ALLOC(y, N, celt_norm); + ALLOC(iy, N, int); + ALLOC(signx, N, opus_val16); + + exp_rotation(X, N, 1, B, K, spread); + + /* Get rid of the sign */ + sum = 0; + j=0; do { + if (X[j]>0) + signx[j]=1; + else { + signx[j]=-1; + X[j]=-X[j]; + } + iy[j] = 0; + y[j] = 0; + } while (++j (N>>1)) + { + opus_val16 rcp; + j=0; do { + sum += X[j]; + } while (++j EPSILON && sum < 64)) +#endif + { + X[0] = QCONST16(1.f,14); + j=1; do + X[j]=0; + while (++j=1, "Allocated too many pulses in the quick pass"); + + /* This should never happen, but just in case it does (e.g. on silence) + we fill the first bin with pulses. */ +#ifdef FIXED_POINT_DEBUG + celt_assert2(pulsesLeft<=N+3, "Not enough pulses in the quick pass"); +#endif + if (pulsesLeft > N+3) + { + opus_val16 tmp = (opus_val16)pulsesLeft; + yy = MAC16_16(yy, tmp, tmp); + yy = MAC16_16(yy, tmp, y[0]); + iy[0] += pulsesLeft; + pulsesLeft=0; + } + + s = 1; + for (i=0;i= best_num/best_den, but that way + we can do it without any division */ + /* OPT: Make sure to use conditional moves here */ + if (MULT16_16(best_den, Rxy) > MULT16_16(Ryy, best_num)) + { + best_den = Ryy; + best_num = Rxy; + best_id = j; + } + } while (++j0, "alg_unquant() needs at least one pulse"); + celt_assert2(N>1, "alg_unquant() needs at least two dimensions"); + ALLOC(iy, N, int); + decode_pulses(iy, N, K, dec); + Ryy = 0; + i=0; + do { + Ryy = MAC16_16(Ryy, iy[i], iy[i]); + } while (++i < N); + normalise_residual(iy, X, N, Ryy, gain); + exp_rotation(X, N, -1, B, K, spread); + collapse_mask = extract_collapse_mask(iy, N, B); + RESTORE_STACK; + return collapse_mask; +} + +void renormalise_vector(celt_norm *X, int N, opus_val16 gain) +{ + int i; +#ifdef FIXED_POINT + int k; +#endif + opus_val32 E = EPSILON; + opus_val16 g; + opus_val32 t; + celt_norm *xptr = X; + for (i=0;i>1; +#endif + t = VSHR32(E, 2*(k-7)); + g = MULT16_16_P15(celt_rsqrt_norm(t),gain); + + xptr = X; + for (i=0;i +#include "arch.h" + +#define OVERRIDE_XCORR_KERNEL +static OPUS_INLINE void xcorr_kernel(const opus_val16 *x, const opus_val16 *y, opus_val32 sum[4], int len) +{ + int j; + __m128 xsum1, xsum2; + xsum1 = _mm_loadu_ps(sum); + xsum2 = _mm_setzero_ps(); + + for (j = 0; j < len-3; j += 4) + { + __m128 x0 = _mm_loadu_ps(x+j); + __m128 yj = _mm_loadu_ps(y+j); + __m128 y3 = _mm_loadu_ps(y+j+3); + + xsum1 = _mm_add_ps(xsum1,_mm_mul_ps(_mm_shuffle_ps(x0,x0,0x00),yj)); + xsum2 = _mm_add_ps(xsum2,_mm_mul_ps(_mm_shuffle_ps(x0,x0,0x55), + _mm_shuffle_ps(yj,y3,0x49))); + xsum1 = _mm_add_ps(xsum1,_mm_mul_ps(_mm_shuffle_ps(x0,x0,0xaa), + _mm_shuffle_ps(yj,y3,0x9e))); + xsum2 = _mm_add_ps(xsum2,_mm_mul_ps(_mm_shuffle_ps(x0,x0,0xff),y3)); + } + if (j < len) + { + xsum1 = _mm_add_ps(xsum1,_mm_mul_ps(_mm_load1_ps(x+j),_mm_loadu_ps(y+j))); + if (++j < len) + { + xsum2 = _mm_add_ps(xsum2,_mm_mul_ps(_mm_load1_ps(x+j),_mm_loadu_ps(y+j))); + if (++j < len) + { + xsum1 = _mm_add_ps(xsum1,_mm_mul_ps(_mm_load1_ps(x+j),_mm_loadu_ps(y+j))); + } + } + } + _mm_storeu_ps(sum,_mm_add_ps(xsum1,xsum2)); +} + +#define OVERRIDE_DUAL_INNER_PROD +static OPUS_INLINE void dual_inner_prod(const opus_val16 *x, const opus_val16 *y01, const opus_val16 *y02, + int N, opus_val32 *xy1, opus_val32 *xy2) +{ + int i; + __m128 xsum1, xsum2; + xsum1 = _mm_setzero_ps(); + xsum2 = _mm_setzero_ps(); + for (i=0;i + *
  • audio_frame is the audio data in opus_int16 (or float for opus_encode_float())
  • + *
  • frame_size is the duration of the frame in samples (per channel)
  • + *
  • packet is the byte array to which the compressed data is written
  • + *
  • max_packet is the maximum number of bytes that can be written in the packet (4000 bytes is recommended). + * Do not use max_packet to control VBR target bitrate, instead use the #OPUS_SET_BITRATE CTL.
  • + * + * + * opus_encode() and opus_encode_float() return the number of bytes actually written to the packet. + * The return value can be negative, which indicates that an error has occurred. If the return value + * is 1 byte, then the packet does not need to be transmitted (DTX). + * + * Once the encoder state if no longer needed, it can be destroyed with + * + * @code + * opus_encoder_destroy(enc); + * @endcode + * + * If the encoder was created with opus_encoder_init() rather than opus_encoder_create(), + * then no action is required aside from potentially freeing the memory that was manually + * allocated for it (calling free(enc) for the example above) + * + */ + +/** Opus encoder state. + * This contains the complete state of an Opus encoder. + * It is position independent and can be freely copied. + * @see opus_encoder_create,opus_encoder_init + */ +typedef struct OpusEncoder OpusEncoder; + +/** Gets the size of an OpusEncoder structure. + * @param[in] channels int: Number of channels. + * This must be 1 or 2. + * @returns The size in bytes. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_encoder_get_size(int channels); + +/** + */ + +/** Allocates and initializes an encoder state. + * There are three coding modes: + * + * @ref OPUS_APPLICATION_VOIP gives best quality at a given bitrate for voice + * signals. It enhances the input signal by high-pass filtering and + * emphasizing formants and harmonics. Optionally it includes in-band + * forward error correction to protect against packet loss. Use this + * mode for typical VoIP applications. Because of the enhancement, + * even at high bitrates the output may sound different from the input. + * + * @ref OPUS_APPLICATION_AUDIO gives best quality at a given bitrate for most + * non-voice signals like music. Use this mode for music and mixed + * (music/voice) content, broadcast, and applications requiring less + * than 15 ms of coding delay. + * + * @ref OPUS_APPLICATION_RESTRICTED_LOWDELAY configures low-delay mode that + * disables the speech-optimized mode in exchange for slightly reduced delay. + * This mode can only be set on an newly initialized or freshly reset encoder + * because it changes the codec delay. + * + * This is useful when the caller knows that the speech-optimized modes will not be needed (use with caution). + * @param [in] Fs opus_int32: Sampling rate of input signal (Hz) + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param [in] channels int: Number of channels (1 or 2) in input signal + * @param [in] application int: Coding mode (@ref OPUS_APPLICATION_VOIP/@ref OPUS_APPLICATION_AUDIO/@ref OPUS_APPLICATION_RESTRICTED_LOWDELAY) + * @param [out] error int*: @ref opus_errorcodes + * @note Regardless of the sampling rate and number channels selected, the Opus encoder + * can switch to a lower audio bandwidth or number of channels if the bitrate + * selected is too low. This also means that it is safe to always use 48 kHz stereo input + * and let the encoder optimize the encoding. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusEncoder *opus_encoder_create( + opus_int32 Fs, + int channels, + int application, + int *error +); + +/** Initializes a previously allocated encoder state + * The memory pointed to by st must be at least the size returned by opus_encoder_get_size(). + * This is intended for applications which use their own allocator instead of malloc. + * @see opus_encoder_create(),opus_encoder_get_size() + * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. + * @param [in] st OpusEncoder*: Encoder state + * @param [in] Fs opus_int32: Sampling rate of input signal (Hz) + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param [in] channels int: Number of channels (1 or 2) in input signal + * @param [in] application int: Coding mode (OPUS_APPLICATION_VOIP/OPUS_APPLICATION_AUDIO/OPUS_APPLICATION_RESTRICTED_LOWDELAY) + * @retval #OPUS_OK Success or @ref opus_errorcodes + */ +OPUS_EXPORT int opus_encoder_init( + OpusEncoder *st, + opus_int32 Fs, + int channels, + int application +) OPUS_ARG_NONNULL(1); + +/** Encodes an Opus frame. + * @param [in] st OpusEncoder*: Encoder state + * @param [in] pcm opus_int16*: Input signal (interleaved if 2 channels). length is frame_size*channels*sizeof(opus_int16) + * @param [in] frame_size int: Number of samples per channel in the + * input signal. + * This must be an Opus frame size for + * the encoder's sampling rate. + * For example, at 48 kHz the permitted + * values are 120, 240, 480, 960, 1920, + * and 2880. + * Passing in a duration of less than + * 10 ms (480 samples at 48 kHz) will + * prevent the encoder from using the LPC + * or hybrid modes. + * @param [out] data unsigned char*: Output payload. + * This must contain storage for at + * least \a max_data_bytes. + * @param [in] max_data_bytes opus_int32: Size of the allocated + * memory for the output + * payload. This may be + * used to impose an upper limit on + * the instant bitrate, but should + * not be used as the only bitrate + * control. Use #OPUS_SET_BITRATE to + * control the bitrate. + * @returns The length of the encoded packet (in bytes) on success or a + * negative error code (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode( + OpusEncoder *st, + const opus_int16 *pcm, + int frame_size, + unsigned char *data, + opus_int32 max_data_bytes +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); + +/** Encodes an Opus frame from floating point input. + * @param [in] st OpusEncoder*: Encoder state + * @param [in] pcm float*: Input in float format (interleaved if 2 channels), with a normal range of +/-1.0. + * Samples with a range beyond +/-1.0 are supported but will + * be clipped by decoders using the integer API and should + * only be used if it is known that the far end supports + * extended dynamic range. + * length is frame_size*channels*sizeof(float) + * @param [in] frame_size int: Number of samples per channel in the + * input signal. + * This must be an Opus frame size for + * the encoder's sampling rate. + * For example, at 48 kHz the permitted + * values are 120, 240, 480, 960, 1920, + * and 2880. + * Passing in a duration of less than + * 10 ms (480 samples at 48 kHz) will + * prevent the encoder from using the LPC + * or hybrid modes. + * @param [out] data unsigned char*: Output payload. + * This must contain storage for at + * least \a max_data_bytes. + * @param [in] max_data_bytes opus_int32: Size of the allocated + * memory for the output + * payload. This may be + * used to impose an upper limit on + * the instant bitrate, but should + * not be used as the only bitrate + * control. Use #OPUS_SET_BITRATE to + * control the bitrate. + * @returns The length of the encoded packet (in bytes) on success or a + * negative error code (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_encode_float( + OpusEncoder *st, + const float *pcm, + int frame_size, + unsigned char *data, + opus_int32 max_data_bytes +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); + +/** Frees an OpusEncoder allocated by opus_encoder_create(). + * @param[in] st OpusEncoder*: State to be freed. + */ +OPUS_EXPORT void opus_encoder_destroy(OpusEncoder *st); + +/** Perform a CTL function on an Opus encoder. + * + * Generally the request and subsequent arguments are generated + * by a convenience macro. + * @param st OpusEncoder*: Encoder state. + * @param request This and all remaining parameters should be replaced by one + * of the convenience macros in @ref opus_genericctls or + * @ref opus_encoderctls. + * @see opus_genericctls + * @see opus_encoderctls + */ +OPUS_EXPORT int opus_encoder_ctl(OpusEncoder *st, int request, ...) OPUS_ARG_NONNULL(1); +/**@}*/ + +/** @defgroup opus_decoder Opus Decoder + * @{ + * + * @brief This page describes the process and functions used to decode Opus. + * + * The decoding process also starts with creating a decoder + * state. This can be done with: + * @code + * int error; + * OpusDecoder *dec; + * dec = opus_decoder_create(Fs, channels, &error); + * @endcode + * where + * @li Fs is the sampling rate and must be 8000, 12000, 16000, 24000, or 48000 + * @li channels is the number of channels (1 or 2) + * @li error will hold the error code in case of failure (or #OPUS_OK on success) + * @li the return value is a newly created decoder state to be used for decoding + * + * While opus_decoder_create() allocates memory for the state, it's also possible + * to initialize pre-allocated memory: + * @code + * int size; + * int error; + * OpusDecoder *dec; + * size = opus_decoder_get_size(channels); + * dec = malloc(size); + * error = opus_decoder_init(dec, Fs, channels); + * @endcode + * where opus_decoder_get_size() returns the required size for the decoder state. Note that + * future versions of this code may change the size, so no assuptions should be made about it. + * + * The decoder state is always continuous in memory and only a shallow copy is sufficient + * to copy it (e.g. memcpy()) + * + * To decode a frame, opus_decode() or opus_decode_float() must be called with a packet of compressed audio data: + * @code + * frame_size = opus_decode(dec, packet, len, decoded, max_size, 0); + * @endcode + * where + * + * @li packet is the byte array containing the compressed data + * @li len is the exact number of bytes contained in the packet + * @li decoded is the decoded audio data in opus_int16 (or float for opus_decode_float()) + * @li max_size is the max duration of the frame in samples (per channel) that can fit into the decoded_frame array + * + * opus_decode() and opus_decode_float() return the number of samples (per channel) decoded from the packet. + * If that value is negative, then an error has occurred. This can occur if the packet is corrupted or if the audio + * buffer is too small to hold the decoded audio. + * + * Opus is a stateful codec with overlapping blocks and as a result Opus + * packets are not coded independently of each other. Packets must be + * passed into the decoder serially and in the correct order for a correct + * decode. Lost packets can be replaced with loss concealment by calling + * the decoder with a null pointer and zero length for the missing packet. + * + * A single codec state may only be accessed from a single thread at + * a time and any required locking must be performed by the caller. Separate + * streams must be decoded with separate decoder states and can be decoded + * in parallel unless the library was compiled with NONTHREADSAFE_PSEUDOSTACK + * defined. + * + */ + +/** Opus decoder state. + * This contains the complete state of an Opus decoder. + * It is position independent and can be freely copied. + * @see opus_decoder_create,opus_decoder_init + */ +typedef struct OpusDecoder OpusDecoder; + +/** Gets the size of an OpusDecoder structure. + * @param [in] channels int: Number of channels. + * This must be 1 or 2. + * @returns The size in bytes. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decoder_get_size(int channels); + +/** Allocates and initializes a decoder state. + * @param [in] Fs opus_int32: Sample rate to decode at (Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param [in] channels int: Number of channels (1 or 2) to decode + * @param [out] error int*: #OPUS_OK Success or @ref opus_errorcodes + * + * Internally Opus stores data at 48000 Hz, so that should be the default + * value for Fs. However, the decoder can efficiently decode to buffers + * at 8, 12, 16, and 24 kHz so if for some reason the caller cannot use + * data at the full sample rate, or knows the compressed data doesn't + * use the full frequency range, it can request decoding at a reduced + * rate. Likewise, the decoder is capable of filling in either mono or + * interleaved stereo pcm buffers, at the caller's request. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusDecoder *opus_decoder_create( + opus_int32 Fs, + int channels, + int *error +); + +/** Initializes a previously allocated decoder state. + * The state must be at least the size returned by opus_decoder_get_size(). + * This is intended for applications which use their own allocator instead of malloc. @see opus_decoder_create,opus_decoder_get_size + * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. + * @param [in] st OpusDecoder*: Decoder state. + * @param [in] Fs opus_int32: Sampling rate to decode to (Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param [in] channels int: Number of channels (1 or 2) to decode + * @retval #OPUS_OK Success or @ref opus_errorcodes + */ +OPUS_EXPORT int opus_decoder_init( + OpusDecoder *st, + opus_int32 Fs, + int channels +) OPUS_ARG_NONNULL(1); + +/** Decode an Opus packet. + * @param [in] st OpusDecoder*: Decoder state + * @param [in] data char*: Input payload. Use a NULL pointer to indicate packet loss + * @param [in] len opus_int32: Number of bytes in payload* + * @param [out] pcm opus_int16*: Output signal (interleaved if 2 channels). length + * is frame_size*channels*sizeof(opus_int16) + * @param [in] frame_size Number of samples per channel of available space in \a pcm. + * If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will + * not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=1), + * then frame_size needs to be exactly the duration of audio that is missing, otherwise the + * decoder will not be in the optimal state to decode the next incoming packet. For the PLC and + * FEC cases, frame_size must be a multiple of 2.5 ms. + * @param [in] decode_fec int: Flag (0 or 1) to request that any in-band forward error correction data be + * decoded. If no such data is available, the frame is decoded as if it were lost. + * @returns Number of decoded samples or @ref opus_errorcodes + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decode( + OpusDecoder *st, + const unsigned char *data, + opus_int32 len, + opus_int16 *pcm, + int frame_size, + int decode_fec +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + +/** Decode an Opus packet with floating point output. + * @param [in] st OpusDecoder*: Decoder state + * @param [in] data char*: Input payload. Use a NULL pointer to indicate packet loss + * @param [in] len opus_int32: Number of bytes in payload + * @param [out] pcm float*: Output signal (interleaved if 2 channels). length + * is frame_size*channels*sizeof(float) + * @param [in] frame_size Number of samples per channel of available space in \a pcm. + * If this is less than the maximum packet duration (120ms; 5760 for 48kHz), this function will + * not be capable of decoding some packets. In the case of PLC (data==NULL) or FEC (decode_fec=1), + * then frame_size needs to be exactly the duration of audio that is missing, otherwise the + * decoder will not be in the optimal state to decode the next incoming packet. For the PLC and + * FEC cases, frame_size must be a multiple of 2.5 ms. + * @param [in] decode_fec int: Flag (0 or 1) to request that any in-band forward error correction data be + * decoded. If no such data is available the frame is decoded as if it were lost. + * @returns Number of decoded samples or @ref opus_errorcodes + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decode_float( + OpusDecoder *st, + const unsigned char *data, + opus_int32 len, + float *pcm, + int frame_size, + int decode_fec +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + +/** Perform a CTL function on an Opus decoder. + * + * Generally the request and subsequent arguments are generated + * by a convenience macro. + * @param st OpusDecoder*: Decoder state. + * @param request This and all remaining parameters should be replaced by one + * of the convenience macros in @ref opus_genericctls or + * @ref opus_decoderctls. + * @see opus_genericctls + * @see opus_decoderctls + */ +OPUS_EXPORT int opus_decoder_ctl(OpusDecoder *st, int request, ...) OPUS_ARG_NONNULL(1); + +/** Frees an OpusDecoder allocated by opus_decoder_create(). + * @param[in] st OpusDecoder*: State to be freed. + */ +OPUS_EXPORT void opus_decoder_destroy(OpusDecoder *st); + +/** Parse an opus packet into one or more frames. + * Opus_decode will perform this operation internally so most applications do + * not need to use this function. + * This function does not copy the frames, the returned pointers are pointers into + * the input packet. + * @param [in] data char*: Opus packet to be parsed + * @param [in] len opus_int32: size of data + * @param [out] out_toc char*: TOC pointer + * @param [out] frames char*[48] encapsulated frames + * @param [out] size opus_int16[48] sizes of the encapsulated frames + * @param [out] payload_offset int*: returns the position of the payload within the packet (in bytes) + * @returns number of frames + */ +OPUS_EXPORT int opus_packet_parse( + const unsigned char *data, + opus_int32 len, + unsigned char *out_toc, + const unsigned char *frames[48], + opus_int16 size[48], + int *payload_offset +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + +/** Gets the bandwidth of an Opus packet. + * @param [in] data char*: Opus packet + * @retval OPUS_BANDWIDTH_NARROWBAND Narrowband (4kHz bandpass) + * @retval OPUS_BANDWIDTH_MEDIUMBAND Mediumband (6kHz bandpass) + * @retval OPUS_BANDWIDTH_WIDEBAND Wideband (8kHz bandpass) + * @retval OPUS_BANDWIDTH_SUPERWIDEBAND Superwideband (12kHz bandpass) + * @retval OPUS_BANDWIDTH_FULLBAND Fullband (20kHz bandpass) + * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_bandwidth(const unsigned char *data) OPUS_ARG_NONNULL(1); + +/** Gets the number of samples per frame from an Opus packet. + * @param [in] data char*: Opus packet. + * This must contain at least one byte of + * data. + * @param [in] Fs opus_int32: Sampling rate in Hz. + * This must be a multiple of 400, or + * inaccurate results will be returned. + * @returns Number of samples per frame. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_samples_per_frame(const unsigned char *data, opus_int32 Fs) OPUS_ARG_NONNULL(1); + +/** Gets the number of channels from an Opus packet. + * @param [in] data char*: Opus packet + * @returns Number of channels + * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_channels(const unsigned char *data) OPUS_ARG_NONNULL(1); + +/** Gets the number of frames in an Opus packet. + * @param [in] packet char*: Opus packet + * @param [in] len opus_int32: Length of packet + * @returns Number of frames + * @retval OPUS_BAD_ARG Insufficient data was passed to the function + * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_frames(const unsigned char packet[], opus_int32 len) OPUS_ARG_NONNULL(1); + +/** Gets the number of samples of an Opus packet. + * @param [in] packet char*: Opus packet + * @param [in] len opus_int32: Length of packet + * @param [in] Fs opus_int32: Sampling rate in Hz. + * This must be a multiple of 400, or + * inaccurate results will be returned. + * @returns Number of samples + * @retval OPUS_BAD_ARG Insufficient data was passed to the function + * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_packet_get_nb_samples(const unsigned char packet[], opus_int32 len, opus_int32 Fs) OPUS_ARG_NONNULL(1); + +/** Gets the number of samples of an Opus packet. + * @param [in] dec OpusDecoder*: Decoder state + * @param [in] packet char*: Opus packet + * @param [in] len opus_int32: Length of packet + * @returns Number of samples + * @retval OPUS_BAD_ARG Insufficient data was passed to the function + * @retval OPUS_INVALID_PACKET The compressed data passed is corrupted or of an unsupported type + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_decoder_get_nb_samples(const OpusDecoder *dec, const unsigned char packet[], opus_int32 len) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2); + +/** Applies soft-clipping to bring a float signal within the [-1,1] range. If + * the signal is already in that range, nothing is done. If there are values + * outside of [-1,1], then the signal is clipped as smoothly as possible to + * both fit in the range and avoid creating excessive distortion in the + * process. + * @param [in,out] pcm float*: Input PCM and modified PCM + * @param [in] frame_size int Number of samples per channel to process + * @param [in] channels int: Number of channels + * @param [in,out] softclip_mem float*: State memory for the soft clipping process (one float per channel, initialized to zero) + */ +OPUS_EXPORT void opus_pcm_soft_clip(float *pcm, int frame_size, int channels, float *softclip_mem); + + +/**@}*/ + +/** @defgroup opus_repacketizer Repacketizer + * @{ + * + * The repacketizer can be used to merge multiple Opus packets into a single + * packet or alternatively to split Opus packets that have previously been + * merged. Splitting valid Opus packets is always guaranteed to succeed, + * whereas merging valid packets only succeeds if all frames have the same + * mode, bandwidth, and frame size, and when the total duration of the merged + * packet is no more than 120 ms. + * The repacketizer currently only operates on elementary Opus + * streams. It will not manipualte multistream packets successfully, except in + * the degenerate case where they consist of data from a single stream. + * + * The repacketizing process starts with creating a repacketizer state, either + * by calling opus_repacketizer_create() or by allocating the memory yourself, + * e.g., + * @code + * OpusRepacketizer *rp; + * rp = (OpusRepacketizer*)malloc(opus_repacketizer_get_size()); + * if (rp != NULL) + * opus_repacketizer_init(rp); + * @endcode + * + * Then the application should submit packets with opus_repacketizer_cat(), + * extract new packets with opus_repacketizer_out() or + * opus_repacketizer_out_range(), and then reset the state for the next set of + * input packets via opus_repacketizer_init(). + * + * For example, to split a sequence of packets into individual frames: + * @code + * unsigned char *data; + * int len; + * while (get_next_packet(&data, &len)) + * { + * unsigned char out[1276]; + * opus_int32 out_len; + * int nb_frames; + * int err; + * int i; + * err = opus_repacketizer_cat(rp, data, len); + * if (err != OPUS_OK) + * { + * release_packet(data); + * return err; + * } + * nb_frames = opus_repacketizer_get_nb_frames(rp); + * for (i = 0; i < nb_frames; i++) + * { + * out_len = opus_repacketizer_out_range(rp, i, i+1, out, sizeof(out)); + * if (out_len < 0) + * { + * release_packet(data); + * return (int)out_len; + * } + * output_next_packet(out, out_len); + * } + * opus_repacketizer_init(rp); + * release_packet(data); + * } + * @endcode + * + * Alternatively, to combine a sequence of frames into packets that each + * contain up to TARGET_DURATION_MS milliseconds of data: + * @code + * // The maximum number of packets with duration TARGET_DURATION_MS occurs + * // when the frame size is 2.5 ms, for a total of (TARGET_DURATION_MS*2/5) + * // packets. + * unsigned char *data[(TARGET_DURATION_MS*2/5)+1]; + * opus_int32 len[(TARGET_DURATION_MS*2/5)+1]; + * int nb_packets; + * unsigned char out[1277*(TARGET_DURATION_MS*2/2)]; + * opus_int32 out_len; + * int prev_toc; + * nb_packets = 0; + * while (get_next_packet(data+nb_packets, len+nb_packets)) + * { + * int nb_frames; + * int err; + * nb_frames = opus_packet_get_nb_frames(data[nb_packets], len[nb_packets]); + * if (nb_frames < 1) + * { + * release_packets(data, nb_packets+1); + * return nb_frames; + * } + * nb_frames += opus_repacketizer_get_nb_frames(rp); + * // If adding the next packet would exceed our target, or it has an + * // incompatible TOC sequence, output the packets we already have before + * // submitting it. + * // N.B., The nb_packets > 0 check ensures we've submitted at least one + * // packet since the last call to opus_repacketizer_init(). Otherwise a + * // single packet longer than TARGET_DURATION_MS would cause us to try to + * // output an (invalid) empty packet. It also ensures that prev_toc has + * // been set to a valid value. Additionally, len[nb_packets] > 0 is + * // guaranteed by the call to opus_packet_get_nb_frames() above, so the + * // reference to data[nb_packets][0] should be valid. + * if (nb_packets > 0 && ( + * ((prev_toc & 0xFC) != (data[nb_packets][0] & 0xFC)) || + * opus_packet_get_samples_per_frame(data[nb_packets], 48000)*nb_frames > + * TARGET_DURATION_MS*48)) + * { + * out_len = opus_repacketizer_out(rp, out, sizeof(out)); + * if (out_len < 0) + * { + * release_packets(data, nb_packets+1); + * return (int)out_len; + * } + * output_next_packet(out, out_len); + * opus_repacketizer_init(rp); + * release_packets(data, nb_packets); + * data[0] = data[nb_packets]; + * len[0] = len[nb_packets]; + * nb_packets = 0; + * } + * err = opus_repacketizer_cat(rp, data[nb_packets], len[nb_packets]); + * if (err != OPUS_OK) + * { + * release_packets(data, nb_packets+1); + * return err; + * } + * prev_toc = data[nb_packets][0]; + * nb_packets++; + * } + * // Output the final, partial packet. + * if (nb_packets > 0) + * { + * out_len = opus_repacketizer_out(rp, out, sizeof(out)); + * release_packets(data, nb_packets); + * if (out_len < 0) + * return (int)out_len; + * output_next_packet(out, out_len); + * } + * @endcode + * + * An alternate way of merging packets is to simply call opus_repacketizer_cat() + * unconditionally until it fails. At that point, the merged packet can be + * obtained with opus_repacketizer_out() and the input packet for which + * opus_repacketizer_cat() needs to be re-added to a newly reinitialized + * repacketizer state. + */ + +typedef struct OpusRepacketizer OpusRepacketizer; + +/** Gets the size of an OpusRepacketizer structure. + * @returns The size in bytes. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_repacketizer_get_size(void); + +/** (Re)initializes a previously allocated repacketizer state. + * The state must be at least the size returned by opus_repacketizer_get_size(). + * This can be used for applications which use their own allocator instead of + * malloc(). + * It must also be called to reset the queue of packets waiting to be + * repacketized, which is necessary if the maximum packet duration of 120 ms + * is reached or if you wish to submit packets with a different Opus + * configuration (coding mode, audio bandwidth, frame size, or channel count). + * Failure to do so will prevent a new packet from being added with + * opus_repacketizer_cat(). + * @see opus_repacketizer_create + * @see opus_repacketizer_get_size + * @see opus_repacketizer_cat + * @param rp OpusRepacketizer*: The repacketizer state to + * (re)initialize. + * @returns A pointer to the same repacketizer state that was passed in. + */ +OPUS_EXPORT OpusRepacketizer *opus_repacketizer_init(OpusRepacketizer *rp) OPUS_ARG_NONNULL(1); + +/** Allocates memory and initializes the new repacketizer with + * opus_repacketizer_init(). + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusRepacketizer *opus_repacketizer_create(void); + +/** Frees an OpusRepacketizer allocated by + * opus_repacketizer_create(). + * @param[in] rp OpusRepacketizer*: State to be freed. + */ +OPUS_EXPORT void opus_repacketizer_destroy(OpusRepacketizer *rp); + +/** Add a packet to the current repacketizer state. + * This packet must match the configuration of any packets already submitted + * for repacketization since the last call to opus_repacketizer_init(). + * This means that it must have the same coding mode, audio bandwidth, frame + * size, and channel count. + * This can be checked in advance by examining the top 6 bits of the first + * byte of the packet, and ensuring they match the top 6 bits of the first + * byte of any previously submitted packet. + * The total duration of audio in the repacketizer state also must not exceed + * 120 ms, the maximum duration of a single packet, after adding this packet. + * + * The contents of the current repacketizer state can be extracted into new + * packets using opus_repacketizer_out() or opus_repacketizer_out_range(). + * + * In order to add a packet with a different configuration or to add more + * audio beyond 120 ms, you must clear the repacketizer state by calling + * opus_repacketizer_init(). + * If a packet is too large to add to the current repacketizer state, no part + * of it is added, even if it contains multiple frames, some of which might + * fit. + * If you wish to be able to add parts of such packets, you should first use + * another repacketizer to split the packet into pieces and add them + * individually. + * @see opus_repacketizer_out_range + * @see opus_repacketizer_out + * @see opus_repacketizer_init + * @param rp OpusRepacketizer*: The repacketizer state to which to + * add the packet. + * @param[in] data const unsigned char*: The packet data. + * The application must ensure + * this pointer remains valid + * until the next call to + * opus_repacketizer_init() or + * opus_repacketizer_destroy(). + * @param len opus_int32: The number of bytes in the packet data. + * @returns An error code indicating whether or not the operation succeeded. + * @retval #OPUS_OK The packet's contents have been added to the repacketizer + * state. + * @retval #OPUS_INVALID_PACKET The packet did not have a valid TOC sequence, + * the packet's TOC sequence was not compatible + * with previously submitted packets (because + * the coding mode, audio bandwidth, frame size, + * or channel count did not match), or adding + * this packet would increase the total amount of + * audio stored in the repacketizer state to more + * than 120 ms. + */ +OPUS_EXPORT int opus_repacketizer_cat(OpusRepacketizer *rp, const unsigned char *data, opus_int32 len) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2); + + +/** Construct a new packet from data previously submitted to the repacketizer + * state via opus_repacketizer_cat(). + * @param rp OpusRepacketizer*: The repacketizer state from which to + * construct the new packet. + * @param begin int: The index of the first frame in the current + * repacketizer state to include in the output. + * @param end int: One past the index of the last frame in the + * current repacketizer state to include in the + * output. + * @param[out] data const unsigned char*: The buffer in which to + * store the output packet. + * @param maxlen opus_int32: The maximum number of bytes to store in + * the output buffer. In order to guarantee + * success, this should be at least + * 1276 for a single frame, + * or for multiple frames, + * 1277*(end-begin). + * However, 1*(end-begin) plus + * the size of all packet data submitted to + * the repacketizer since the last call to + * opus_repacketizer_init() or + * opus_repacketizer_create() is also + * sufficient, and possibly much smaller. + * @returns The total size of the output packet on success, or an error code + * on failure. + * @retval #OPUS_BAD_ARG [begin,end) was an invalid range of + * frames (begin < 0, begin >= end, or end > + * opus_repacketizer_get_nb_frames()). + * @retval #OPUS_BUFFER_TOO_SMALL \a maxlen was insufficient to contain the + * complete output packet. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_repacketizer_out_range(OpusRepacketizer *rp, int begin, int end, unsigned char *data, opus_int32 maxlen) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + +/** Return the total number of frames contained in packet data submitted to + * the repacketizer state so far via opus_repacketizer_cat() since the last + * call to opus_repacketizer_init() or opus_repacketizer_create(). + * This defines the valid range of packets that can be extracted with + * opus_repacketizer_out_range() or opus_repacketizer_out(). + * @param rp OpusRepacketizer*: The repacketizer state containing the + * frames. + * @returns The total number of frames contained in the packet data submitted + * to the repacketizer state. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_repacketizer_get_nb_frames(OpusRepacketizer *rp) OPUS_ARG_NONNULL(1); + +/** Construct a new packet from data previously submitted to the repacketizer + * state via opus_repacketizer_cat(). + * This is a convenience routine that returns all the data submitted so far + * in a single packet. + * It is equivalent to calling + * @code + * opus_repacketizer_out_range(rp, 0, opus_repacketizer_get_nb_frames(rp), + * data, maxlen) + * @endcode + * @param rp OpusRepacketizer*: The repacketizer state from which to + * construct the new packet. + * @param[out] data const unsigned char*: The buffer in which to + * store the output packet. + * @param maxlen opus_int32: The maximum number of bytes to store in + * the output buffer. In order to guarantee + * success, this should be at least + * 1277*opus_repacketizer_get_nb_frames(rp). + * However, + * 1*opus_repacketizer_get_nb_frames(rp) + * plus the size of all packet data + * submitted to the repacketizer since the + * last call to opus_repacketizer_init() or + * opus_repacketizer_create() is also + * sufficient, and possibly much smaller. + * @returns The total size of the output packet on success, or an error code + * on failure. + * @retval #OPUS_BUFFER_TOO_SMALL \a maxlen was insufficient to contain the + * complete output packet. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_repacketizer_out(OpusRepacketizer *rp, unsigned char *data, opus_int32 maxlen) OPUS_ARG_NONNULL(1); + +/** Pads a given Opus packet to a larger size (possibly changing the TOC sequence). + * @param[in,out] data const unsigned char*: The buffer containing the + * packet to pad. + * @param len opus_int32: The size of the packet. + * This must be at least 1. + * @param new_len opus_int32: The desired size of the packet after padding. + * This must be at least as large as len. + * @returns an error code + * @retval #OPUS_OK \a on success. + * @retval #OPUS_BAD_ARG \a len was less than 1 or new_len was less than len. + * @retval #OPUS_INVALID_PACKET \a data did not contain a valid Opus packet. + */ +OPUS_EXPORT int opus_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len); + +/** Remove all padding from a given Opus packet and rewrite the TOC sequence to + * minimize space usage. + * @param[in,out] data const unsigned char*: The buffer containing the + * packet to strip. + * @param len opus_int32: The size of the packet. + * This must be at least 1. + * @returns The new size of the output packet on success, or an error code + * on failure. + * @retval #OPUS_BAD_ARG \a len was less than 1. + * @retval #OPUS_INVALID_PACKET \a data did not contain a valid Opus packet. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_packet_unpad(unsigned char *data, opus_int32 len); + +/** Pads a given Opus multi-stream packet to a larger size (possibly changing the TOC sequence). + * @param[in,out] data const unsigned char*: The buffer containing the + * packet to pad. + * @param len opus_int32: The size of the packet. + * This must be at least 1. + * @param new_len opus_int32: The desired size of the packet after padding. + * This must be at least 1. + * @param nb_streams opus_int32: The number of streams (not channels) in the packet. + * This must be at least as large as len. + * @returns an error code + * @retval #OPUS_OK \a on success. + * @retval #OPUS_BAD_ARG \a len was less than 1. + * @retval #OPUS_INVALID_PACKET \a data did not contain a valid Opus packet. + */ +OPUS_EXPORT int opus_multistream_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len, int nb_streams); + +/** Remove all padding from a given Opus multi-stream packet and rewrite the TOC sequence to + * minimize space usage. + * @param[in,out] data const unsigned char*: The buffer containing the + * packet to strip. + * @param len opus_int32: The size of the packet. + * This must be at least 1. + * @param nb_streams opus_int32: The number of streams (not channels) in the packet. + * This must be at least 1. + * @returns The new size of the output packet on success, or an error code + * on failure. + * @retval #OPUS_BAD_ARG \a len was less than 1 or new_len was less than len. + * @retval #OPUS_INVALID_PACKET \a data did not contain a valid Opus packet. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_packet_unpad(unsigned char *data, opus_int32 len, int nb_streams); + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* OPUS_H */ diff --git a/src/opus-1.1/include/opus_custom.h b/src/opus-1.1/include/opus_custom.h new file mode 100644 index 00000000..41f36bf2 --- /dev/null +++ b/src/opus-1.1/include/opus_custom.h @@ -0,0 +1,342 @@ +/* Copyright (c) 2007-2008 CSIRO + Copyright (c) 2007-2009 Xiph.Org Foundation + Copyright (c) 2008-2012 Gregory Maxwell + Written by Jean-Marc Valin and Gregory Maxwell */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/** + @file opus_custom.h + @brief Opus-Custom reference implementation API + */ + +#ifndef OPUS_CUSTOM_H +#define OPUS_CUSTOM_H + +#include "opus_defines.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef CUSTOM_MODES +# define OPUS_CUSTOM_EXPORT OPUS_EXPORT +# define OPUS_CUSTOM_EXPORT_STATIC OPUS_EXPORT +#else +# define OPUS_CUSTOM_EXPORT +# ifdef OPUS_BUILD +# define OPUS_CUSTOM_EXPORT_STATIC static OPUS_INLINE +# else +# define OPUS_CUSTOM_EXPORT_STATIC +# endif +#endif + +/** @defgroup opus_custom Opus Custom + * @{ + * Opus Custom is an optional part of the Opus specification and + * reference implementation which uses a distinct API from the regular + * API and supports frame sizes that are not normally supported.\ Use + * of Opus Custom is discouraged for all but very special applications + * for which a frame size different from 2.5, 5, 10, or 20 ms is needed + * (for either complexity or latency reasons) and where interoperability + * is less important. + * + * In addition to the interoperability limitations the use of Opus custom + * disables a substantial chunk of the codec and generally lowers the + * quality available at a given bitrate. Normally when an application needs + * a different frame size from the codec it should buffer to match the + * sizes but this adds a small amount of delay which may be important + * in some very low latency applications. Some transports (especially + * constant rate RF transports) may also work best with frames of + * particular durations. + * + * Libopus only supports custom modes if they are enabled at compile time. + * + * The Opus Custom API is similar to the regular API but the + * @ref opus_encoder_create and @ref opus_decoder_create calls take + * an additional mode parameter which is a structure produced by + * a call to @ref opus_custom_mode_create. Both the encoder and decoder + * must create a mode using the same sample rate (fs) and frame size + * (frame size) so these parameters must either be signaled out of band + * or fixed in a particular implementation. + * + * Similar to regular Opus the custom modes support on the fly frame size + * switching, but the sizes available depend on the particular frame size in + * use. For some initial frame sizes on a single on the fly size is available. + */ + +/** Contains the state of an encoder. One encoder state is needed + for each stream. It is initialized once at the beginning of the + stream. Do *not* re-initialize the state for every frame. + @brief Encoder state + */ +typedef struct OpusCustomEncoder OpusCustomEncoder; + +/** State of the decoder. One decoder state is needed for each stream. + It is initialized once at the beginning of the stream. Do *not* + re-initialize the state for every frame. + @brief Decoder state + */ +typedef struct OpusCustomDecoder OpusCustomDecoder; + +/** The mode contains all the information necessary to create an + encoder. Both the encoder and decoder need to be initialized + with exactly the same mode, otherwise the output will be + corrupted. + @brief Mode configuration + */ +typedef struct OpusCustomMode OpusCustomMode; + +/** Creates a new mode struct. This will be passed to an encoder or + * decoder. The mode MUST NOT BE DESTROYED until the encoders and + * decoders that use it are destroyed as well. + * @param [in] Fs int: Sampling rate (8000 to 96000 Hz) + * @param [in] frame_size int: Number of samples (per channel) to encode in each + * packet (64 - 1024, prime factorization must contain zero or more 2s, 3s, or 5s and no other primes) + * @param [out] error int*: Returned error code (if NULL, no error will be returned) + * @return A newly created mode + */ +OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomMode *opus_custom_mode_create(opus_int32 Fs, int frame_size, int *error); + +/** Destroys a mode struct. Only call this after all encoders and + * decoders using this mode are destroyed as well. + * @param [in] mode OpusCustomMode*: Mode to be freed. + */ +OPUS_CUSTOM_EXPORT void opus_custom_mode_destroy(OpusCustomMode *mode); + + +#if !defined(OPUS_BUILD) || defined(CELT_ENCODER_C) + +/* Encoder */ +/** Gets the size of an OpusCustomEncoder structure. + * @param [in] mode OpusCustomMode *: Mode configuration + * @param [in] channels int: Number of channels + * @returns size + */ +OPUS_CUSTOM_EXPORT_STATIC OPUS_WARN_UNUSED_RESULT int opus_custom_encoder_get_size( + const OpusCustomMode *mode, + int channels +) OPUS_ARG_NONNULL(1); + +# ifdef CUSTOM_MODES +/** Initializes a previously allocated encoder state + * The memory pointed to by st must be the size returned by opus_custom_encoder_get_size. + * This is intended for applications which use their own allocator instead of malloc. + * @see opus_custom_encoder_create(),opus_custom_encoder_get_size() + * To reset a previously initialized state use the OPUS_RESET_STATE CTL. + * @param [in] st OpusCustomEncoder*: Encoder state + * @param [in] mode OpusCustomMode *: Contains all the information about the characteristics of + * the stream (must be the same characteristics as used for the + * decoder) + * @param [in] channels int: Number of channels + * @return OPUS_OK Success or @ref opus_errorcodes + */ +OPUS_CUSTOM_EXPORT int opus_custom_encoder_init( + OpusCustomEncoder *st, + const OpusCustomMode *mode, + int channels +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2); +# endif +#endif + + +/** Creates a new encoder state. Each stream needs its own encoder + * state (can't be shared across simultaneous streams). + * @param [in] mode OpusCustomMode*: Contains all the information about the characteristics of + * the stream (must be the same characteristics as used for the + * decoder) + * @param [in] channels int: Number of channels + * @param [out] error int*: Returns an error code + * @return Newly created encoder state. +*/ +OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomEncoder *opus_custom_encoder_create( + const OpusCustomMode *mode, + int channels, + int *error +) OPUS_ARG_NONNULL(1); + + +/** Destroys a an encoder state. + * @param[in] st OpusCustomEncoder*: State to be freed. + */ +OPUS_CUSTOM_EXPORT void opus_custom_encoder_destroy(OpusCustomEncoder *st); + +/** Encodes a frame of audio. + * @param [in] st OpusCustomEncoder*: Encoder state + * @param [in] pcm float*: PCM audio in float format, with a normal range of +/-1.0. + * Samples with a range beyond +/-1.0 are supported but will + * be clipped by decoders using the integer API and should + * only be used if it is known that the far end supports + * extended dynamic range. There must be exactly + * frame_size samples per channel. + * @param [in] frame_size int: Number of samples per frame of input signal + * @param [out] compressed char *: The compressed data is written here. This may not alias pcm and must be at least maxCompressedBytes long. + * @param [in] maxCompressedBytes int: Maximum number of bytes to use for compressing the frame + * (can change from one frame to another) + * @return Number of bytes written to "compressed". + * If negative, an error has occurred (see error codes). It is IMPORTANT that + * the length returned be somehow transmitted to the decoder. Otherwise, no + * decoding is possible. + */ +OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_encode_float( + OpusCustomEncoder *st, + const float *pcm, + int frame_size, + unsigned char *compressed, + int maxCompressedBytes +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); + +/** Encodes a frame of audio. + * @param [in] st OpusCustomEncoder*: Encoder state + * @param [in] pcm opus_int16*: PCM audio in signed 16-bit format (native endian). + * There must be exactly frame_size samples per channel. + * @param [in] frame_size int: Number of samples per frame of input signal + * @param [out] compressed char *: The compressed data is written here. This may not alias pcm and must be at least maxCompressedBytes long. + * @param [in] maxCompressedBytes int: Maximum number of bytes to use for compressing the frame + * (can change from one frame to another) + * @return Number of bytes written to "compressed". + * If negative, an error has occurred (see error codes). It is IMPORTANT that + * the length returned be somehow transmitted to the decoder. Otherwise, no + * decoding is possible. + */ +OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_encode( + OpusCustomEncoder *st, + const opus_int16 *pcm, + int frame_size, + unsigned char *compressed, + int maxCompressedBytes +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); + +/** Perform a CTL function on an Opus custom encoder. + * + * Generally the request and subsequent arguments are generated + * by a convenience macro. + * @see opus_encoderctls + */ +OPUS_CUSTOM_EXPORT int opus_custom_encoder_ctl(OpusCustomEncoder * OPUS_RESTRICT st, int request, ...) OPUS_ARG_NONNULL(1); + + +#if !defined(OPUS_BUILD) || defined(CELT_DECODER_C) +/* Decoder */ + +/** Gets the size of an OpusCustomDecoder structure. + * @param [in] mode OpusCustomMode *: Mode configuration + * @param [in] channels int: Number of channels + * @returns size + */ +OPUS_CUSTOM_EXPORT_STATIC OPUS_WARN_UNUSED_RESULT int opus_custom_decoder_get_size( + const OpusCustomMode *mode, + int channels +) OPUS_ARG_NONNULL(1); + +/** Initializes a previously allocated decoder state + * The memory pointed to by st must be the size returned by opus_custom_decoder_get_size. + * This is intended for applications which use their own allocator instead of malloc. + * @see opus_custom_decoder_create(),opus_custom_decoder_get_size() + * To reset a previously initialized state use the OPUS_RESET_STATE CTL. + * @param [in] st OpusCustomDecoder*: Decoder state + * @param [in] mode OpusCustomMode *: Contains all the information about the characteristics of + * the stream (must be the same characteristics as used for the + * encoder) + * @param [in] channels int: Number of channels + * @return OPUS_OK Success or @ref opus_errorcodes + */ +OPUS_CUSTOM_EXPORT_STATIC int opus_custom_decoder_init( + OpusCustomDecoder *st, + const OpusCustomMode *mode, + int channels +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2); + +#endif + + +/** Creates a new decoder state. Each stream needs its own decoder state (can't + * be shared across simultaneous streams). + * @param [in] mode OpusCustomMode: Contains all the information about the characteristics of the + * stream (must be the same characteristics as used for the encoder) + * @param [in] channels int: Number of channels + * @param [out] error int*: Returns an error code + * @return Newly created decoder state. + */ +OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT OpusCustomDecoder *opus_custom_decoder_create( + const OpusCustomMode *mode, + int channels, + int *error +) OPUS_ARG_NONNULL(1); + +/** Destroys a an decoder state. + * @param[in] st OpusCustomDecoder*: State to be freed. + */ +OPUS_CUSTOM_EXPORT void opus_custom_decoder_destroy(OpusCustomDecoder *st); + +/** Decode an opus custom frame with floating point output + * @param [in] st OpusCustomDecoder*: Decoder state + * @param [in] data char*: Input payload. Use a NULL pointer to indicate packet loss + * @param [in] len int: Number of bytes in payload + * @param [out] pcm float*: Output signal (interleaved if 2 channels). length + * is frame_size*channels*sizeof(float) + * @param [in] frame_size Number of samples per channel of available space in *pcm. + * @returns Number of decoded samples or @ref opus_errorcodes + */ +OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_decode_float( + OpusCustomDecoder *st, + const unsigned char *data, + int len, + float *pcm, + int frame_size +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + +/** Decode an opus custom frame + * @param [in] st OpusCustomDecoder*: Decoder state + * @param [in] data char*: Input payload. Use a NULL pointer to indicate packet loss + * @param [in] len int: Number of bytes in payload + * @param [out] pcm opus_int16*: Output signal (interleaved if 2 channels). length + * is frame_size*channels*sizeof(opus_int16) + * @param [in] frame_size Number of samples per channel of available space in *pcm. + * @returns Number of decoded samples or @ref opus_errorcodes + */ +OPUS_CUSTOM_EXPORT OPUS_WARN_UNUSED_RESULT int opus_custom_decode( + OpusCustomDecoder *st, + const unsigned char *data, + int len, + opus_int16 *pcm, + int frame_size +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + +/** Perform a CTL function on an Opus custom decoder. + * + * Generally the request and subsequent arguments are generated + * by a convenience macro. + * @see opus_genericctls + */ +OPUS_CUSTOM_EXPORT int opus_custom_decoder_ctl(OpusCustomDecoder * OPUS_RESTRICT st, int request, ...) OPUS_ARG_NONNULL(1); + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* OPUS_CUSTOM_H */ diff --git a/src/opus-1.1/include/opus_defines.h b/src/opus-1.1/include/opus_defines.h new file mode 100644 index 00000000..265089f6 --- /dev/null +++ b/src/opus-1.1/include/opus_defines.h @@ -0,0 +1,726 @@ +/* Copyright (c) 2010-2011 Xiph.Org Foundation, Skype Limited + Written by Jean-Marc Valin and Koen Vos */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/** + * @file opus_defines.h + * @brief Opus reference implementation constants + */ + +#ifndef OPUS_DEFINES_H +#define OPUS_DEFINES_H + +#include "opus_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @defgroup opus_errorcodes Error codes + * @{ + */ +/** No error @hideinitializer*/ +#define OPUS_OK 0 +/** One or more invalid/out of range arguments @hideinitializer*/ +#define OPUS_BAD_ARG -1 +/** The mode struct passed is invalid @hideinitializer*/ +#define OPUS_BUFFER_TOO_SMALL -2 +/** An internal error was detected @hideinitializer*/ +#define OPUS_INTERNAL_ERROR -3 +/** The compressed data passed is corrupted @hideinitializer*/ +#define OPUS_INVALID_PACKET -4 +/** Invalid/unsupported request number @hideinitializer*/ +#define OPUS_UNIMPLEMENTED -5 +/** An encoder or decoder structure is invalid or already freed @hideinitializer*/ +#define OPUS_INVALID_STATE -6 +/** Memory allocation has failed @hideinitializer*/ +#define OPUS_ALLOC_FAIL -7 +/**@}*/ + +/** @cond OPUS_INTERNAL_DOC */ +/**Export control for opus functions */ + +#ifndef OPUS_EXPORT +# if defined(WIN32) +# ifdef OPUS_BUILD +# define OPUS_EXPORT __declspec(dllexport) +# else +# define OPUS_EXPORT +# endif +# elif defined(__GNUC__) && defined(OPUS_BUILD) +# define OPUS_EXPORT __attribute__ ((visibility ("default"))) +# else +# define OPUS_EXPORT +# endif +#endif + +# if !defined(OPUS_GNUC_PREREQ) +# if defined(__GNUC__)&&defined(__GNUC_MINOR__) +# define OPUS_GNUC_PREREQ(_maj,_min) \ + ((__GNUC__<<16)+__GNUC_MINOR__>=((_maj)<<16)+(_min)) +# else +# define OPUS_GNUC_PREREQ(_maj,_min) 0 +# endif +# endif + +#if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) ) +# if OPUS_GNUC_PREREQ(3,0) +# define OPUS_RESTRICT __restrict__ +# elif (defined(_MSC_VER) && _MSC_VER >= 1400) +# define OPUS_RESTRICT __restrict +# else +# define OPUS_RESTRICT +# endif +#else +# define OPUS_RESTRICT restrict +#endif + +#if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) ) +# if OPUS_GNUC_PREREQ(2,7) +# define OPUS_INLINE __inline__ +# elif (defined(_MSC_VER)) +# define OPUS_INLINE __inline +# else +# define OPUS_INLINE +# endif +#else +# define OPUS_INLINE inline +#endif + +/**Warning attributes for opus functions + * NONNULL is not used in OPUS_BUILD to avoid the compiler optimizing out + * some paranoid null checks. */ +#if defined(__GNUC__) && OPUS_GNUC_PREREQ(3, 4) +# define OPUS_WARN_UNUSED_RESULT __attribute__ ((__warn_unused_result__)) +#else +# define OPUS_WARN_UNUSED_RESULT +#endif +#if !defined(OPUS_BUILD) && defined(__GNUC__) && OPUS_GNUC_PREREQ(3, 4) +# define OPUS_ARG_NONNULL(_x) __attribute__ ((__nonnull__(_x))) +#else +# define OPUS_ARG_NONNULL(_x) +#endif + +/** These are the actual Encoder CTL ID numbers. + * They should not be used directly by applications. + * In general, SETs should be even and GETs should be odd.*/ +#define OPUS_SET_APPLICATION_REQUEST 4000 +#define OPUS_GET_APPLICATION_REQUEST 4001 +#define OPUS_SET_BITRATE_REQUEST 4002 +#define OPUS_GET_BITRATE_REQUEST 4003 +#define OPUS_SET_MAX_BANDWIDTH_REQUEST 4004 +#define OPUS_GET_MAX_BANDWIDTH_REQUEST 4005 +#define OPUS_SET_VBR_REQUEST 4006 +#define OPUS_GET_VBR_REQUEST 4007 +#define OPUS_SET_BANDWIDTH_REQUEST 4008 +#define OPUS_GET_BANDWIDTH_REQUEST 4009 +#define OPUS_SET_COMPLEXITY_REQUEST 4010 +#define OPUS_GET_COMPLEXITY_REQUEST 4011 +#define OPUS_SET_INBAND_FEC_REQUEST 4012 +#define OPUS_GET_INBAND_FEC_REQUEST 4013 +#define OPUS_SET_PACKET_LOSS_PERC_REQUEST 4014 +#define OPUS_GET_PACKET_LOSS_PERC_REQUEST 4015 +#define OPUS_SET_DTX_REQUEST 4016 +#define OPUS_GET_DTX_REQUEST 4017 +#define OPUS_SET_VBR_CONSTRAINT_REQUEST 4020 +#define OPUS_GET_VBR_CONSTRAINT_REQUEST 4021 +#define OPUS_SET_FORCE_CHANNELS_REQUEST 4022 +#define OPUS_GET_FORCE_CHANNELS_REQUEST 4023 +#define OPUS_SET_SIGNAL_REQUEST 4024 +#define OPUS_GET_SIGNAL_REQUEST 4025 +#define OPUS_GET_LOOKAHEAD_REQUEST 4027 +/* #define OPUS_RESET_STATE 4028 */ +#define OPUS_GET_SAMPLE_RATE_REQUEST 4029 +#define OPUS_GET_FINAL_RANGE_REQUEST 4031 +#define OPUS_GET_PITCH_REQUEST 4033 +#define OPUS_SET_GAIN_REQUEST 4034 +#define OPUS_GET_GAIN_REQUEST 4045 /* Should have been 4035 */ +#define OPUS_SET_LSB_DEPTH_REQUEST 4036 +#define OPUS_GET_LSB_DEPTH_REQUEST 4037 +#define OPUS_GET_LAST_PACKET_DURATION_REQUEST 4039 +#define OPUS_SET_EXPERT_FRAME_DURATION_REQUEST 4040 +#define OPUS_GET_EXPERT_FRAME_DURATION_REQUEST 4041 +#define OPUS_SET_PREDICTION_DISABLED_REQUEST 4042 +#define OPUS_GET_PREDICTION_DISABLED_REQUEST 4043 + +/* Don't use 4045, it's already taken by OPUS_GET_GAIN_REQUEST */ + +/* Macros to trigger compilation errors when the wrong types are provided to a CTL */ +#define __opus_check_int(x) (((void)((x) == (opus_int32)0)), (opus_int32)(x)) +#define __opus_check_int_ptr(ptr) ((ptr) + ((ptr) - (opus_int32*)(ptr))) +#define __opus_check_uint_ptr(ptr) ((ptr) + ((ptr) - (opus_uint32*)(ptr))) +#define __opus_check_val16_ptr(ptr) ((ptr) + ((ptr) - (opus_val16*)(ptr))) +/** @endcond */ + +/** @defgroup opus_ctlvalues Pre-defined values for CTL interface + * @see opus_genericctls, opus_encoderctls + * @{ + */ +/* Values for the various encoder CTLs */ +#define OPUS_AUTO -1000 /**opus_int32: Allowed values: 0-10, inclusive. + * + * @hideinitializer */ +#define OPUS_SET_COMPLEXITY(x) OPUS_SET_COMPLEXITY_REQUEST, __opus_check_int(x) +/** Gets the encoder's complexity configuration. + * @see OPUS_SET_COMPLEXITY + * @param[out] x opus_int32 *: Returns a value in the range 0-10, + * inclusive. + * @hideinitializer */ +#define OPUS_GET_COMPLEXITY(x) OPUS_GET_COMPLEXITY_REQUEST, __opus_check_int_ptr(x) + +/** Configures the bitrate in the encoder. + * Rates from 500 to 512000 bits per second are meaningful, as well as the + * special values #OPUS_AUTO and #OPUS_BITRATE_MAX. + * The value #OPUS_BITRATE_MAX can be used to cause the codec to use as much + * rate as it can, which is useful for controlling the rate by adjusting the + * output buffer size. + * @see OPUS_GET_BITRATE + * @param[in] x opus_int32: Bitrate in bits per second. The default + * is determined based on the number of + * channels and the input sampling rate. + * @hideinitializer */ +#define OPUS_SET_BITRATE(x) OPUS_SET_BITRATE_REQUEST, __opus_check_int(x) +/** Gets the encoder's bitrate configuration. + * @see OPUS_SET_BITRATE + * @param[out] x opus_int32 *: Returns the bitrate in bits per second. + * The default is determined based on the + * number of channels and the input + * sampling rate. + * @hideinitializer */ +#define OPUS_GET_BITRATE(x) OPUS_GET_BITRATE_REQUEST, __opus_check_int_ptr(x) + +/** Enables or disables variable bitrate (VBR) in the encoder. + * The configured bitrate may not be met exactly because frames must + * be an integer number of bytes in length. + * @warning Only the MDCT mode of Opus can provide hard CBR behavior. + * @see OPUS_GET_VBR + * @see OPUS_SET_VBR_CONSTRAINT + * @param[in] x opus_int32: Allowed values: + *
    + *
    0
    Hard CBR. For LPC/hybrid modes at very low bit-rate, this can + * cause noticeable quality degradation.
    + *
    1
    VBR (default). The exact type of VBR is controlled by + * #OPUS_SET_VBR_CONSTRAINT.
    + *
    + * @hideinitializer */ +#define OPUS_SET_VBR(x) OPUS_SET_VBR_REQUEST, __opus_check_int(x) +/** Determine if variable bitrate (VBR) is enabled in the encoder. + * @see OPUS_SET_VBR + * @see OPUS_GET_VBR_CONSTRAINT + * @param[out] x opus_int32 *: Returns one of the following values: + *
    + *
    0
    Hard CBR.
    + *
    1
    VBR (default). The exact type of VBR may be retrieved via + * #OPUS_GET_VBR_CONSTRAINT.
    + *
    + * @hideinitializer */ +#define OPUS_GET_VBR(x) OPUS_GET_VBR_REQUEST, __opus_check_int_ptr(x) + +/** Enables or disables constrained VBR in the encoder. + * This setting is ignored when the encoder is in CBR mode. + * @warning Only the MDCT mode of Opus currently heeds the constraint. + * Speech mode ignores it completely, hybrid mode may fail to obey it + * if the LPC layer uses more bitrate than the constraint would have + * permitted. + * @see OPUS_GET_VBR_CONSTRAINT + * @see OPUS_SET_VBR + * @param[in] x opus_int32: Allowed values: + *
    + *
    0
    Unconstrained VBR.
    + *
    1
    Constrained VBR (default). This creates a maximum of one + * frame of buffering delay assuming a transport with a + * serialization speed of the nominal bitrate.
    + *
    + * @hideinitializer */ +#define OPUS_SET_VBR_CONSTRAINT(x) OPUS_SET_VBR_CONSTRAINT_REQUEST, __opus_check_int(x) +/** Determine if constrained VBR is enabled in the encoder. + * @see OPUS_SET_VBR_CONSTRAINT + * @see OPUS_GET_VBR + * @param[out] x opus_int32 *: Returns one of the following values: + *
    + *
    0
    Unconstrained VBR.
    + *
    1
    Constrained VBR (default).
    + *
    + * @hideinitializer */ +#define OPUS_GET_VBR_CONSTRAINT(x) OPUS_GET_VBR_CONSTRAINT_REQUEST, __opus_check_int_ptr(x) + +/** Configures mono/stereo forcing in the encoder. + * This can force the encoder to produce packets encoded as either mono or + * stereo, regardless of the format of the input audio. This is useful when + * the caller knows that the input signal is currently a mono source embedded + * in a stereo stream. + * @see OPUS_GET_FORCE_CHANNELS + * @param[in] x opus_int32: Allowed values: + *
    + *
    #OPUS_AUTO
    Not forced (default)
    + *
    1
    Forced mono
    + *
    2
    Forced stereo
    + *
    + * @hideinitializer */ +#define OPUS_SET_FORCE_CHANNELS(x) OPUS_SET_FORCE_CHANNELS_REQUEST, __opus_check_int(x) +/** Gets the encoder's forced channel configuration. + * @see OPUS_SET_FORCE_CHANNELS + * @param[out] x opus_int32 *: + *
    + *
    #OPUS_AUTO
    Not forced (default)
    + *
    1
    Forced mono
    + *
    2
    Forced stereo
    + *
    + * @hideinitializer */ +#define OPUS_GET_FORCE_CHANNELS(x) OPUS_GET_FORCE_CHANNELS_REQUEST, __opus_check_int_ptr(x) + +/** Configures the maximum bandpass that the encoder will select automatically. + * Applications should normally use this instead of #OPUS_SET_BANDWIDTH + * (leaving that set to the default, #OPUS_AUTO). This allows the + * application to set an upper bound based on the type of input it is + * providing, but still gives the encoder the freedom to reduce the bandpass + * when the bitrate becomes too low, for better overall quality. + * @see OPUS_GET_MAX_BANDWIDTH + * @param[in] x opus_int32: Allowed values: + *
    + *
    OPUS_BANDWIDTH_NARROWBAND
    4 kHz passband
    + *
    OPUS_BANDWIDTH_MEDIUMBAND
    6 kHz passband
    + *
    OPUS_BANDWIDTH_WIDEBAND
    8 kHz passband
    + *
    OPUS_BANDWIDTH_SUPERWIDEBAND
    12 kHz passband
    + *
    OPUS_BANDWIDTH_FULLBAND
    20 kHz passband (default)
    + *
    + * @hideinitializer */ +#define OPUS_SET_MAX_BANDWIDTH(x) OPUS_SET_MAX_BANDWIDTH_REQUEST, __opus_check_int(x) + +/** Gets the encoder's configured maximum allowed bandpass. + * @see OPUS_SET_MAX_BANDWIDTH + * @param[out] x opus_int32 *: Allowed values: + *
    + *
    #OPUS_BANDWIDTH_NARROWBAND
    4 kHz passband
    + *
    #OPUS_BANDWIDTH_MEDIUMBAND
    6 kHz passband
    + *
    #OPUS_BANDWIDTH_WIDEBAND
    8 kHz passband
    + *
    #OPUS_BANDWIDTH_SUPERWIDEBAND
    12 kHz passband
    + *
    #OPUS_BANDWIDTH_FULLBAND
    20 kHz passband (default)
    + *
    + * @hideinitializer */ +#define OPUS_GET_MAX_BANDWIDTH(x) OPUS_GET_MAX_BANDWIDTH_REQUEST, __opus_check_int_ptr(x) + +/** Sets the encoder's bandpass to a specific value. + * This prevents the encoder from automatically selecting the bandpass based + * on the available bitrate. If an application knows the bandpass of the input + * audio it is providing, it should normally use #OPUS_SET_MAX_BANDWIDTH + * instead, which still gives the encoder the freedom to reduce the bandpass + * when the bitrate becomes too low, for better overall quality. + * @see OPUS_GET_BANDWIDTH + * @param[in] x opus_int32: Allowed values: + *
    + *
    #OPUS_AUTO
    (default)
    + *
    #OPUS_BANDWIDTH_NARROWBAND
    4 kHz passband
    + *
    #OPUS_BANDWIDTH_MEDIUMBAND
    6 kHz passband
    + *
    #OPUS_BANDWIDTH_WIDEBAND
    8 kHz passband
    + *
    #OPUS_BANDWIDTH_SUPERWIDEBAND
    12 kHz passband
    + *
    #OPUS_BANDWIDTH_FULLBAND
    20 kHz passband
    + *
    + * @hideinitializer */ +#define OPUS_SET_BANDWIDTH(x) OPUS_SET_BANDWIDTH_REQUEST, __opus_check_int(x) + +/** Configures the type of signal being encoded. + * This is a hint which helps the encoder's mode selection. + * @see OPUS_GET_SIGNAL + * @param[in] x opus_int32: Allowed values: + *
    + *
    #OPUS_AUTO
    (default)
    + *
    #OPUS_SIGNAL_VOICE
    Bias thresholds towards choosing LPC or Hybrid modes.
    + *
    #OPUS_SIGNAL_MUSIC
    Bias thresholds towards choosing MDCT modes.
    + *
    + * @hideinitializer */ +#define OPUS_SET_SIGNAL(x) OPUS_SET_SIGNAL_REQUEST, __opus_check_int(x) +/** Gets the encoder's configured signal type. + * @see OPUS_SET_SIGNAL + * @param[out] x opus_int32 *: Returns one of the following values: + *
    + *
    #OPUS_AUTO
    (default)
    + *
    #OPUS_SIGNAL_VOICE
    Bias thresholds towards choosing LPC or Hybrid modes.
    + *
    #OPUS_SIGNAL_MUSIC
    Bias thresholds towards choosing MDCT modes.
    + *
    + * @hideinitializer */ +#define OPUS_GET_SIGNAL(x) OPUS_GET_SIGNAL_REQUEST, __opus_check_int_ptr(x) + + +/** Configures the encoder's intended application. + * The initial value is a mandatory argument to the encoder_create function. + * @see OPUS_GET_APPLICATION + * @param[in] x opus_int32: Returns one of the following values: + *
    + *
    #OPUS_APPLICATION_VOIP
    + *
    Process signal for improved speech intelligibility.
    + *
    #OPUS_APPLICATION_AUDIO
    + *
    Favor faithfulness to the original input.
    + *
    #OPUS_APPLICATION_RESTRICTED_LOWDELAY
    + *
    Configure the minimum possible coding delay by disabling certain modes + * of operation.
    + *
    + * @hideinitializer */ +#define OPUS_SET_APPLICATION(x) OPUS_SET_APPLICATION_REQUEST, __opus_check_int(x) +/** Gets the encoder's configured application. + * @see OPUS_SET_APPLICATION + * @param[out] x opus_int32 *: Returns one of the following values: + *
    + *
    #OPUS_APPLICATION_VOIP
    + *
    Process signal for improved speech intelligibility.
    + *
    #OPUS_APPLICATION_AUDIO
    + *
    Favor faithfulness to the original input.
    + *
    #OPUS_APPLICATION_RESTRICTED_LOWDELAY
    + *
    Configure the minimum possible coding delay by disabling certain modes + * of operation.
    + *
    + * @hideinitializer */ +#define OPUS_GET_APPLICATION(x) OPUS_GET_APPLICATION_REQUEST, __opus_check_int_ptr(x) + +/** Gets the sampling rate the encoder or decoder was initialized with. + * This simply returns the Fs value passed to opus_encoder_init() + * or opus_decoder_init(). + * @param[out] x opus_int32 *: Sampling rate of encoder or decoder. + * @hideinitializer + */ +#define OPUS_GET_SAMPLE_RATE(x) OPUS_GET_SAMPLE_RATE_REQUEST, __opus_check_int_ptr(x) + +/** Gets the total samples of delay added by the entire codec. + * This can be queried by the encoder and then the provided number of samples can be + * skipped on from the start of the decoder's output to provide time aligned input + * and output. From the perspective of a decoding application the real data begins this many + * samples late. + * + * The decoder contribution to this delay is identical for all decoders, but the + * encoder portion of the delay may vary from implementation to implementation, + * version to version, or even depend on the encoder's initial configuration. + * Applications needing delay compensation should call this CTL rather than + * hard-coding a value. + * @param[out] x opus_int32 *: Number of lookahead samples + * @hideinitializer */ +#define OPUS_GET_LOOKAHEAD(x) OPUS_GET_LOOKAHEAD_REQUEST, __opus_check_int_ptr(x) + +/** Configures the encoder's use of inband forward error correction (FEC). + * @note This is only applicable to the LPC layer + * @see OPUS_GET_INBAND_FEC + * @param[in] x opus_int32: Allowed values: + *
    + *
    0
    Disable inband FEC (default).
    + *
    1
    Enable inband FEC.
    + *
    + * @hideinitializer */ +#define OPUS_SET_INBAND_FEC(x) OPUS_SET_INBAND_FEC_REQUEST, __opus_check_int(x) +/** Gets encoder's configured use of inband forward error correction. + * @see OPUS_SET_INBAND_FEC + * @param[out] x opus_int32 *: Returns one of the following values: + *
    + *
    0
    Inband FEC disabled (default).
    + *
    1
    Inband FEC enabled.
    + *
    + * @hideinitializer */ +#define OPUS_GET_INBAND_FEC(x) OPUS_GET_INBAND_FEC_REQUEST, __opus_check_int_ptr(x) + +/** Configures the encoder's expected packet loss percentage. + * Higher values with trigger progressively more loss resistant behavior in the encoder + * at the expense of quality at a given bitrate in the lossless case, but greater quality + * under loss. + * @see OPUS_GET_PACKET_LOSS_PERC + * @param[in] x opus_int32: Loss percentage in the range 0-100, inclusive (default: 0). + * @hideinitializer */ +#define OPUS_SET_PACKET_LOSS_PERC(x) OPUS_SET_PACKET_LOSS_PERC_REQUEST, __opus_check_int(x) +/** Gets the encoder's configured packet loss percentage. + * @see OPUS_SET_PACKET_LOSS_PERC + * @param[out] x opus_int32 *: Returns the configured loss percentage + * in the range 0-100, inclusive (default: 0). + * @hideinitializer */ +#define OPUS_GET_PACKET_LOSS_PERC(x) OPUS_GET_PACKET_LOSS_PERC_REQUEST, __opus_check_int_ptr(x) + +/** Configures the encoder's use of discontinuous transmission (DTX). + * @note This is only applicable to the LPC layer + * @see OPUS_GET_DTX + * @param[in] x opus_int32: Allowed values: + *
    + *
    0
    Disable DTX (default).
    + *
    1
    Enabled DTX.
    + *
    + * @hideinitializer */ +#define OPUS_SET_DTX(x) OPUS_SET_DTX_REQUEST, __opus_check_int(x) +/** Gets encoder's configured use of discontinuous transmission. + * @see OPUS_SET_DTX + * @param[out] x opus_int32 *: Returns one of the following values: + *
    + *
    0
    DTX disabled (default).
    + *
    1
    DTX enabled.
    + *
    + * @hideinitializer */ +#define OPUS_GET_DTX(x) OPUS_GET_DTX_REQUEST, __opus_check_int_ptr(x) +/** Configures the depth of signal being encoded. + * This is a hint which helps the encoder identify silence and near-silence. + * @see OPUS_GET_LSB_DEPTH + * @param[in] x opus_int32: Input precision in bits, between 8 and 24 + * (default: 24). + * @hideinitializer */ +#define OPUS_SET_LSB_DEPTH(x) OPUS_SET_LSB_DEPTH_REQUEST, __opus_check_int(x) +/** Gets the encoder's configured signal depth. + * @see OPUS_SET_LSB_DEPTH + * @param[out] x opus_int32 *: Input precision in bits, between 8 and + * 24 (default: 24). + * @hideinitializer */ +#define OPUS_GET_LSB_DEPTH(x) OPUS_GET_LSB_DEPTH_REQUEST, __opus_check_int_ptr(x) + +/** Gets the duration (in samples) of the last packet successfully decoded or concealed. + * @param[out] x opus_int32 *: Number of samples (at current sampling rate). + * @hideinitializer */ +#define OPUS_GET_LAST_PACKET_DURATION(x) OPUS_GET_LAST_PACKET_DURATION_REQUEST, __opus_check_int_ptr(x) + +/** Configures the encoder's use of variable duration frames. + * When variable duration is enabled, the encoder is free to use a shorter frame + * size than the one requested in the opus_encode*() call. + * It is then the user's responsibility + * to verify how much audio was encoded by checking the ToC byte of the encoded + * packet. The part of the audio that was not encoded needs to be resent to the + * encoder for the next call. Do not use this option unless you really + * know what you are doing. + * @see OPUS_GET_EXPERT_VARIABLE_DURATION + * @param[in] x opus_int32: Allowed values: + *
    + *
    OPUS_FRAMESIZE_ARG
    Select frame size from the argument (default).
    + *
    OPUS_FRAMESIZE_2_5_MS
    Use 2.5 ms frames.
    + *
    OPUS_FRAMESIZE_5_MS
    Use 2.5 ms frames.
    + *
    OPUS_FRAMESIZE_10_MS
    Use 10 ms frames.
    + *
    OPUS_FRAMESIZE_20_MS
    Use 20 ms frames.
    + *
    OPUS_FRAMESIZE_40_MS
    Use 40 ms frames.
    + *
    OPUS_FRAMESIZE_60_MS
    Use 60 ms frames.
    + *
    OPUS_FRAMESIZE_VARIABLE
    Optimize the frame size dynamically.
    + *
    + * @hideinitializer */ +#define OPUS_SET_EXPERT_FRAME_DURATION(x) OPUS_SET_EXPERT_FRAME_DURATION_REQUEST, __opus_check_int(x) +/** Gets the encoder's configured use of variable duration frames. + * @see OPUS_SET_EXPERT_VARIABLE_DURATION + * @param[out] x opus_int32 *: Returns one of the following values: + *
    + *
    OPUS_FRAMESIZE_ARG
    Select frame size from the argument (default).
    + *
    OPUS_FRAMESIZE_2_5_MS
    Use 2.5 ms frames.
    + *
    OPUS_FRAMESIZE_5_MS
    Use 2.5 ms frames.
    + *
    OPUS_FRAMESIZE_10_MS
    Use 10 ms frames.
    + *
    OPUS_FRAMESIZE_20_MS
    Use 20 ms frames.
    + *
    OPUS_FRAMESIZE_40_MS
    Use 40 ms frames.
    + *
    OPUS_FRAMESIZE_60_MS
    Use 60 ms frames.
    + *
    OPUS_FRAMESIZE_VARIABLE
    Optimize the frame size dynamically.
    + *
    + * @hideinitializer */ +#define OPUS_GET_EXPERT_FRAME_DURATION(x) OPUS_GET_EXPERT_FRAME_DURATION_REQUEST, __opus_check_int_ptr(x) + +/** If set to 1, disables almost all use of prediction, making frames almost + completely independent. This reduces quality. (default : 0) + * @hideinitializer */ +#define OPUS_SET_PREDICTION_DISABLED(x) OPUS_SET_PREDICTION_DISABLED_REQUEST, __opus_check_int(x) +/** Gets the encoder's configured prediction status. + * @hideinitializer */ +#define OPUS_GET_PREDICTION_DISABLED(x) OPUS_GET_PREDICTION_DISABLED_REQUEST, __opus_check_int_ptr(x) + +/**@}*/ + +/** @defgroup opus_genericctls Generic CTLs + * + * These macros are used with the \c opus_decoder_ctl and + * \c opus_encoder_ctl calls to generate a particular + * request. + * + * When called on an \c OpusDecoder they apply to that + * particular decoder instance. When called on an + * \c OpusEncoder they apply to the corresponding setting + * on that encoder instance, if present. + * + * Some usage examples: + * + * @code + * int ret; + * opus_int32 pitch; + * ret = opus_decoder_ctl(dec_ctx, OPUS_GET_PITCH(&pitch)); + * if (ret == OPUS_OK) return ret; + * + * opus_encoder_ctl(enc_ctx, OPUS_RESET_STATE); + * opus_decoder_ctl(dec_ctx, OPUS_RESET_STATE); + * + * opus_int32 enc_bw, dec_bw; + * opus_encoder_ctl(enc_ctx, OPUS_GET_BANDWIDTH(&enc_bw)); + * opus_decoder_ctl(dec_ctx, OPUS_GET_BANDWIDTH(&dec_bw)); + * if (enc_bw != dec_bw) { + * printf("packet bandwidth mismatch!\n"); + * } + * @endcode + * + * @see opus_encoder, opus_decoder_ctl, opus_encoder_ctl, opus_decoderctls, opus_encoderctls + * @{ + */ + +/** Resets the codec state to be equivalent to a freshly initialized state. + * This should be called when switching streams in order to prevent + * the back to back decoding from giving different results from + * one at a time decoding. + * @hideinitializer */ +#define OPUS_RESET_STATE 4028 + +/** Gets the final state of the codec's entropy coder. + * This is used for testing purposes, + * The encoder and decoder state should be identical after coding a payload + * (assuming no data corruption or software bugs) + * + * @param[out] x opus_uint32 *: Entropy coder state + * + * @hideinitializer */ +#define OPUS_GET_FINAL_RANGE(x) OPUS_GET_FINAL_RANGE_REQUEST, __opus_check_uint_ptr(x) + +/** Gets the pitch of the last decoded frame, if available. + * This can be used for any post-processing algorithm requiring the use of pitch, + * e.g. time stretching/shortening. If the last frame was not voiced, or if the + * pitch was not coded in the frame, then zero is returned. + * + * This CTL is only implemented for decoder instances. + * + * @param[out] x opus_int32 *: pitch period at 48 kHz (or 0 if not available) + * + * @hideinitializer */ +#define OPUS_GET_PITCH(x) OPUS_GET_PITCH_REQUEST, __opus_check_int_ptr(x) + +/** Gets the encoder's configured bandpass or the decoder's last bandpass. + * @see OPUS_SET_BANDWIDTH + * @param[out] x opus_int32 *: Returns one of the following values: + *
    + *
    #OPUS_AUTO
    (default)
    + *
    #OPUS_BANDWIDTH_NARROWBAND
    4 kHz passband
    + *
    #OPUS_BANDWIDTH_MEDIUMBAND
    6 kHz passband
    + *
    #OPUS_BANDWIDTH_WIDEBAND
    8 kHz passband
    + *
    #OPUS_BANDWIDTH_SUPERWIDEBAND
    12 kHz passband
    + *
    #OPUS_BANDWIDTH_FULLBAND
    20 kHz passband
    + *
    + * @hideinitializer */ +#define OPUS_GET_BANDWIDTH(x) OPUS_GET_BANDWIDTH_REQUEST, __opus_check_int_ptr(x) + +/**@}*/ + +/** @defgroup opus_decoderctls Decoder related CTLs + * @see opus_genericctls, opus_encoderctls, opus_decoder + * @{ + */ + +/** Configures decoder gain adjustment. + * Scales the decoded output by a factor specified in Q8 dB units. + * This has a maximum range of -32768 to 32767 inclusive, and returns + * OPUS_BAD_ARG otherwise. The default is zero indicating no adjustment. + * This setting survives decoder reset. + * + * gain = pow(10, x/(20.0*256)) + * + * @param[in] x opus_int32: Amount to scale PCM signal by in Q8 dB units. + * @hideinitializer */ +#define OPUS_SET_GAIN(x) OPUS_SET_GAIN_REQUEST, __opus_check_int(x) +/** Gets the decoder's configured gain adjustment. @see OPUS_SET_GAIN + * + * @param[out] x opus_int32 *: Amount to scale PCM signal by in Q8 dB units. + * @hideinitializer */ +#define OPUS_GET_GAIN(x) OPUS_GET_GAIN_REQUEST, __opus_check_int_ptr(x) + +/**@}*/ + +/** @defgroup opus_libinfo Opus library information functions + * @{ + */ + +/** Converts an opus error code into a human readable string. + * + * @param[in] error int: Error number + * @returns Error string + */ +OPUS_EXPORT const char *opus_strerror(int error); + +/** Gets the libopus version string. + * + * @returns Version string + */ +OPUS_EXPORT const char *opus_get_version_string(void); +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* OPUS_DEFINES_H */ diff --git a/src/opus-1.1/include/opus_multistream.h b/src/opus-1.1/include/opus_multistream.h new file mode 100644 index 00000000..ae599793 --- /dev/null +++ b/src/opus-1.1/include/opus_multistream.h @@ -0,0 +1,660 @@ +/* Copyright (c) 2011 Xiph.Org Foundation + Written by Jean-Marc Valin */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/** + * @file opus_multistream.h + * @brief Opus reference implementation multistream API + */ + +#ifndef OPUS_MULTISTREAM_H +#define OPUS_MULTISTREAM_H + +#include "opus.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** @cond OPUS_INTERNAL_DOC */ + +/** Macros to trigger compilation errors when the wrong types are provided to a + * CTL. */ +/**@{*/ +#define __opus_check_encstate_ptr(ptr) ((ptr) + ((ptr) - (OpusEncoder**)(ptr))) +#define __opus_check_decstate_ptr(ptr) ((ptr) + ((ptr) - (OpusDecoder**)(ptr))) +/**@}*/ + +/** These are the actual encoder and decoder CTL ID numbers. + * They should not be used directly by applications. + * In general, SETs should be even and GETs should be odd.*/ +/**@{*/ +#define OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST 5120 +#define OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST 5122 +/**@}*/ + +/** @endcond */ + +/** @defgroup opus_multistream_ctls Multistream specific encoder and decoder CTLs + * + * These are convenience macros that are specific to the + * opus_multistream_encoder_ctl() and opus_multistream_decoder_ctl() + * interface. + * The CTLs from @ref opus_genericctls, @ref opus_encoderctls, and + * @ref opus_decoderctls may be applied to a multistream encoder or decoder as + * well. + * In addition, you may retrieve the encoder or decoder state for an specific + * stream via #OPUS_MULTISTREAM_GET_ENCODER_STATE or + * #OPUS_MULTISTREAM_GET_DECODER_STATE and apply CTLs to it individually. + */ +/**@{*/ + +/** Gets the encoder state for an individual stream of a multistream encoder. + * @param[in] x opus_int32: The index of the stream whose encoder you + * wish to retrieve. + * This must be non-negative and less than + * the streams parameter used + * to initialize the encoder. + * @param[out] y OpusEncoder**: Returns a pointer to the given + * encoder state. + * @retval OPUS_BAD_ARG The index of the requested stream was out of range. + * @hideinitializer + */ +#define OPUS_MULTISTREAM_GET_ENCODER_STATE(x,y) OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST, __opus_check_int(x), __opus_check_encstate_ptr(y) + +/** Gets the decoder state for an individual stream of a multistream decoder. + * @param[in] x opus_int32: The index of the stream whose decoder you + * wish to retrieve. + * This must be non-negative and less than + * the streams parameter used + * to initialize the decoder. + * @param[out] y OpusDecoder**: Returns a pointer to the given + * decoder state. + * @retval OPUS_BAD_ARG The index of the requested stream was out of range. + * @hideinitializer + */ +#define OPUS_MULTISTREAM_GET_DECODER_STATE(x,y) OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST, __opus_check_int(x), __opus_check_decstate_ptr(y) + +/**@}*/ + +/** @defgroup opus_multistream Opus Multistream API + * @{ + * + * The multistream API allows individual Opus streams to be combined into a + * single packet, enabling support for up to 255 channels. Unlike an + * elementary Opus stream, the encoder and decoder must negotiate the channel + * configuration before the decoder can successfully interpret the data in the + * packets produced by the encoder. Some basic information, such as packet + * duration, can be computed without any special negotiation. + * + * The format for multistream Opus packets is defined in the + * Ogg + * encapsulation specification and is based on the self-delimited Opus + * framing described in Appendix B of RFC 6716. + * Normal Opus packets are just a degenerate case of multistream Opus packets, + * and can be encoded or decoded with the multistream API by setting + * streams to 1 when initializing the encoder or + * decoder. + * + * Multistream Opus streams can contain up to 255 elementary Opus streams. + * These may be either "uncoupled" or "coupled", indicating that the decoder + * is configured to decode them to either 1 or 2 channels, respectively. + * The streams are ordered so that all coupled streams appear at the + * beginning. + * + * A mapping table defines which decoded channel i + * should be used for each input/output (I/O) channel j. This table is + * typically provided as an unsigned char array. + * Let i = mapping[j] be the index for I/O channel j. + * If i < 2*coupled_streams, then I/O channel j is + * encoded as the left channel of stream (i/2) if i + * is even, or as the right channel of stream (i/2) if + * i is odd. Otherwise, I/O channel j is encoded as + * mono in stream (i - coupled_streams), unless it has the special + * value 255, in which case it is omitted from the encoding entirely (the + * decoder will reproduce it as silence). Each value i must either + * be the special value 255 or be less than streams + coupled_streams. + * + * The output channels specified by the encoder + * should use the + * Vorbis + * channel ordering. A decoder may wish to apply an additional permutation + * to the mapping the encoder used to achieve a different output channel + * order (e.g. for outputing in WAV order). + * + * Each multistream packet contains an Opus packet for each stream, and all of + * the Opus packets in a single multistream packet must have the same + * duration. Therefore the duration of a multistream packet can be extracted + * from the TOC sequence of the first stream, which is located at the + * beginning of the packet, just like an elementary Opus stream: + * + * @code + * int nb_samples; + * int nb_frames; + * nb_frames = opus_packet_get_nb_frames(data, len); + * if (nb_frames < 1) + * return nb_frames; + * nb_samples = opus_packet_get_samples_per_frame(data, 48000) * nb_frames; + * @endcode + * + * The general encoding and decoding process proceeds exactly the same as in + * the normal @ref opus_encoder and @ref opus_decoder APIs. + * See their documentation for an overview of how to use the corresponding + * multistream functions. + */ + +/** Opus multistream encoder state. + * This contains the complete state of a multistream Opus encoder. + * It is position independent and can be freely copied. + * @see opus_multistream_encoder_create + * @see opus_multistream_encoder_init + */ +typedef struct OpusMSEncoder OpusMSEncoder; + +/** Opus multistream decoder state. + * This contains the complete state of a multistream Opus decoder. + * It is position independent and can be freely copied. + * @see opus_multistream_decoder_create + * @see opus_multistream_decoder_init + */ +typedef struct OpusMSDecoder OpusMSDecoder; + +/**\name Multistream encoder functions */ +/**@{*/ + +/** Gets the size of an OpusMSEncoder structure. + * @param streams int: The total number of streams to encode from the + * input. + * This must be no more than 255. + * @param coupled_streams int: Number of coupled (2 channel) streams + * to encode. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * encoded channels (streams + + * coupled_streams) must be no + * more than 255. + * @returns The size in bytes on success, or a negative error code + * (see @ref opus_errorcodes) on error. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_encoder_get_size( + int streams, + int coupled_streams +); + +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_surround_encoder_get_size( + int channels, + int mapping_family +); + + +/** Allocates and initializes a multistream encoder state. + * Call opus_multistream_encoder_destroy() to release + * this object when finished. + * @param Fs opus_int32: Sampling rate of the input signal (in Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param channels int: Number of channels in the input signal. + * This must be at most 255. + * It may be greater than the number of + * coded channels (streams + + * coupled_streams). + * @param streams int: The total number of streams to encode from the + * input. + * This must be no more than the number of channels. + * @param coupled_streams int: Number of coupled (2 channel) streams + * to encode. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * encoded channels (streams + + * coupled_streams) must be no + * more than the number of input channels. + * @param[in] mapping const unsigned char[channels]: Mapping from + * encoded channels to input channels, as described in + * @ref opus_multistream. As an extra constraint, the + * multistream encoder does not allow encoding coupled + * streams for which one channel is unused since this + * is never a good idea. + * @param application int: The target encoder application. + * This must be one of the following: + *
    + *
    #OPUS_APPLICATION_VOIP
    + *
    Process signal for improved speech intelligibility.
    + *
    #OPUS_APPLICATION_AUDIO
    + *
    Favor faithfulness to the original input.
    + *
    #OPUS_APPLICATION_RESTRICTED_LOWDELAY
    + *
    Configure the minimum possible coding delay by disabling certain modes + * of operation.
    + *
    + * @param[out] error int *: Returns #OPUS_OK on success, or an error + * code (see @ref opus_errorcodes) on + * failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSEncoder *opus_multistream_encoder_create( + opus_int32 Fs, + int channels, + int streams, + int coupled_streams, + const unsigned char *mapping, + int application, + int *error +) OPUS_ARG_NONNULL(5); + +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSEncoder *opus_multistream_surround_encoder_create( + opus_int32 Fs, + int channels, + int mapping_family, + int *streams, + int *coupled_streams, + unsigned char *mapping, + int application, + int *error +) OPUS_ARG_NONNULL(5); + +/** Initialize a previously allocated multistream encoder state. + * The memory pointed to by \a st must be at least the size returned by + * opus_multistream_encoder_get_size(). + * This is intended for applications which use their own allocator instead of + * malloc. + * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. + * @see opus_multistream_encoder_create + * @see opus_multistream_encoder_get_size + * @param st OpusMSEncoder*: Multistream encoder state to initialize. + * @param Fs opus_int32: Sampling rate of the input signal (in Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param channels int: Number of channels in the input signal. + * This must be at most 255. + * It may be greater than the number of + * coded channels (streams + + * coupled_streams). + * @param streams int: The total number of streams to encode from the + * input. + * This must be no more than the number of channels. + * @param coupled_streams int: Number of coupled (2 channel) streams + * to encode. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * encoded channels (streams + + * coupled_streams) must be no + * more than the number of input channels. + * @param[in] mapping const unsigned char[channels]: Mapping from + * encoded channels to input channels, as described in + * @ref opus_multistream. As an extra constraint, the + * multistream encoder does not allow encoding coupled + * streams for which one channel is unused since this + * is never a good idea. + * @param application int: The target encoder application. + * This must be one of the following: + *
    + *
    #OPUS_APPLICATION_VOIP
    + *
    Process signal for improved speech intelligibility.
    + *
    #OPUS_APPLICATION_AUDIO
    + *
    Favor faithfulness to the original input.
    + *
    #OPUS_APPLICATION_RESTRICTED_LOWDELAY
    + *
    Configure the minimum possible coding delay by disabling certain modes + * of operation.
    + *
    + * @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes) + * on failure. + */ +OPUS_EXPORT int opus_multistream_encoder_init( + OpusMSEncoder *st, + opus_int32 Fs, + int channels, + int streams, + int coupled_streams, + const unsigned char *mapping, + int application +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6); + +OPUS_EXPORT int opus_multistream_surround_encoder_init( + OpusMSEncoder *st, + opus_int32 Fs, + int channels, + int mapping_family, + int *streams, + int *coupled_streams, + unsigned char *mapping, + int application +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6); + +/** Encodes a multistream Opus frame. + * @param st OpusMSEncoder*: Multistream encoder state. + * @param[in] pcm const opus_int16*: The input signal as interleaved + * samples. + * This must contain + * frame_size*channels + * samples. + * @param frame_size int: Number of samples per channel in the input + * signal. + * This must be an Opus frame size for the + * encoder's sampling rate. + * For example, at 48 kHz the permitted values + * are 120, 240, 480, 960, 1920, and 2880. + * Passing in a duration of less than 10 ms + * (480 samples at 48 kHz) will prevent the + * encoder from using the LPC or hybrid modes. + * @param[out] data unsigned char*: Output payload. + * This must contain storage for at + * least \a max_data_bytes. + * @param [in] max_data_bytes opus_int32: Size of the allocated + * memory for the output + * payload. This may be + * used to impose an upper limit on + * the instant bitrate, but should + * not be used as the only bitrate + * control. Use #OPUS_SET_BITRATE to + * control the bitrate. + * @returns The length of the encoded packet (in bytes) on success or a + * negative error code (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode( + OpusMSEncoder *st, + const opus_int16 *pcm, + int frame_size, + unsigned char *data, + opus_int32 max_data_bytes +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); + +/** Encodes a multistream Opus frame from floating point input. + * @param st OpusMSEncoder*: Multistream encoder state. + * @param[in] pcm const float*: The input signal as interleaved + * samples with a normal range of + * +/-1.0. + * Samples with a range beyond +/-1.0 + * are supported but will be clipped by + * decoders using the integer API and + * should only be used if it is known + * that the far end supports extended + * dynamic range. + * This must contain + * frame_size*channels + * samples. + * @param frame_size int: Number of samples per channel in the input + * signal. + * This must be an Opus frame size for the + * encoder's sampling rate. + * For example, at 48 kHz the permitted values + * are 120, 240, 480, 960, 1920, and 2880. + * Passing in a duration of less than 10 ms + * (480 samples at 48 kHz) will prevent the + * encoder from using the LPC or hybrid modes. + * @param[out] data unsigned char*: Output payload. + * This must contain storage for at + * least \a max_data_bytes. + * @param [in] max_data_bytes opus_int32: Size of the allocated + * memory for the output + * payload. This may be + * used to impose an upper limit on + * the instant bitrate, but should + * not be used as the only bitrate + * control. Use #OPUS_SET_BITRATE to + * control the bitrate. + * @returns The length of the encoded packet (in bytes) on success or a + * negative error code (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_encode_float( + OpusMSEncoder *st, + const float *pcm, + int frame_size, + unsigned char *data, + opus_int32 max_data_bytes +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(2) OPUS_ARG_NONNULL(4); + +/** Frees an OpusMSEncoder allocated by + * opus_multistream_encoder_create(). + * @param st OpusMSEncoder*: Multistream encoder state to be freed. + */ +OPUS_EXPORT void opus_multistream_encoder_destroy(OpusMSEncoder *st); + +/** Perform a CTL function on a multistream Opus encoder. + * + * Generally the request and subsequent arguments are generated by a + * convenience macro. + * @param st OpusMSEncoder*: Multistream encoder state. + * @param request This and all remaining parameters should be replaced by one + * of the convenience macros in @ref opus_genericctls, + * @ref opus_encoderctls, or @ref opus_multistream_ctls. + * @see opus_genericctls + * @see opus_encoderctls + * @see opus_multistream_ctls + */ +OPUS_EXPORT int opus_multistream_encoder_ctl(OpusMSEncoder *st, int request, ...) OPUS_ARG_NONNULL(1); + +/**@}*/ + +/**\name Multistream decoder functions */ +/**@{*/ + +/** Gets the size of an OpusMSDecoder structure. + * @param streams int: The total number of streams coded in the + * input. + * This must be no more than 255. + * @param coupled_streams int: Number streams to decode as coupled + * (2 channel) streams. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * coded channels (streams + + * coupled_streams) must be no + * more than 255. + * @returns The size in bytes on success, or a negative error code + * (see @ref opus_errorcodes) on error. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT opus_int32 opus_multistream_decoder_get_size( + int streams, + int coupled_streams +); + +/** Allocates and initializes a multistream decoder state. + * Call opus_multistream_decoder_destroy() to release + * this object when finished. + * @param Fs opus_int32: Sampling rate to decode at (in Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param channels int: Number of channels to output. + * This must be at most 255. + * It may be different from the number of coded + * channels (streams + + * coupled_streams). + * @param streams int: The total number of streams coded in the + * input. + * This must be no more than 255. + * @param coupled_streams int: Number of streams to decode as coupled + * (2 channel) streams. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * coded channels (streams + + * coupled_streams) must be no + * more than 255. + * @param[in] mapping const unsigned char[channels]: Mapping from + * coded channels to output channels, as described in + * @ref opus_multistream. + * @param[out] error int *: Returns #OPUS_OK on success, or an error + * code (see @ref opus_errorcodes) on + * failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT OpusMSDecoder *opus_multistream_decoder_create( + opus_int32 Fs, + int channels, + int streams, + int coupled_streams, + const unsigned char *mapping, + int *error +) OPUS_ARG_NONNULL(5); + +/** Intialize a previously allocated decoder state object. + * The memory pointed to by \a st must be at least the size returned by + * opus_multistream_encoder_get_size(). + * This is intended for applications which use their own allocator instead of + * malloc. + * To reset a previously initialized state, use the #OPUS_RESET_STATE CTL. + * @see opus_multistream_decoder_create + * @see opus_multistream_deocder_get_size + * @param st OpusMSEncoder*: Multistream encoder state to initialize. + * @param Fs opus_int32: Sampling rate to decode at (in Hz). + * This must be one of 8000, 12000, 16000, + * 24000, or 48000. + * @param channels int: Number of channels to output. + * This must be at most 255. + * It may be different from the number of coded + * channels (streams + + * coupled_streams). + * @param streams int: The total number of streams coded in the + * input. + * This must be no more than 255. + * @param coupled_streams int: Number of streams to decode as coupled + * (2 channel) streams. + * This must be no larger than the total + * number of streams. + * Additionally, The total number of + * coded channels (streams + + * coupled_streams) must be no + * more than 255. + * @param[in] mapping const unsigned char[channels]: Mapping from + * coded channels to output channels, as described in + * @ref opus_multistream. + * @returns #OPUS_OK on success, or an error code (see @ref opus_errorcodes) + * on failure. + */ +OPUS_EXPORT int opus_multistream_decoder_init( + OpusMSDecoder *st, + opus_int32 Fs, + int channels, + int streams, + int coupled_streams, + const unsigned char *mapping +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(6); + +/** Decode a multistream Opus packet. + * @param st OpusMSDecoder*: Multistream decoder state. + * @param[in] data const unsigned char*: Input payload. + * Use a NULL + * pointer to indicate packet + * loss. + * @param len opus_int32: Number of bytes in payload. + * @param[out] pcm opus_int16*: Output signal, with interleaved + * samples. + * This must contain room for + * frame_size*channels + * samples. + * @param frame_size int: The number of samples per channel of + * available space in \a pcm. + * If this is less than the maximum packet duration + * (120 ms; 5760 for 48kHz), this function will not be capable + * of decoding some packets. In the case of PLC (data==NULL) + * or FEC (decode_fec=1), then frame_size needs to be exactly + * the duration of audio that is missing, otherwise the + * decoder will not be in the optimal state to decode the + * next incoming packet. For the PLC and FEC cases, frame_size + * must be a multiple of 2.5 ms. + * @param decode_fec int: Flag (0 or 1) to request that any in-band + * forward error correction data be decoded. + * If no such data is available, the frame is + * decoded as if it were lost. + * @returns Number of samples decoded on success or a negative error code + * (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode( + OpusMSDecoder *st, + const unsigned char *data, + opus_int32 len, + opus_int16 *pcm, + int frame_size, + int decode_fec +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + +/** Decode a multistream Opus packet with floating point output. + * @param st OpusMSDecoder*: Multistream decoder state. + * @param[in] data const unsigned char*: Input payload. + * Use a NULL + * pointer to indicate packet + * loss. + * @param len opus_int32: Number of bytes in payload. + * @param[out] pcm opus_int16*: Output signal, with interleaved + * samples. + * This must contain room for + * frame_size*channels + * samples. + * @param frame_size int: The number of samples per channel of + * available space in \a pcm. + * If this is less than the maximum packet duration + * (120 ms; 5760 for 48kHz), this function will not be capable + * of decoding some packets. In the case of PLC (data==NULL) + * or FEC (decode_fec=1), then frame_size needs to be exactly + * the duration of audio that is missing, otherwise the + * decoder will not be in the optimal state to decode the + * next incoming packet. For the PLC and FEC cases, frame_size + * must be a multiple of 2.5 ms. + * @param decode_fec int: Flag (0 or 1) to request that any in-band + * forward error correction data be decoded. + * If no such data is available, the frame is + * decoded as if it were lost. + * @returns Number of samples decoded on success or a negative error code + * (see @ref opus_errorcodes) on failure. + */ +OPUS_EXPORT OPUS_WARN_UNUSED_RESULT int opus_multistream_decode_float( + OpusMSDecoder *st, + const unsigned char *data, + opus_int32 len, + float *pcm, + int frame_size, + int decode_fec +) OPUS_ARG_NONNULL(1) OPUS_ARG_NONNULL(4); + +/** Perform a CTL function on a multistream Opus decoder. + * + * Generally the request and subsequent arguments are generated by a + * convenience macro. + * @param st OpusMSDecoder*: Multistream decoder state. + * @param request This and all remaining parameters should be replaced by one + * of the convenience macros in @ref opus_genericctls, + * @ref opus_decoderctls, or @ref opus_multistream_ctls. + * @see opus_genericctls + * @see opus_decoderctls + * @see opus_multistream_ctls + */ +OPUS_EXPORT int opus_multistream_decoder_ctl(OpusMSDecoder *st, int request, ...) OPUS_ARG_NONNULL(1); + +/** Frees an OpusMSDecoder allocated by + * opus_multistream_decoder_create(). + * @param st OpusMSDecoder: Multistream decoder state to be freed. + */ +OPUS_EXPORT void opus_multistream_decoder_destroy(OpusMSDecoder *st); + +/**@}*/ + +/**@}*/ + +#ifdef __cplusplus +} +#endif + +#endif /* OPUS_MULTISTREAM_H */ diff --git a/src/opus-1.1/include/opus_types.h b/src/opus-1.1/include/opus_types.h new file mode 100644 index 00000000..b28e03ae --- /dev/null +++ b/src/opus-1.1/include/opus_types.h @@ -0,0 +1,159 @@ +/* (C) COPYRIGHT 1994-2002 Xiph.Org Foundation */ +/* Modified by Jean-Marc Valin */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/* opus_types.h based on ogg_types.h from libogg */ + +/** + @file opus_types.h + @brief Opus reference implementation types +*/ +#ifndef OPUS_TYPES_H +#define OPUS_TYPES_H + +/* Use the real stdint.h if it's there (taken from Paul Hsieh's pstdint.h) */ +#if (defined(__STDC__) && __STDC__ && __STDC_VERSION__ >= 199901L) || (defined(__GNUC__) && (defined(_STDINT_H) || defined(_STDINT_H_)) || defined (HAVE_STDINT_H)) +#include + + typedef int16_t opus_int16; + typedef uint16_t opus_uint16; + typedef int32_t opus_int32; + typedef uint32_t opus_uint32; +#elif defined(_WIN32) + +# if defined(__CYGWIN__) +# include <_G_config.h> + typedef _G_int32_t opus_int32; + typedef _G_uint32_t opus_uint32; + typedef _G_int16 opus_int16; + typedef _G_uint16 opus_uint16; +# elif defined(__MINGW32__) + typedef short opus_int16; + typedef unsigned short opus_uint16; + typedef int opus_int32; + typedef unsigned int opus_uint32; +# elif defined(__MWERKS__) + typedef int opus_int32; + typedef unsigned int opus_uint32; + typedef short opus_int16; + typedef unsigned short opus_uint16; +# else + /* MSVC/Borland */ + typedef __int32 opus_int32; + typedef unsigned __int32 opus_uint32; + typedef __int16 opus_int16; + typedef unsigned __int16 opus_uint16; +# endif + +#elif defined(__MACOS__) + +# include + typedef SInt16 opus_int16; + typedef UInt16 opus_uint16; + typedef SInt32 opus_int32; + typedef UInt32 opus_uint32; + +#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */ + +# include + typedef int16_t opus_int16; + typedef u_int16_t opus_uint16; + typedef int32_t opus_int32; + typedef u_int32_t opus_uint32; + +#elif defined(__BEOS__) + + /* Be */ +# include + typedef int16 opus_int16; + typedef u_int16 opus_uint16; + typedef int32_t opus_int32; + typedef u_int32_t opus_uint32; + +#elif defined (__EMX__) + + /* OS/2 GCC */ + typedef short opus_int16; + typedef unsigned short opus_uint16; + typedef int opus_int32; + typedef unsigned int opus_uint32; + +#elif defined (DJGPP) + + /* DJGPP */ + typedef short opus_int16; + typedef unsigned short opus_uint16; + typedef int opus_int32; + typedef unsigned int opus_uint32; + +#elif defined(R5900) + + /* PS2 EE */ + typedef int opus_int32; + typedef unsigned opus_uint32; + typedef short opus_int16; + typedef unsigned short opus_uint16; + +#elif defined(__SYMBIAN32__) + + /* Symbian GCC */ + typedef signed short opus_int16; + typedef unsigned short opus_uint16; + typedef signed int opus_int32; + typedef unsigned int opus_uint32; + +#elif defined(CONFIG_TI_C54X) || defined (CONFIG_TI_C55X) + + typedef short opus_int16; + typedef unsigned short opus_uint16; + typedef long opus_int32; + typedef unsigned long opus_uint32; + +#elif defined(CONFIG_TI_C6X) + + typedef short opus_int16; + typedef unsigned short opus_uint16; + typedef int opus_int32; + typedef unsigned int opus_uint32; + +#else + + /* Give up, take a reasonable guess */ + typedef short opus_int16; + typedef unsigned short opus_uint16; + typedef int opus_int32; + typedef unsigned int opus_uint32; + +#endif + +#define opus_int int /* used for counters etc; at least 16 bits */ +#define opus_int64 long long +#define opus_int8 signed char + +#define opus_uint unsigned int /* used for counters etc; at least 16 bits */ +#define opus_uint64 unsigned long long +#define opus_uint8 unsigned char + +#endif /* OPUS_TYPES_H */ diff --git a/src/opus-1.1/silk/A2NLSF.c b/src/opus-1.1/silk/A2NLSF.c new file mode 100644 index 00000000..74b1b95d --- /dev/null +++ b/src/opus-1.1/silk/A2NLSF.c @@ -0,0 +1,252 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +/* Conversion between prediction filter coefficients and NLSFs */ +/* Requires the order to be an even number */ +/* A piecewise linear approximation maps LSF <-> cos(LSF) */ +/* Therefore the result is not accurate NLSFs, but the two */ +/* functions are accurate inverses of each other */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SigProc_FIX.h" +#include "tables.h" + +/* Number of binary divisions, when not in low complexity mode */ +#define BIN_DIV_STEPS_A2NLSF_FIX 3 /* must be no higher than 16 - log2( LSF_COS_TAB_SZ_FIX ) */ +#define MAX_ITERATIONS_A2NLSF_FIX 30 + +/* Helper function for A2NLSF(..) */ +/* Transforms polynomials from cos(n*f) to cos(f)^n */ +static OPUS_INLINE void silk_A2NLSF_trans_poly( + opus_int32 *p, /* I/O Polynomial */ + const opus_int dd /* I Polynomial order (= filter order / 2 ) */ +) +{ + opus_int k, n; + + for( k = 2; k <= dd; k++ ) { + for( n = dd; n > k; n-- ) { + p[ n - 2 ] -= p[ n ]; + } + p[ k - 2 ] -= silk_LSHIFT( p[ k ], 1 ); + } +} +/* Helper function for A2NLSF(..) */ +/* Polynomial evaluation */ +static OPUS_INLINE opus_int32 silk_A2NLSF_eval_poly( /* return the polynomial evaluation, in Q16 */ + opus_int32 *p, /* I Polynomial, Q16 */ + const opus_int32 x, /* I Evaluation point, Q12 */ + const opus_int dd /* I Order */ +) +{ + opus_int n; + opus_int32 x_Q16, y32; + + y32 = p[ dd ]; /* Q16 */ + x_Q16 = silk_LSHIFT( x, 4 ); + for( n = dd - 1; n >= 0; n-- ) { + y32 = silk_SMLAWW( p[ n ], y32, x_Q16 ); /* Q16 */ + } + return y32; +} + +static OPUS_INLINE void silk_A2NLSF_init( + const opus_int32 *a_Q16, + opus_int32 *P, + opus_int32 *Q, + const opus_int dd +) +{ + opus_int k; + + /* Convert filter coefs to even and odd polynomials */ + P[dd] = silk_LSHIFT( 1, 16 ); + Q[dd] = silk_LSHIFT( 1, 16 ); + for( k = 0; k < dd; k++ ) { + P[ k ] = -a_Q16[ dd - k - 1 ] - a_Q16[ dd + k ]; /* Q16 */ + Q[ k ] = -a_Q16[ dd - k - 1 ] + a_Q16[ dd + k ]; /* Q16 */ + } + + /* Divide out zeros as we have that for even filter orders, */ + /* z = 1 is always a root in Q, and */ + /* z = -1 is always a root in P */ + for( k = dd; k > 0; k-- ) { + P[ k - 1 ] -= P[ k ]; + Q[ k - 1 ] += Q[ k ]; + } + + /* Transform polynomials from cos(n*f) to cos(f)^n */ + silk_A2NLSF_trans_poly( P, dd ); + silk_A2NLSF_trans_poly( Q, dd ); +} + +/* Compute Normalized Line Spectral Frequencies (NLSFs) from whitening filter coefficients */ +/* If not all roots are found, the a_Q16 coefficients are bandwidth expanded until convergence. */ +void silk_A2NLSF( + opus_int16 *NLSF, /* O Normalized Line Spectral Frequencies in Q15 (0..2^15-1) [d] */ + opus_int32 *a_Q16, /* I/O Monic whitening filter coefficients in Q16 [d] */ + const opus_int d /* I Filter order (must be even) */ +) +{ + opus_int i, k, m, dd, root_ix, ffrac; + opus_int32 xlo, xhi, xmid; + opus_int32 ylo, yhi, ymid, thr; + opus_int32 nom, den; + opus_int32 P[ SILK_MAX_ORDER_LPC / 2 + 1 ]; + opus_int32 Q[ SILK_MAX_ORDER_LPC / 2 + 1 ]; + opus_int32 *PQ[ 2 ]; + opus_int32 *p; + + /* Store pointers to array */ + PQ[ 0 ] = P; + PQ[ 1 ] = Q; + + dd = silk_RSHIFT( d, 1 ); + + silk_A2NLSF_init( a_Q16, P, Q, dd ); + + /* Find roots, alternating between P and Q */ + p = P; /* Pointer to polynomial */ + + xlo = silk_LSFCosTab_FIX_Q12[ 0 ]; /* Q12*/ + ylo = silk_A2NLSF_eval_poly( p, xlo, dd ); + + if( ylo < 0 ) { + /* Set the first NLSF to zero and move on to the next */ + NLSF[ 0 ] = 0; + p = Q; /* Pointer to polynomial */ + ylo = silk_A2NLSF_eval_poly( p, xlo, dd ); + root_ix = 1; /* Index of current root */ + } else { + root_ix = 0; /* Index of current root */ + } + k = 1; /* Loop counter */ + i = 0; /* Counter for bandwidth expansions applied */ + thr = 0; + while( 1 ) { + /* Evaluate polynomial */ + xhi = silk_LSFCosTab_FIX_Q12[ k ]; /* Q12 */ + yhi = silk_A2NLSF_eval_poly( p, xhi, dd ); + + /* Detect zero crossing */ + if( ( ylo <= 0 && yhi >= thr ) || ( ylo >= 0 && yhi <= -thr ) ) { + if( yhi == 0 ) { + /* If the root lies exactly at the end of the current */ + /* interval, look for the next root in the next interval */ + thr = 1; + } else { + thr = 0; + } + /* Binary division */ + ffrac = -256; + for( m = 0; m < BIN_DIV_STEPS_A2NLSF_FIX; m++ ) { + /* Evaluate polynomial */ + xmid = silk_RSHIFT_ROUND( xlo + xhi, 1 ); + ymid = silk_A2NLSF_eval_poly( p, xmid, dd ); + + /* Detect zero crossing */ + if( ( ylo <= 0 && ymid >= 0 ) || ( ylo >= 0 && ymid <= 0 ) ) { + /* Reduce frequency */ + xhi = xmid; + yhi = ymid; + } else { + /* Increase frequency */ + xlo = xmid; + ylo = ymid; + ffrac = silk_ADD_RSHIFT( ffrac, 128, m ); + } + } + + /* Interpolate */ + if( silk_abs( ylo ) < 65536 ) { + /* Avoid dividing by zero */ + den = ylo - yhi; + nom = silk_LSHIFT( ylo, 8 - BIN_DIV_STEPS_A2NLSF_FIX ) + silk_RSHIFT( den, 1 ); + if( den != 0 ) { + ffrac += silk_DIV32( nom, den ); + } + } else { + /* No risk of dividing by zero because abs(ylo - yhi) >= abs(ylo) >= 65536 */ + ffrac += silk_DIV32( ylo, silk_RSHIFT( ylo - yhi, 8 - BIN_DIV_STEPS_A2NLSF_FIX ) ); + } + NLSF[ root_ix ] = (opus_int16)silk_min_32( silk_LSHIFT( (opus_int32)k, 8 ) + ffrac, silk_int16_MAX ); + + silk_assert( NLSF[ root_ix ] >= 0 ); + + root_ix++; /* Next root */ + if( root_ix >= d ) { + /* Found all roots */ + break; + } + /* Alternate pointer to polynomial */ + p = PQ[ root_ix & 1 ]; + + /* Evaluate polynomial */ + xlo = silk_LSFCosTab_FIX_Q12[ k - 1 ]; /* Q12*/ + ylo = silk_LSHIFT( 1 - ( root_ix & 2 ), 12 ); + } else { + /* Increment loop counter */ + k++; + xlo = xhi; + ylo = yhi; + thr = 0; + + if( k > LSF_COS_TAB_SZ_FIX ) { + i++; + if( i > MAX_ITERATIONS_A2NLSF_FIX ) { + /* Set NLSFs to white spectrum and exit */ + NLSF[ 0 ] = (opus_int16)silk_DIV32_16( 1 << 15, d + 1 ); + for( k = 1; k < d; k++ ) { + NLSF[ k ] = (opus_int16)silk_SMULBB( k + 1, NLSF[ 0 ] ); + } + return; + } + + /* Error: Apply progressively more bandwidth expansion and run again */ + silk_bwexpander_32( a_Q16, d, 65536 - silk_SMULBB( 10 + i, i ) ); /* 10_Q16 = 0.00015*/ + + silk_A2NLSF_init( a_Q16, P, Q, dd ); + p = P; /* Pointer to polynomial */ + xlo = silk_LSFCosTab_FIX_Q12[ 0 ]; /* Q12*/ + ylo = silk_A2NLSF_eval_poly( p, xlo, dd ); + if( ylo < 0 ) { + /* Set the first NLSF to zero and move on to the next */ + NLSF[ 0 ] = 0; + p = Q; /* Pointer to polynomial */ + ylo = silk_A2NLSF_eval_poly( p, xlo, dd ); + root_ix = 1; /* Index of current root */ + } else { + root_ix = 0; /* Index of current root */ + } + k = 1; /* Reset loop counter */ + } + } + } +} diff --git a/src/opus-1.1/silk/API.h b/src/opus-1.1/silk/API.h new file mode 100644 index 00000000..f0601bcf --- /dev/null +++ b/src/opus-1.1/silk/API.h @@ -0,0 +1,133 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifndef SILK_API_H +#define SILK_API_H + +#include "control.h" +#include "typedef.h" +#include "errors.h" +#include "entenc.h" +#include "entdec.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define SILK_MAX_FRAMES_PER_PACKET 3 + +/* Struct for TOC (Table of Contents) */ +typedef struct { + opus_int VADFlag; /* Voice activity for packet */ + opus_int VADFlags[ SILK_MAX_FRAMES_PER_PACKET ]; /* Voice activity for each frame in packet */ + opus_int inbandFECFlag; /* Flag indicating if packet contains in-band FEC */ +} silk_TOC_struct; + +/****************************************/ +/* Encoder functions */ +/****************************************/ + +/***********************************************/ +/* Get size in bytes of the Silk encoder state */ +/***********************************************/ +opus_int silk_Get_Encoder_Size( /* O Returns error code */ + opus_int *encSizeBytes /* O Number of bytes in SILK encoder state */ +); + +/*************************/ +/* Init or reset encoder */ +/*************************/ +opus_int silk_InitEncoder( /* O Returns error code */ + void *encState, /* I/O State */ + int arch, /* I Run-time architecture */ + silk_EncControlStruct *encStatus /* O Encoder Status */ +); + +/**************************/ +/* Encode frame with Silk */ +/**************************/ +/* Note: if prefillFlag is set, the input must contain 10 ms of audio, irrespective of what */ +/* encControl->payloadSize_ms is set to */ +opus_int silk_Encode( /* O Returns error code */ + void *encState, /* I/O State */ + silk_EncControlStruct *encControl, /* I Control status */ + const opus_int16 *samplesIn, /* I Speech sample input vector */ + opus_int nSamplesIn, /* I Number of samples in input vector */ + ec_enc *psRangeEnc, /* I/O Compressor data structure */ + opus_int32 *nBytesOut, /* I/O Number of bytes in payload (input: Max bytes) */ + const opus_int prefillFlag /* I Flag to indicate prefilling buffers no coding */ +); + +/****************************************/ +/* Decoder functions */ +/****************************************/ + +/***********************************************/ +/* Get size in bytes of the Silk decoder state */ +/***********************************************/ +opus_int silk_Get_Decoder_Size( /* O Returns error code */ + opus_int *decSizeBytes /* O Number of bytes in SILK decoder state */ +); + +/*************************/ +/* Init or Reset decoder */ +/*************************/ +opus_int silk_InitDecoder( /* O Returns error code */ + void *decState /* I/O State */ +); + +/******************/ +/* Decode a frame */ +/******************/ +opus_int silk_Decode( /* O Returns error code */ + void* decState, /* I/O State */ + silk_DecControlStruct* decControl, /* I/O Control Structure */ + opus_int lostFlag, /* I 0: no loss, 1 loss, 2 decode fec */ + opus_int newPacketFlag, /* I Indicates first decoder call for this packet */ + ec_dec *psRangeDec, /* I/O Compressor data structure */ + opus_int16 *samplesOut, /* O Decoded output speech vector */ + opus_int32 *nSamplesOut /* O Number of samples decoded */ +); + +#if 0 +/**************************************/ +/* Get table of contents for a packet */ +/**************************************/ +opus_int silk_get_TOC( + const opus_uint8 *payload, /* I Payload data */ + const opus_int nBytesIn, /* I Number of input bytes */ + const opus_int nFramesPerPayload, /* I Number of SILK frames per payload */ + silk_TOC_struct *Silk_TOC /* O Type of content */ +); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/opus-1.1/silk/CNG.c b/src/opus-1.1/silk/CNG.c new file mode 100644 index 00000000..8481d95d --- /dev/null +++ b/src/opus-1.1/silk/CNG.c @@ -0,0 +1,172 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main.h" +#include "stack_alloc.h" + +/* Generates excitation for CNG LPC synthesis */ +static OPUS_INLINE void silk_CNG_exc( + opus_int32 residual_Q10[], /* O CNG residual signal Q10 */ + opus_int32 exc_buf_Q14[], /* I Random samples buffer Q10 */ + opus_int32 Gain_Q16, /* I Gain to apply */ + opus_int length, /* I Length */ + opus_int32 *rand_seed /* I/O Seed to random index generator */ +) +{ + opus_int32 seed; + opus_int i, idx, exc_mask; + + exc_mask = CNG_BUF_MASK_MAX; + while( exc_mask > length ) { + exc_mask = silk_RSHIFT( exc_mask, 1 ); + } + + seed = *rand_seed; + for( i = 0; i < length; i++ ) { + seed = silk_RAND( seed ); + idx = (opus_int)( silk_RSHIFT( seed, 24 ) & exc_mask ); + silk_assert( idx >= 0 ); + silk_assert( idx <= CNG_BUF_MASK_MAX ); + residual_Q10[ i ] = (opus_int16)silk_SAT16( silk_SMULWW( exc_buf_Q14[ idx ], Gain_Q16 >> 4 ) ); + } + *rand_seed = seed; +} + +void silk_CNG_Reset( + silk_decoder_state *psDec /* I/O Decoder state */ +) +{ + opus_int i, NLSF_step_Q15, NLSF_acc_Q15; + + NLSF_step_Q15 = silk_DIV32_16( silk_int16_MAX, psDec->LPC_order + 1 ); + NLSF_acc_Q15 = 0; + for( i = 0; i < psDec->LPC_order; i++ ) { + NLSF_acc_Q15 += NLSF_step_Q15; + psDec->sCNG.CNG_smth_NLSF_Q15[ i ] = NLSF_acc_Q15; + } + psDec->sCNG.CNG_smth_Gain_Q16 = 0; + psDec->sCNG.rand_seed = 3176576; +} + +/* Updates CNG estimate, and applies the CNG when packet was lost */ +void silk_CNG( + silk_decoder_state *psDec, /* I/O Decoder state */ + silk_decoder_control *psDecCtrl, /* I/O Decoder control */ + opus_int16 frame[], /* I/O Signal */ + opus_int length /* I Length of residual */ +) +{ + opus_int i, subfr; + opus_int32 sum_Q6, max_Gain_Q16; + opus_int16 A_Q12[ MAX_LPC_ORDER ]; + silk_CNG_struct *psCNG = &psDec->sCNG; + SAVE_STACK; + + if( psDec->fs_kHz != psCNG->fs_kHz ) { + /* Reset state */ + silk_CNG_Reset( psDec ); + + psCNG->fs_kHz = psDec->fs_kHz; + } + if( psDec->lossCnt == 0 && psDec->prevSignalType == TYPE_NO_VOICE_ACTIVITY ) { + /* Update CNG parameters */ + + /* Smoothing of LSF's */ + for( i = 0; i < psDec->LPC_order; i++ ) { + psCNG->CNG_smth_NLSF_Q15[ i ] += silk_SMULWB( (opus_int32)psDec->prevNLSF_Q15[ i ] - (opus_int32)psCNG->CNG_smth_NLSF_Q15[ i ], CNG_NLSF_SMTH_Q16 ); + } + /* Find the subframe with the highest gain */ + max_Gain_Q16 = 0; + subfr = 0; + for( i = 0; i < psDec->nb_subfr; i++ ) { + if( psDecCtrl->Gains_Q16[ i ] > max_Gain_Q16 ) { + max_Gain_Q16 = psDecCtrl->Gains_Q16[ i ]; + subfr = i; + } + } + /* Update CNG excitation buffer with excitation from this subframe */ + silk_memmove( &psCNG->CNG_exc_buf_Q14[ psDec->subfr_length ], psCNG->CNG_exc_buf_Q14, ( psDec->nb_subfr - 1 ) * psDec->subfr_length * sizeof( opus_int32 ) ); + silk_memcpy( psCNG->CNG_exc_buf_Q14, &psDec->exc_Q14[ subfr * psDec->subfr_length ], psDec->subfr_length * sizeof( opus_int32 ) ); + + /* Smooth gains */ + for( i = 0; i < psDec->nb_subfr; i++ ) { + psCNG->CNG_smth_Gain_Q16 += silk_SMULWB( psDecCtrl->Gains_Q16[ i ] - psCNG->CNG_smth_Gain_Q16, CNG_GAIN_SMTH_Q16 ); + } + } + + /* Add CNG when packet is lost or during DTX */ + if( psDec->lossCnt ) { + VARDECL( opus_int32, CNG_sig_Q10 ); + + ALLOC( CNG_sig_Q10, length + MAX_LPC_ORDER, opus_int32 ); + + /* Generate CNG excitation */ + silk_CNG_exc( CNG_sig_Q10 + MAX_LPC_ORDER, psCNG->CNG_exc_buf_Q14, psCNG->CNG_smth_Gain_Q16, length, &psCNG->rand_seed ); + + /* Convert CNG NLSF to filter representation */ + silk_NLSF2A( A_Q12, psCNG->CNG_smth_NLSF_Q15, psDec->LPC_order ); + + /* Generate CNG signal, by synthesis filtering */ + silk_memcpy( CNG_sig_Q10, psCNG->CNG_synth_state, MAX_LPC_ORDER * sizeof( opus_int32 ) ); + for( i = 0; i < length; i++ ) { + silk_assert( psDec->LPC_order == 10 || psDec->LPC_order == 16 ); + /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ + sum_Q6 = silk_RSHIFT( psDec->LPC_order, 1 ); + sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 1 ], A_Q12[ 0 ] ); + sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 2 ], A_Q12[ 1 ] ); + sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 3 ], A_Q12[ 2 ] ); + sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 4 ], A_Q12[ 3 ] ); + sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 5 ], A_Q12[ 4 ] ); + sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 6 ], A_Q12[ 5 ] ); + sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 7 ], A_Q12[ 6 ] ); + sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 8 ], A_Q12[ 7 ] ); + sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 9 ], A_Q12[ 8 ] ); + sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 10 ], A_Q12[ 9 ] ); + if( psDec->LPC_order == 16 ) { + sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 11 ], A_Q12[ 10 ] ); + sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 12 ], A_Q12[ 11 ] ); + sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 13 ], A_Q12[ 12 ] ); + sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 14 ], A_Q12[ 13 ] ); + sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 15 ], A_Q12[ 14 ] ); + sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 16 ], A_Q12[ 15 ] ); + } + + /* Update states */ + CNG_sig_Q10[ MAX_LPC_ORDER + i ] = silk_ADD_LSHIFT( CNG_sig_Q10[ MAX_LPC_ORDER + i ], sum_Q6, 4 ); + + frame[ i ] = silk_ADD_SAT16( frame[ i ], silk_RSHIFT_ROUND( sum_Q6, 6 ) ); + } + silk_memcpy( psCNG->CNG_synth_state, &CNG_sig_Q10[ length ], MAX_LPC_ORDER * sizeof( opus_int32 ) ); + } else { + silk_memset( psCNG->CNG_synth_state, 0, psDec->LPC_order * sizeof( opus_int32 ) ); + } + RESTORE_STACK; +} diff --git a/src/opus-1.1/silk/HP_variable_cutoff.c b/src/opus-1.1/silk/HP_variable_cutoff.c new file mode 100644 index 00000000..bbe10f04 --- /dev/null +++ b/src/opus-1.1/silk/HP_variable_cutoff.c @@ -0,0 +1,77 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#ifdef FIXED_POINT +#include "main_FIX.h" +#else +#include "main_FLP.h" +#endif +#include "tuning_parameters.h" + +/* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */ +void silk_HP_variable_cutoff( + silk_encoder_state_Fxx state_Fxx[] /* I/O Encoder states */ +) +{ + opus_int quality_Q15; + opus_int32 pitch_freq_Hz_Q16, pitch_freq_log_Q7, delta_freq_Q7; + silk_encoder_state *psEncC1 = &state_Fxx[ 0 ].sCmn; + + /* Adaptive cutoff frequency: estimate low end of pitch frequency range */ + if( psEncC1->prevSignalType == TYPE_VOICED ) { + /* difference, in log domain */ + pitch_freq_Hz_Q16 = silk_DIV32_16( silk_LSHIFT( silk_MUL( psEncC1->fs_kHz, 1000 ), 16 ), psEncC1->prevLag ); + pitch_freq_log_Q7 = silk_lin2log( pitch_freq_Hz_Q16 ) - ( 16 << 7 ); + + /* adjustment based on quality */ + quality_Q15 = psEncC1->input_quality_bands_Q15[ 0 ]; + pitch_freq_log_Q7 = silk_SMLAWB( pitch_freq_log_Q7, silk_SMULWB( silk_LSHIFT( -quality_Q15, 2 ), quality_Q15 ), + pitch_freq_log_Q7 - ( silk_lin2log( SILK_FIX_CONST( VARIABLE_HP_MIN_CUTOFF_HZ, 16 ) ) - ( 16 << 7 ) ) ); + + /* delta_freq = pitch_freq_log - psEnc->variable_HP_smth1; */ + delta_freq_Q7 = pitch_freq_log_Q7 - silk_RSHIFT( psEncC1->variable_HP_smth1_Q15, 8 ); + if( delta_freq_Q7 < 0 ) { + /* less smoothing for decreasing pitch frequency, to track something close to the minimum */ + delta_freq_Q7 = silk_MUL( delta_freq_Q7, 3 ); + } + + /* limit delta, to reduce impact of outliers in pitch estimation */ + delta_freq_Q7 = silk_LIMIT_32( delta_freq_Q7, -SILK_FIX_CONST( VARIABLE_HP_MAX_DELTA_FREQ, 7 ), SILK_FIX_CONST( VARIABLE_HP_MAX_DELTA_FREQ, 7 ) ); + + /* update smoother */ + psEncC1->variable_HP_smth1_Q15 = silk_SMLAWB( psEncC1->variable_HP_smth1_Q15, + silk_SMULBB( psEncC1->speech_activity_Q8, delta_freq_Q7 ), SILK_FIX_CONST( VARIABLE_HP_SMTH_COEF1, 16 ) ); + + /* limit frequency range */ + psEncC1->variable_HP_smth1_Q15 = silk_LIMIT_32( psEncC1->variable_HP_smth1_Q15, + silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 ), + silk_LSHIFT( silk_lin2log( VARIABLE_HP_MAX_CUTOFF_HZ ), 8 ) ); + } +} diff --git a/src/opus-1.1/silk/Inlines.h b/src/opus-1.1/silk/Inlines.h new file mode 100644 index 00000000..ec986cdf --- /dev/null +++ b/src/opus-1.1/silk/Inlines.h @@ -0,0 +1,188 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +/*! \file silk_Inlines.h + * \brief silk_Inlines.h defines OPUS_INLINE signal processing functions. + */ + +#ifndef SILK_FIX_INLINES_H +#define SILK_FIX_INLINES_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* count leading zeros of opus_int64 */ +static OPUS_INLINE opus_int32 silk_CLZ64( opus_int64 in ) +{ + opus_int32 in_upper; + + in_upper = (opus_int32)silk_RSHIFT64(in, 32); + if (in_upper == 0) { + /* Search in the lower 32 bits */ + return 32 + silk_CLZ32( (opus_int32) in ); + } else { + /* Search in the upper 32 bits */ + return silk_CLZ32( in_upper ); + } +} + +/* get number of leading zeros and fractional part (the bits right after the leading one */ +static OPUS_INLINE void silk_CLZ_FRAC( + opus_int32 in, /* I input */ + opus_int32 *lz, /* O number of leading zeros */ + opus_int32 *frac_Q7 /* O the 7 bits right after the leading one */ +) +{ + opus_int32 lzeros = silk_CLZ32(in); + + * lz = lzeros; + * frac_Q7 = silk_ROR32(in, 24 - lzeros) & 0x7f; +} + +/* Approximation of square root */ +/* Accuracy: < +/- 10% for output values > 15 */ +/* < +/- 2.5% for output values > 120 */ +static OPUS_INLINE opus_int32 silk_SQRT_APPROX( opus_int32 x ) +{ + opus_int32 y, lz, frac_Q7; + + if( x <= 0 ) { + return 0; + } + + silk_CLZ_FRAC(x, &lz, &frac_Q7); + + if( lz & 1 ) { + y = 32768; + } else { + y = 46214; /* 46214 = sqrt(2) * 32768 */ + } + + /* get scaling right */ + y >>= silk_RSHIFT(lz, 1); + + /* increment using fractional part of input */ + y = silk_SMLAWB(y, y, silk_SMULBB(213, frac_Q7)); + + return y; +} + +/* Divide two int32 values and return result as int32 in a given Q-domain */ +static OPUS_INLINE opus_int32 silk_DIV32_varQ( /* O returns a good approximation of "(a32 << Qres) / b32" */ + const opus_int32 a32, /* I numerator (Q0) */ + const opus_int32 b32, /* I denominator (Q0) */ + const opus_int Qres /* I Q-domain of result (>= 0) */ +) +{ + opus_int a_headrm, b_headrm, lshift; + opus_int32 b32_inv, a32_nrm, b32_nrm, result; + + silk_assert( b32 != 0 ); + silk_assert( Qres >= 0 ); + + /* Compute number of bits head room and normalize inputs */ + a_headrm = silk_CLZ32( silk_abs(a32) ) - 1; + a32_nrm = silk_LSHIFT(a32, a_headrm); /* Q: a_headrm */ + b_headrm = silk_CLZ32( silk_abs(b32) ) - 1; + b32_nrm = silk_LSHIFT(b32, b_headrm); /* Q: b_headrm */ + + /* Inverse of b32, with 14 bits of precision */ + b32_inv = silk_DIV32_16( silk_int32_MAX >> 2, silk_RSHIFT(b32_nrm, 16) ); /* Q: 29 + 16 - b_headrm */ + + /* First approximation */ + result = silk_SMULWB(a32_nrm, b32_inv); /* Q: 29 + a_headrm - b_headrm */ + + /* Compute residual by subtracting product of denominator and first approximation */ + /* It's OK to overflow because the final value of a32_nrm should always be small */ + a32_nrm = silk_SUB32_ovflw(a32_nrm, silk_LSHIFT_ovflw( silk_SMMUL(b32_nrm, result), 3 )); /* Q: a_headrm */ + + /* Refinement */ + result = silk_SMLAWB(result, a32_nrm, b32_inv); /* Q: 29 + a_headrm - b_headrm */ + + /* Convert to Qres domain */ + lshift = 29 + a_headrm - b_headrm - Qres; + if( lshift < 0 ) { + return silk_LSHIFT_SAT32(result, -lshift); + } else { + if( lshift < 32){ + return silk_RSHIFT(result, lshift); + } else { + /* Avoid undefined result */ + return 0; + } + } +} + +/* Invert int32 value and return result as int32 in a given Q-domain */ +static OPUS_INLINE opus_int32 silk_INVERSE32_varQ( /* O returns a good approximation of "(1 << Qres) / b32" */ + const opus_int32 b32, /* I denominator (Q0) */ + const opus_int Qres /* I Q-domain of result (> 0) */ +) +{ + opus_int b_headrm, lshift; + opus_int32 b32_inv, b32_nrm, err_Q32, result; + + silk_assert( b32 != 0 ); + silk_assert( Qres > 0 ); + + /* Compute number of bits head room and normalize input */ + b_headrm = silk_CLZ32( silk_abs(b32) ) - 1; + b32_nrm = silk_LSHIFT(b32, b_headrm); /* Q: b_headrm */ + + /* Inverse of b32, with 14 bits of precision */ + b32_inv = silk_DIV32_16( silk_int32_MAX >> 2, silk_RSHIFT(b32_nrm, 16) ); /* Q: 29 + 16 - b_headrm */ + + /* First approximation */ + result = silk_LSHIFT(b32_inv, 16); /* Q: 61 - b_headrm */ + + /* Compute residual by subtracting product of denominator and first approximation from one */ + err_Q32 = silk_LSHIFT( ((opus_int32)1<<29) - silk_SMULWB(b32_nrm, b32_inv), 3 ); /* Q32 */ + + /* Refinement */ + result = silk_SMLAWW(result, err_Q32, b32_inv); /* Q: 61 - b_headrm */ + + /* Convert to Qres domain */ + lshift = 61 - b_headrm - Qres; + if( lshift <= 0 ) { + return silk_LSHIFT_SAT32(result, -lshift); + } else { + if( lshift < 32){ + return silk_RSHIFT(result, lshift); + }else{ + /* Avoid undefined result */ + return 0; + } + } +} + +#ifdef __cplusplus +} +#endif + +#endif /* SILK_FIX_INLINES_H */ diff --git a/src/opus-1.1/silk/LPC_analysis_filter.c b/src/opus-1.1/silk/LPC_analysis_filter.c new file mode 100644 index 00000000..9d1f16cb --- /dev/null +++ b/src/opus-1.1/silk/LPC_analysis_filter.c @@ -0,0 +1,106 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SigProc_FIX.h" +#include "celt_lpc.h" + +/*******************************************/ +/* LPC analysis filter */ +/* NB! State is kept internally and the */ +/* filter always starts with zero state */ +/* first d output samples are set to zero */ +/*******************************************/ + +void silk_LPC_analysis_filter( + opus_int16 *out, /* O Output signal */ + const opus_int16 *in, /* I Input signal */ + const opus_int16 *B, /* I MA prediction coefficients, Q12 [order] */ + const opus_int32 len, /* I Signal length */ + const opus_int32 d /* I Filter order */ +) +{ + opus_int j; +#ifdef FIXED_POINT + opus_int16 mem[SILK_MAX_ORDER_LPC]; + opus_int16 num[SILK_MAX_ORDER_LPC]; +#else + int ix; + opus_int32 out32_Q12, out32; + const opus_int16 *in_ptr; +#endif + + silk_assert( d >= 6 ); + silk_assert( (d & 1) == 0 ); + silk_assert( d <= len ); + +#ifdef FIXED_POINT + silk_assert( d <= SILK_MAX_ORDER_LPC ); + for ( j = 0; j < d; j++ ) { + num[ j ] = -B[ j ]; + } + for (j=0;j 0; k-- ) { + /* Check for stability */ + if( ( Anew_QA[ k ] > A_LIMIT ) || ( Anew_QA[ k ] < -A_LIMIT ) ) { + return 0; + } + + /* Set RC equal to negated AR coef */ + rc_Q31 = -silk_LSHIFT( Anew_QA[ k ], 31 - QA ); + + /* rc_mult1_Q30 range: [ 1 : 2^30 ] */ + rc_mult1_Q30 = ( (opus_int32)1 << 30 ) - silk_SMMUL( rc_Q31, rc_Q31 ); + silk_assert( rc_mult1_Q30 > ( 1 << 15 ) ); /* reduce A_LIMIT if fails */ + silk_assert( rc_mult1_Q30 <= ( 1 << 30 ) ); + + /* rc_mult2 range: [ 2^30 : silk_int32_MAX ] */ + mult2Q = 32 - silk_CLZ32( silk_abs( rc_mult1_Q30 ) ); + rc_mult2 = silk_INVERSE32_varQ( rc_mult1_Q30, mult2Q + 30 ); + + /* Update inverse gain */ + /* invGain_Q30 range: [ 0 : 2^30 ] */ + invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 ); + silk_assert( invGain_Q30 >= 0 ); + silk_assert( invGain_Q30 <= ( 1 << 30 ) ); + + /* Swap pointers */ + Aold_QA = Anew_QA; + Anew_QA = A_QA[ k & 1 ]; + + /* Update AR coefficient */ + for( n = 0; n < k; n++ ) { + tmp_QA = Aold_QA[ n ] - MUL32_FRAC_Q( Aold_QA[ k - n - 1 ], rc_Q31, 31 ); + Anew_QA[ n ] = MUL32_FRAC_Q( tmp_QA, rc_mult2 , mult2Q ); + } + } + + /* Check for stability */ + if( ( Anew_QA[ 0 ] > A_LIMIT ) || ( Anew_QA[ 0 ] < -A_LIMIT ) ) { + return 0; + } + + /* Set RC equal to negated AR coef */ + rc_Q31 = -silk_LSHIFT( Anew_QA[ 0 ], 31 - QA ); + + /* Range: [ 1 : 2^30 ] */ + rc_mult1_Q30 = ( (opus_int32)1 << 30 ) - silk_SMMUL( rc_Q31, rc_Q31 ); + + /* Update inverse gain */ + /* Range: [ 0 : 2^30 ] */ + invGain_Q30 = silk_LSHIFT( silk_SMMUL( invGain_Q30, rc_mult1_Q30 ), 2 ); + silk_assert( invGain_Q30 >= 0 ); + silk_assert( invGain_Q30 <= 1<<30 ); + + return invGain_Q30; +} + +/* For input in Q12 domain */ +opus_int32 silk_LPC_inverse_pred_gain( /* O Returns inverse prediction gain in energy domain, Q30 */ + const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */ + const opus_int order /* I Prediction order */ +) +{ + opus_int k; + opus_int32 Atmp_QA[ 2 ][ SILK_MAX_ORDER_LPC ]; + opus_int32 *Anew_QA; + opus_int32 DC_resp = 0; + + Anew_QA = Atmp_QA[ order & 1 ]; + + /* Increase Q domain of the AR coefficients */ + for( k = 0; k < order; k++ ) { + DC_resp += (opus_int32)A_Q12[ k ]; + Anew_QA[ k ] = silk_LSHIFT32( (opus_int32)A_Q12[ k ], QA - 12 ); + } + /* If the DC is unstable, we don't even need to do the full calculations */ + if( DC_resp >= 4096 ) { + return 0; + } + return LPC_inverse_pred_gain_QA( Atmp_QA, order ); +} + +#ifdef FIXED_POINT + +/* For input in Q24 domain */ +opus_int32 silk_LPC_inverse_pred_gain_Q24( /* O Returns inverse prediction gain in energy domain, Q30 */ + const opus_int32 *A_Q24, /* I Prediction coefficients [order] */ + const opus_int order /* I Prediction order */ +) +{ + opus_int k; + opus_int32 Atmp_QA[ 2 ][ SILK_MAX_ORDER_LPC ]; + opus_int32 *Anew_QA; + + Anew_QA = Atmp_QA[ order & 1 ]; + + /* Increase Q domain of the AR coefficients */ + for( k = 0; k < order; k++ ) { + Anew_QA[ k ] = silk_RSHIFT32( A_Q24[ k ], 24 - QA ); + } + + return LPC_inverse_pred_gain_QA( Atmp_QA, order ); +} +#endif diff --git a/src/opus-1.1/silk/LP_variable_cutoff.c b/src/opus-1.1/silk/LP_variable_cutoff.c new file mode 100644 index 00000000..f639e1f8 --- /dev/null +++ b/src/opus-1.1/silk/LP_variable_cutoff.c @@ -0,0 +1,135 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* + Elliptic/Cauer filters designed with 0.1 dB passband ripple, + 80 dB minimum stopband attenuation, and + [0.95 : 0.15 : 0.35] normalized cut off frequencies. +*/ + +#include "main.h" + +/* Helper function, interpolates the filter taps */ +static OPUS_INLINE void silk_LP_interpolate_filter_taps( + opus_int32 B_Q28[ TRANSITION_NB ], + opus_int32 A_Q28[ TRANSITION_NA ], + const opus_int ind, + const opus_int32 fac_Q16 +) +{ + opus_int nb, na; + + if( ind < TRANSITION_INT_NUM - 1 ) { + if( fac_Q16 > 0 ) { + if( fac_Q16 < 32768 ) { /* fac_Q16 is in range of a 16-bit int */ + /* Piece-wise linear interpolation of B and A */ + for( nb = 0; nb < TRANSITION_NB; nb++ ) { + B_Q28[ nb ] = silk_SMLAWB( + silk_Transition_LP_B_Q28[ ind ][ nb ], + silk_Transition_LP_B_Q28[ ind + 1 ][ nb ] - + silk_Transition_LP_B_Q28[ ind ][ nb ], + fac_Q16 ); + } + for( na = 0; na < TRANSITION_NA; na++ ) { + A_Q28[ na ] = silk_SMLAWB( + silk_Transition_LP_A_Q28[ ind ][ na ], + silk_Transition_LP_A_Q28[ ind + 1 ][ na ] - + silk_Transition_LP_A_Q28[ ind ][ na ], + fac_Q16 ); + } + } else { /* ( fac_Q16 - ( 1 << 16 ) ) is in range of a 16-bit int */ + silk_assert( fac_Q16 - ( 1 << 16 ) == silk_SAT16( fac_Q16 - ( 1 << 16 ) ) ); + /* Piece-wise linear interpolation of B and A */ + for( nb = 0; nb < TRANSITION_NB; nb++ ) { + B_Q28[ nb ] = silk_SMLAWB( + silk_Transition_LP_B_Q28[ ind + 1 ][ nb ], + silk_Transition_LP_B_Q28[ ind + 1 ][ nb ] - + silk_Transition_LP_B_Q28[ ind ][ nb ], + fac_Q16 - ( (opus_int32)1 << 16 ) ); + } + for( na = 0; na < TRANSITION_NA; na++ ) { + A_Q28[ na ] = silk_SMLAWB( + silk_Transition_LP_A_Q28[ ind + 1 ][ na ], + silk_Transition_LP_A_Q28[ ind + 1 ][ na ] - + silk_Transition_LP_A_Q28[ ind ][ na ], + fac_Q16 - ( (opus_int32)1 << 16 ) ); + } + } + } else { + silk_memcpy( B_Q28, silk_Transition_LP_B_Q28[ ind ], TRANSITION_NB * sizeof( opus_int32 ) ); + silk_memcpy( A_Q28, silk_Transition_LP_A_Q28[ ind ], TRANSITION_NA * sizeof( opus_int32 ) ); + } + } else { + silk_memcpy( B_Q28, silk_Transition_LP_B_Q28[ TRANSITION_INT_NUM - 1 ], TRANSITION_NB * sizeof( opus_int32 ) ); + silk_memcpy( A_Q28, silk_Transition_LP_A_Q28[ TRANSITION_INT_NUM - 1 ], TRANSITION_NA * sizeof( opus_int32 ) ); + } +} + +/* Low-pass filter with variable cutoff frequency based on */ +/* piece-wise linear interpolation between elliptic filters */ +/* Start by setting psEncC->mode <> 0; */ +/* Deactivate by setting psEncC->mode = 0; */ +void silk_LP_variable_cutoff( + silk_LP_state *psLP, /* I/O LP filter state */ + opus_int16 *frame, /* I/O Low-pass filtered output signal */ + const opus_int frame_length /* I Frame length */ +) +{ + opus_int32 B_Q28[ TRANSITION_NB ], A_Q28[ TRANSITION_NA ], fac_Q16 = 0; + opus_int ind = 0; + + silk_assert( psLP->transition_frame_no >= 0 && psLP->transition_frame_no <= TRANSITION_FRAMES ); + + /* Run filter if needed */ + if( psLP->mode != 0 ) { + /* Calculate index and interpolation factor for interpolation */ +#if( TRANSITION_INT_STEPS == 64 ) + fac_Q16 = silk_LSHIFT( TRANSITION_FRAMES - psLP->transition_frame_no, 16 - 6 ); +#else + fac_Q16 = silk_DIV32_16( silk_LSHIFT( TRANSITION_FRAMES - psLP->transition_frame_no, 16 ), TRANSITION_FRAMES ); +#endif + ind = silk_RSHIFT( fac_Q16, 16 ); + fac_Q16 -= silk_LSHIFT( ind, 16 ); + + silk_assert( ind >= 0 ); + silk_assert( ind < TRANSITION_INT_NUM ); + + /* Interpolate filter coefficients */ + silk_LP_interpolate_filter_taps( B_Q28, A_Q28, ind, fac_Q16 ); + + /* Update transition frame number for next frame */ + psLP->transition_frame_no = silk_LIMIT( psLP->transition_frame_no + psLP->mode, 0, TRANSITION_FRAMES ); + + /* ARMA low-pass filtering */ + silk_assert( TRANSITION_NB == 3 && TRANSITION_NA == 2 ); + silk_biquad_alt( frame, B_Q28, A_Q28, psLP->In_LP_State, frame, frame_length, 1); + } +} diff --git a/src/opus-1.1/silk/MacroCount.h b/src/opus-1.1/silk/MacroCount.h new file mode 100644 index 00000000..834817d0 --- /dev/null +++ b/src/opus-1.1/silk/MacroCount.h @@ -0,0 +1,718 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifndef SIGPROCFIX_API_MACROCOUNT_H +#define SIGPROCFIX_API_MACROCOUNT_H +#include + +#ifdef silk_MACRO_COUNT +#define varDefine opus_int64 ops_count = 0; + +extern opus_int64 ops_count; + +static OPUS_INLINE opus_int64 silk_SaveCount(){ + return(ops_count); +} + +static OPUS_INLINE opus_int64 silk_SaveResetCount(){ + opus_int64 ret; + + ret = ops_count; + ops_count = 0; + return(ret); +} + +static OPUS_INLINE silk_PrintCount(){ + printf("ops_count = %d \n ", (opus_int32)ops_count); +} + +#undef silk_MUL +static OPUS_INLINE opus_int32 silk_MUL(opus_int32 a32, opus_int32 b32){ + opus_int32 ret; + ops_count += 4; + ret = a32 * b32; + return ret; +} + +#undef silk_MUL_uint +static OPUS_INLINE opus_uint32 silk_MUL_uint(opus_uint32 a32, opus_uint32 b32){ + opus_uint32 ret; + ops_count += 4; + ret = a32 * b32; + return ret; +} +#undef silk_MLA +static OPUS_INLINE opus_int32 silk_MLA(opus_int32 a32, opus_int32 b32, opus_int32 c32){ + opus_int32 ret; + ops_count += 4; + ret = a32 + b32 * c32; + return ret; +} + +#undef silk_MLA_uint +static OPUS_INLINE opus_int32 silk_MLA_uint(opus_uint32 a32, opus_uint32 b32, opus_uint32 c32){ + opus_uint32 ret; + ops_count += 4; + ret = a32 + b32 * c32; + return ret; +} + +#undef silk_SMULWB +static OPUS_INLINE opus_int32 silk_SMULWB(opus_int32 a32, opus_int32 b32){ + opus_int32 ret; + ops_count += 5; + ret = (a32 >> 16) * (opus_int32)((opus_int16)b32) + (((a32 & 0x0000FFFF) * (opus_int32)((opus_int16)b32)) >> 16); + return ret; +} +#undef silk_SMLAWB +static OPUS_INLINE opus_int32 silk_SMLAWB(opus_int32 a32, opus_int32 b32, opus_int32 c32){ + opus_int32 ret; + ops_count += 5; + ret = ((a32) + ((((b32) >> 16) * (opus_int32)((opus_int16)(c32))) + ((((b32) & 0x0000FFFF) * (opus_int32)((opus_int16)(c32))) >> 16))); + return ret; +} + +#undef silk_SMULWT +static OPUS_INLINE opus_int32 silk_SMULWT(opus_int32 a32, opus_int32 b32){ + opus_int32 ret; + ops_count += 4; + ret = (a32 >> 16) * (b32 >> 16) + (((a32 & 0x0000FFFF) * (b32 >> 16)) >> 16); + return ret; +} +#undef silk_SMLAWT +static OPUS_INLINE opus_int32 silk_SMLAWT(opus_int32 a32, opus_int32 b32, opus_int32 c32){ + opus_int32 ret; + ops_count += 4; + ret = a32 + ((b32 >> 16) * (c32 >> 16)) + (((b32 & 0x0000FFFF) * ((c32 >> 16)) >> 16)); + return ret; +} + +#undef silk_SMULBB +static OPUS_INLINE opus_int32 silk_SMULBB(opus_int32 a32, opus_int32 b32){ + opus_int32 ret; + ops_count += 1; + ret = (opus_int32)((opus_int16)a32) * (opus_int32)((opus_int16)b32); + return ret; +} +#undef silk_SMLABB +static OPUS_INLINE opus_int32 silk_SMLABB(opus_int32 a32, opus_int32 b32, opus_int32 c32){ + opus_int32 ret; + ops_count += 1; + ret = a32 + (opus_int32)((opus_int16)b32) * (opus_int32)((opus_int16)c32); + return ret; +} + +#undef silk_SMULBT +static OPUS_INLINE opus_int32 silk_SMULBT(opus_int32 a32, opus_int32 b32 ){ + opus_int32 ret; + ops_count += 4; + ret = ((opus_int32)((opus_int16)a32)) * (b32 >> 16); + return ret; +} + +#undef silk_SMLABT +static OPUS_INLINE opus_int32 silk_SMLABT(opus_int32 a32, opus_int32 b32, opus_int32 c32){ + opus_int32 ret; + ops_count += 1; + ret = a32 + ((opus_int32)((opus_int16)b32)) * (c32 >> 16); + return ret; +} + +#undef silk_SMULTT +static OPUS_INLINE opus_int32 silk_SMULTT(opus_int32 a32, opus_int32 b32){ + opus_int32 ret; + ops_count += 1; + ret = (a32 >> 16) * (b32 >> 16); + return ret; +} + +#undef silk_SMLATT +static OPUS_INLINE opus_int32 silk_SMLATT(opus_int32 a32, opus_int32 b32, opus_int32 c32){ + opus_int32 ret; + ops_count += 1; + ret = a32 + (b32 >> 16) * (c32 >> 16); + return ret; +} + + +/* multiply-accumulate macros that allow overflow in the addition (ie, no asserts in debug mode)*/ +#undef silk_MLA_ovflw +#define silk_MLA_ovflw silk_MLA + +#undef silk_SMLABB_ovflw +#define silk_SMLABB_ovflw silk_SMLABB + +#undef silk_SMLABT_ovflw +#define silk_SMLABT_ovflw silk_SMLABT + +#undef silk_SMLATT_ovflw +#define silk_SMLATT_ovflw silk_SMLATT + +#undef silk_SMLAWB_ovflw +#define silk_SMLAWB_ovflw silk_SMLAWB + +#undef silk_SMLAWT_ovflw +#define silk_SMLAWT_ovflw silk_SMLAWT + +#undef silk_SMULL +static OPUS_INLINE opus_int64 silk_SMULL(opus_int32 a32, opus_int32 b32){ + opus_int64 ret; + ops_count += 8; + ret = ((opus_int64)(a32) * /*(opus_int64)*/(b32)); + return ret; +} + +#undef silk_SMLAL +static OPUS_INLINE opus_int64 silk_SMLAL(opus_int64 a64, opus_int32 b32, opus_int32 c32){ + opus_int64 ret; + ops_count += 8; + ret = a64 + ((opus_int64)(b32) * /*(opus_int64)*/(c32)); + return ret; +} +#undef silk_SMLALBB +static OPUS_INLINE opus_int64 silk_SMLALBB(opus_int64 a64, opus_int16 b16, opus_int16 c16){ + opus_int64 ret; + ops_count += 4; + ret = a64 + ((opus_int64)(b16) * /*(opus_int64)*/(c16)); + return ret; +} + +#undef SigProcFIX_CLZ16 +static OPUS_INLINE opus_int32 SigProcFIX_CLZ16(opus_int16 in16) +{ + opus_int32 out32 = 0; + ops_count += 10; + if( in16 == 0 ) { + return 16; + } + /* test nibbles */ + if( in16 & 0xFF00 ) { + if( in16 & 0xF000 ) { + in16 >>= 12; + } else { + out32 += 4; + in16 >>= 8; + } + } else { + if( in16 & 0xFFF0 ) { + out32 += 8; + in16 >>= 4; + } else { + out32 += 12; + } + } + /* test bits and return */ + if( in16 & 0xC ) { + if( in16 & 0x8 ) + return out32 + 0; + else + return out32 + 1; + } else { + if( in16 & 0xE ) + return out32 + 2; + else + return out32 + 3; + } +} + +#undef SigProcFIX_CLZ32 +static OPUS_INLINE opus_int32 SigProcFIX_CLZ32(opus_int32 in32) +{ + /* test highest 16 bits and convert to opus_int16 */ + ops_count += 2; + if( in32 & 0xFFFF0000 ) { + return SigProcFIX_CLZ16((opus_int16)(in32 >> 16)); + } else { + return SigProcFIX_CLZ16((opus_int16)in32) + 16; + } +} + +#undef silk_DIV32 +static OPUS_INLINE opus_int32 silk_DIV32(opus_int32 a32, opus_int32 b32){ + ops_count += 64; + return a32 / b32; +} + +#undef silk_DIV32_16 +static OPUS_INLINE opus_int32 silk_DIV32_16(opus_int32 a32, opus_int32 b32){ + ops_count += 32; + return a32 / b32; +} + +#undef silk_SAT8 +static OPUS_INLINE opus_int8 silk_SAT8(opus_int64 a){ + opus_int8 tmp; + ops_count += 1; + tmp = (opus_int8)((a) > silk_int8_MAX ? silk_int8_MAX : \ + ((a) < silk_int8_MIN ? silk_int8_MIN : (a))); + return(tmp); +} + +#undef silk_SAT16 +static OPUS_INLINE opus_int16 silk_SAT16(opus_int64 a){ + opus_int16 tmp; + ops_count += 1; + tmp = (opus_int16)((a) > silk_int16_MAX ? silk_int16_MAX : \ + ((a) < silk_int16_MIN ? silk_int16_MIN : (a))); + return(tmp); +} +#undef silk_SAT32 +static OPUS_INLINE opus_int32 silk_SAT32(opus_int64 a){ + opus_int32 tmp; + ops_count += 1; + tmp = (opus_int32)((a) > silk_int32_MAX ? silk_int32_MAX : \ + ((a) < silk_int32_MIN ? silk_int32_MIN : (a))); + return(tmp); +} +#undef silk_POS_SAT32 +static OPUS_INLINE opus_int32 silk_POS_SAT32(opus_int64 a){ + opus_int32 tmp; + ops_count += 1; + tmp = (opus_int32)((a) > silk_int32_MAX ? silk_int32_MAX : (a)); + return(tmp); +} + +#undef silk_ADD_POS_SAT8 +static OPUS_INLINE opus_int8 silk_ADD_POS_SAT8(opus_int64 a, opus_int64 b){ + opus_int8 tmp; + ops_count += 1; + tmp = (opus_int8)((((a)+(b)) & 0x80) ? silk_int8_MAX : ((a)+(b))); + return(tmp); +} +#undef silk_ADD_POS_SAT16 +static OPUS_INLINE opus_int16 silk_ADD_POS_SAT16(opus_int64 a, opus_int64 b){ + opus_int16 tmp; + ops_count += 1; + tmp = (opus_int16)((((a)+(b)) & 0x8000) ? silk_int16_MAX : ((a)+(b))); + return(tmp); +} + +#undef silk_ADD_POS_SAT32 +static OPUS_INLINE opus_int32 silk_ADD_POS_SAT32(opus_int64 a, opus_int64 b){ + opus_int32 tmp; + ops_count += 1; + tmp = (opus_int32)((((a)+(b)) & 0x80000000) ? silk_int32_MAX : ((a)+(b))); + return(tmp); +} + +#undef silk_ADD_POS_SAT64 +static OPUS_INLINE opus_int64 silk_ADD_POS_SAT64(opus_int64 a, opus_int64 b){ + opus_int64 tmp; + ops_count += 1; + tmp = ((((a)+(b)) & 0x8000000000000000LL) ? silk_int64_MAX : ((a)+(b))); + return(tmp); +} + +#undef silk_LSHIFT8 +static OPUS_INLINE opus_int8 silk_LSHIFT8(opus_int8 a, opus_int32 shift){ + opus_int8 ret; + ops_count += 1; + ret = a << shift; + return ret; +} +#undef silk_LSHIFT16 +static OPUS_INLINE opus_int16 silk_LSHIFT16(opus_int16 a, opus_int32 shift){ + opus_int16 ret; + ops_count += 1; + ret = a << shift; + return ret; +} +#undef silk_LSHIFT32 +static OPUS_INLINE opus_int32 silk_LSHIFT32(opus_int32 a, opus_int32 shift){ + opus_int32 ret; + ops_count += 1; + ret = a << shift; + return ret; +} +#undef silk_LSHIFT64 +static OPUS_INLINE opus_int64 silk_LSHIFT64(opus_int64 a, opus_int shift){ + ops_count += 1; + return a << shift; +} + +#undef silk_LSHIFT_ovflw +static OPUS_INLINE opus_int32 silk_LSHIFT_ovflw(opus_int32 a, opus_int32 shift){ + ops_count += 1; + return a << shift; +} + +#undef silk_LSHIFT_uint +static OPUS_INLINE opus_uint32 silk_LSHIFT_uint(opus_uint32 a, opus_int32 shift){ + opus_uint32 ret; + ops_count += 1; + ret = a << shift; + return ret; +} + +#undef silk_RSHIFT8 +static OPUS_INLINE opus_int8 silk_RSHIFT8(opus_int8 a, opus_int32 shift){ + ops_count += 1; + return a >> shift; +} +#undef silk_RSHIFT16 +static OPUS_INLINE opus_int16 silk_RSHIFT16(opus_int16 a, opus_int32 shift){ + ops_count += 1; + return a >> shift; +} +#undef silk_RSHIFT32 +static OPUS_INLINE opus_int32 silk_RSHIFT32(opus_int32 a, opus_int32 shift){ + ops_count += 1; + return a >> shift; +} +#undef silk_RSHIFT64 +static OPUS_INLINE opus_int64 silk_RSHIFT64(opus_int64 a, opus_int64 shift){ + ops_count += 1; + return a >> shift; +} + +#undef silk_RSHIFT_uint +static OPUS_INLINE opus_uint32 silk_RSHIFT_uint(opus_uint32 a, opus_int32 shift){ + ops_count += 1; + return a >> shift; +} + +#undef silk_ADD_LSHIFT +static OPUS_INLINE opus_int32 silk_ADD_LSHIFT(opus_int32 a, opus_int32 b, opus_int32 shift){ + opus_int32 ret; + ops_count += 1; + ret = a + (b << shift); + return ret; /* shift >= 0*/ +} +#undef silk_ADD_LSHIFT32 +static OPUS_INLINE opus_int32 silk_ADD_LSHIFT32(opus_int32 a, opus_int32 b, opus_int32 shift){ + opus_int32 ret; + ops_count += 1; + ret = a + (b << shift); + return ret; /* shift >= 0*/ +} +#undef silk_ADD_LSHIFT_uint +static OPUS_INLINE opus_uint32 silk_ADD_LSHIFT_uint(opus_uint32 a, opus_uint32 b, opus_int32 shift){ + opus_uint32 ret; + ops_count += 1; + ret = a + (b << shift); + return ret; /* shift >= 0*/ +} +#undef silk_ADD_RSHIFT +static OPUS_INLINE opus_int32 silk_ADD_RSHIFT(opus_int32 a, opus_int32 b, opus_int32 shift){ + opus_int32 ret; + ops_count += 1; + ret = a + (b >> shift); + return ret; /* shift > 0*/ +} +#undef silk_ADD_RSHIFT32 +static OPUS_INLINE opus_int32 silk_ADD_RSHIFT32(opus_int32 a, opus_int32 b, opus_int32 shift){ + opus_int32 ret; + ops_count += 1; + ret = a + (b >> shift); + return ret; /* shift > 0*/ +} +#undef silk_ADD_RSHIFT_uint +static OPUS_INLINE opus_uint32 silk_ADD_RSHIFT_uint(opus_uint32 a, opus_uint32 b, opus_int32 shift){ + opus_uint32 ret; + ops_count += 1; + ret = a + (b >> shift); + return ret; /* shift > 0*/ +} +#undef silk_SUB_LSHIFT32 +static OPUS_INLINE opus_int32 silk_SUB_LSHIFT32(opus_int32 a, opus_int32 b, opus_int32 shift){ + opus_int32 ret; + ops_count += 1; + ret = a - (b << shift); + return ret; /* shift >= 0*/ +} +#undef silk_SUB_RSHIFT32 +static OPUS_INLINE opus_int32 silk_SUB_RSHIFT32(opus_int32 a, opus_int32 b, opus_int32 shift){ + opus_int32 ret; + ops_count += 1; + ret = a - (b >> shift); + return ret; /* shift > 0*/ +} + +#undef silk_RSHIFT_ROUND +static OPUS_INLINE opus_int32 silk_RSHIFT_ROUND(opus_int32 a, opus_int32 shift){ + opus_int32 ret; + ops_count += 3; + ret = shift == 1 ? (a >> 1) + (a & 1) : ((a >> (shift - 1)) + 1) >> 1; + return ret; +} + +#undef silk_RSHIFT_ROUND64 +static OPUS_INLINE opus_int64 silk_RSHIFT_ROUND64(opus_int64 a, opus_int32 shift){ + opus_int64 ret; + ops_count += 6; + ret = shift == 1 ? (a >> 1) + (a & 1) : ((a >> (shift - 1)) + 1) >> 1; + return ret; +} + +#undef silk_abs_int64 +static OPUS_INLINE opus_int64 silk_abs_int64(opus_int64 a){ + ops_count += 1; + return (((a) > 0) ? (a) : -(a)); /* Be careful, silk_abs returns wrong when input equals to silk_intXX_MIN*/ +} + +#undef silk_abs_int32 +static OPUS_INLINE opus_int32 silk_abs_int32(opus_int32 a){ + ops_count += 1; + return silk_abs(a); +} + + +#undef silk_min +static silk_min(a, b){ + ops_count += 1; + return (((a) < (b)) ? (a) : (b)); +} +#undef silk_max +static silk_max(a, b){ + ops_count += 1; + return (((a) > (b)) ? (a) : (b)); +} +#undef silk_sign +static silk_sign(a){ + ops_count += 1; + return ((a) > 0 ? 1 : ( (a) < 0 ? -1 : 0 )); +} + +#undef silk_ADD16 +static OPUS_INLINE opus_int16 silk_ADD16(opus_int16 a, opus_int16 b){ + opus_int16 ret; + ops_count += 1; + ret = a + b; + return ret; +} + +#undef silk_ADD32 +static OPUS_INLINE opus_int32 silk_ADD32(opus_int32 a, opus_int32 b){ + opus_int32 ret; + ops_count += 1; + ret = a + b; + return ret; +} + +#undef silk_ADD64 +static OPUS_INLINE opus_int64 silk_ADD64(opus_int64 a, opus_int64 b){ + opus_int64 ret; + ops_count += 2; + ret = a + b; + return ret; +} + +#undef silk_SUB16 +static OPUS_INLINE opus_int16 silk_SUB16(opus_int16 a, opus_int16 b){ + opus_int16 ret; + ops_count += 1; + ret = a - b; + return ret; +} + +#undef silk_SUB32 +static OPUS_INLINE opus_int32 silk_SUB32(opus_int32 a, opus_int32 b){ + opus_int32 ret; + ops_count += 1; + ret = a - b; + return ret; +} + +#undef silk_SUB64 +static OPUS_INLINE opus_int64 silk_SUB64(opus_int64 a, opus_int64 b){ + opus_int64 ret; + ops_count += 2; + ret = a - b; + return ret; +} + +#undef silk_ADD_SAT16 +static OPUS_INLINE opus_int16 silk_ADD_SAT16( opus_int16 a16, opus_int16 b16 ) { + opus_int16 res; + /* Nb will be counted in AKP_add32 and silk_SAT16*/ + res = (opus_int16)silk_SAT16( silk_ADD32( (opus_int32)(a16), (b16) ) ); + return res; +} + +#undef silk_ADD_SAT32 +static OPUS_INLINE opus_int32 silk_ADD_SAT32(opus_int32 a32, opus_int32 b32){ + opus_int32 res; + ops_count += 1; + res = ((((a32) + (b32)) & 0x80000000) == 0 ? \ + ((((a32) & (b32)) & 0x80000000) != 0 ? silk_int32_MIN : (a32)+(b32)) : \ + ((((a32) | (b32)) & 0x80000000) == 0 ? silk_int32_MAX : (a32)+(b32)) ); + return res; +} + +#undef silk_ADD_SAT64 +static OPUS_INLINE opus_int64 silk_ADD_SAT64( opus_int64 a64, opus_int64 b64 ) { + opus_int64 res; + ops_count += 1; + res = ((((a64) + (b64)) & 0x8000000000000000LL) == 0 ? \ + ((((a64) & (b64)) & 0x8000000000000000LL) != 0 ? silk_int64_MIN : (a64)+(b64)) : \ + ((((a64) | (b64)) & 0x8000000000000000LL) == 0 ? silk_int64_MAX : (a64)+(b64)) ); + return res; +} + +#undef silk_SUB_SAT16 +static OPUS_INLINE opus_int16 silk_SUB_SAT16( opus_int16 a16, opus_int16 b16 ) { + opus_int16 res; + silk_assert(0); + /* Nb will be counted in sub-macros*/ + res = (opus_int16)silk_SAT16( silk_SUB32( (opus_int32)(a16), (b16) ) ); + return res; +} + +#undef silk_SUB_SAT32 +static OPUS_INLINE opus_int32 silk_SUB_SAT32( opus_int32 a32, opus_int32 b32 ) { + opus_int32 res; + ops_count += 1; + res = ((((a32)-(b32)) & 0x80000000) == 0 ? \ + (( (a32) & ((b32)^0x80000000) & 0x80000000) ? silk_int32_MIN : (a32)-(b32)) : \ + ((((a32)^0x80000000) & (b32) & 0x80000000) ? silk_int32_MAX : (a32)-(b32)) ); + return res; +} + +#undef silk_SUB_SAT64 +static OPUS_INLINE opus_int64 silk_SUB_SAT64( opus_int64 a64, opus_int64 b64 ) { + opus_int64 res; + ops_count += 1; + res = ((((a64)-(b64)) & 0x8000000000000000LL) == 0 ? \ + (( (a64) & ((b64)^0x8000000000000000LL) & 0x8000000000000000LL) ? silk_int64_MIN : (a64)-(b64)) : \ + ((((a64)^0x8000000000000000LL) & (b64) & 0x8000000000000000LL) ? silk_int64_MAX : (a64)-(b64)) ); + + return res; +} + +#undef silk_SMULWW +static OPUS_INLINE opus_int32 silk_SMULWW(opus_int32 a32, opus_int32 b32){ + opus_int32 ret; + /* Nb will be counted in sub-macros*/ + ret = silk_MLA(silk_SMULWB((a32), (b32)), (a32), silk_RSHIFT_ROUND((b32), 16)); + return ret; +} + +#undef silk_SMLAWW +static OPUS_INLINE opus_int32 silk_SMLAWW(opus_int32 a32, opus_int32 b32, opus_int32 c32){ + opus_int32 ret; + /* Nb will be counted in sub-macros*/ + ret = silk_MLA(silk_SMLAWB((a32), (b32), (c32)), (b32), silk_RSHIFT_ROUND((c32), 16)); + return ret; +} + +#undef silk_min_int +static OPUS_INLINE opus_int silk_min_int(opus_int a, opus_int b) +{ + ops_count += 1; + return (((a) < (b)) ? (a) : (b)); +} + +#undef silk_min_16 +static OPUS_INLINE opus_int16 silk_min_16(opus_int16 a, opus_int16 b) +{ + ops_count += 1; + return (((a) < (b)) ? (a) : (b)); +} +#undef silk_min_32 +static OPUS_INLINE opus_int32 silk_min_32(opus_int32 a, opus_int32 b) +{ + ops_count += 1; + return (((a) < (b)) ? (a) : (b)); +} +#undef silk_min_64 +static OPUS_INLINE opus_int64 silk_min_64(opus_int64 a, opus_int64 b) +{ + ops_count += 1; + return (((a) < (b)) ? (a) : (b)); +} + +/* silk_min() versions with typecast in the function call */ +#undef silk_max_int +static OPUS_INLINE opus_int silk_max_int(opus_int a, opus_int b) +{ + ops_count += 1; + return (((a) > (b)) ? (a) : (b)); +} +#undef silk_max_16 +static OPUS_INLINE opus_int16 silk_max_16(opus_int16 a, opus_int16 b) +{ + ops_count += 1; + return (((a) > (b)) ? (a) : (b)); +} +#undef silk_max_32 +static OPUS_INLINE opus_int32 silk_max_32(opus_int32 a, opus_int32 b) +{ + ops_count += 1; + return (((a) > (b)) ? (a) : (b)); +} + +#undef silk_max_64 +static OPUS_INLINE opus_int64 silk_max_64(opus_int64 a, opus_int64 b) +{ + ops_count += 1; + return (((a) > (b)) ? (a) : (b)); +} + + +#undef silk_LIMIT_int +static OPUS_INLINE opus_int silk_LIMIT_int(opus_int a, opus_int limit1, opus_int limit2) +{ + opus_int ret; + ops_count += 6; + + ret = ((limit1) > (limit2) ? ((a) > (limit1) ? (limit1) : ((a) < (limit2) ? (limit2) : (a))) \ + : ((a) > (limit2) ? (limit2) : ((a) < (limit1) ? (limit1) : (a)))); + + return(ret); +} + +#undef silk_LIMIT_16 +static OPUS_INLINE opus_int16 silk_LIMIT_16(opus_int16 a, opus_int16 limit1, opus_int16 limit2) +{ + opus_int16 ret; + ops_count += 6; + + ret = ((limit1) > (limit2) ? ((a) > (limit1) ? (limit1) : ((a) < (limit2) ? (limit2) : (a))) \ + : ((a) > (limit2) ? (limit2) : ((a) < (limit1) ? (limit1) : (a)))); + +return(ret); +} + + +#undef silk_LIMIT_32 +static OPUS_INLINE opus_int silk_LIMIT_32(opus_int32 a, opus_int32 limit1, opus_int32 limit2) +{ + opus_int32 ret; + ops_count += 6; + + ret = ((limit1) > (limit2) ? ((a) > (limit1) ? (limit1) : ((a) < (limit2) ? (limit2) : (a))) \ + : ((a) > (limit2) ? (limit2) : ((a) < (limit1) ? (limit1) : (a)))); + return(ret); +} + +#else +#define varDefine +#define silk_SaveCount() + +#endif +#endif + diff --git a/src/opus-1.1/silk/MacroDebug.h b/src/opus-1.1/silk/MacroDebug.h new file mode 100644 index 00000000..35aedc5c --- /dev/null +++ b/src/opus-1.1/silk/MacroDebug.h @@ -0,0 +1,952 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Copyright (C) 2012 Xiph.Org Foundation +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifndef MACRO_DEBUG_H +#define MACRO_DEBUG_H + +/* Redefine macro functions with extensive assertion in DEBUG mode. + As functions can't be undefined, this file can't work with SigProcFIX_MacroCount.h */ + +#if ( defined (FIXED_DEBUG) || ( 0 && defined (_DEBUG) ) ) && !defined (silk_MACRO_COUNT) + +#undef silk_ADD16 +#define silk_ADD16(a,b) silk_ADD16_((a), (b), __FILE__, __LINE__) +static OPUS_INLINE opus_int16 silk_ADD16_(opus_int16 a, opus_int16 b, char *file, int line){ + opus_int16 ret; + + ret = a + b; + if ( ret != silk_ADD_SAT16( a, b ) ) + { + fprintf (stderr, "silk_ADD16(%d, %d) in %s: line %d\n", a, b, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return ret; +} + +#undef silk_ADD32 +#define silk_ADD32(a,b) silk_ADD32_((a), (b), __FILE__, __LINE__) +static OPUS_INLINE opus_int32 silk_ADD32_(opus_int32 a, opus_int32 b, char *file, int line){ + opus_int32 ret; + + ret = a + b; + if ( ret != silk_ADD_SAT32( a, b ) ) + { + fprintf (stderr, "silk_ADD32(%d, %d) in %s: line %d\n", a, b, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return ret; +} + +#undef silk_ADD64 +#define silk_ADD64(a,b) silk_ADD64_((a), (b), __FILE__, __LINE__) +static OPUS_INLINE opus_int64 silk_ADD64_(opus_int64 a, opus_int64 b, char *file, int line){ + opus_int64 ret; + + ret = a + b; + if ( ret != silk_ADD_SAT64( a, b ) ) + { + fprintf (stderr, "silk_ADD64(%lld, %lld) in %s: line %d\n", (long long)a, (long long)b, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return ret; +} + +#undef silk_SUB16 +#define silk_SUB16(a,b) silk_SUB16_((a), (b), __FILE__, __LINE__) +static OPUS_INLINE opus_int16 silk_SUB16_(opus_int16 a, opus_int16 b, char *file, int line){ + opus_int16 ret; + + ret = a - b; + if ( ret != silk_SUB_SAT16( a, b ) ) + { + fprintf (stderr, "silk_SUB16(%d, %d) in %s: line %d\n", a, b, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return ret; +} + +#undef silk_SUB32 +#define silk_SUB32(a,b) silk_SUB32_((a), (b), __FILE__, __LINE__) +static OPUS_INLINE opus_int32 silk_SUB32_(opus_int32 a, opus_int32 b, char *file, int line){ + opus_int32 ret; + + ret = a - b; + if ( ret != silk_SUB_SAT32( a, b ) ) + { + fprintf (stderr, "silk_SUB32(%d, %d) in %s: line %d\n", a, b, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return ret; +} + +#undef silk_SUB64 +#define silk_SUB64(a,b) silk_SUB64_((a), (b), __FILE__, __LINE__) +static OPUS_INLINE opus_int64 silk_SUB64_(opus_int64 a, opus_int64 b, char *file, int line){ + opus_int64 ret; + + ret = a - b; + if ( ret != silk_SUB_SAT64( a, b ) ) + { + fprintf (stderr, "silk_SUB64(%lld, %lld) in %s: line %d\n", (long long)a, (long long)b, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return ret; +} + +#undef silk_ADD_SAT16 +#define silk_ADD_SAT16(a,b) silk_ADD_SAT16_((a), (b), __FILE__, __LINE__) +static OPUS_INLINE opus_int16 silk_ADD_SAT16_( opus_int16 a16, opus_int16 b16, char *file, int line) { + opus_int16 res; + res = (opus_int16)silk_SAT16( silk_ADD32( (opus_int32)(a16), (b16) ) ); + if ( res != silk_SAT16( (opus_int32)a16 + (opus_int32)b16 ) ) + { + fprintf (stderr, "silk_ADD_SAT16(%d, %d) in %s: line %d\n", a16, b16, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return res; +} + +#undef silk_ADD_SAT32 +#define silk_ADD_SAT32(a,b) silk_ADD_SAT32_((a), (b), __FILE__, __LINE__) +static OPUS_INLINE opus_int32 silk_ADD_SAT32_(opus_int32 a32, opus_int32 b32, char *file, int line){ + opus_int32 res; + res = ((((opus_uint32)(a32) + (opus_uint32)(b32)) & 0x80000000) == 0 ? \ + ((((a32) & (b32)) & 0x80000000) != 0 ? silk_int32_MIN : (a32)+(b32)) : \ + ((((a32) | (b32)) & 0x80000000) == 0 ? silk_int32_MAX : (a32)+(b32)) ); + if ( res != silk_SAT32( (opus_int64)a32 + (opus_int64)b32 ) ) + { + fprintf (stderr, "silk_ADD_SAT32(%d, %d) in %s: line %d\n", a32, b32, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return res; +} + +#undef silk_ADD_SAT64 +#define silk_ADD_SAT64(a,b) silk_ADD_SAT64_((a), (b), __FILE__, __LINE__) +static OPUS_INLINE opus_int64 silk_ADD_SAT64_( opus_int64 a64, opus_int64 b64, char *file, int line) { + opus_int64 res; + int fail = 0; + res = ((((a64) + (b64)) & 0x8000000000000000LL) == 0 ? \ + ((((a64) & (b64)) & 0x8000000000000000LL) != 0 ? silk_int64_MIN : (a64)+(b64)) : \ + ((((a64) | (b64)) & 0x8000000000000000LL) == 0 ? silk_int64_MAX : (a64)+(b64)) ); + if( res != a64 + b64 ) { + /* Check that we saturated to the correct extreme value */ + if ( !(( res == silk_int64_MAX && ( ( a64 >> 1 ) + ( b64 >> 1 ) > ( silk_int64_MAX >> 3 ) ) ) || + ( res == silk_int64_MIN && ( ( a64 >> 1 ) + ( b64 >> 1 ) < ( silk_int64_MIN >> 3 ) ) ) ) ) + { + fail = 1; + } + } else { + /* Saturation not necessary */ + fail = res != a64 + b64; + } + if ( fail ) + { + fprintf (stderr, "silk_ADD_SAT64(%lld, %lld) in %s: line %d\n", (long long)a64, (long long)b64, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return res; +} + +#undef silk_SUB_SAT16 +#define silk_SUB_SAT16(a,b) silk_SUB_SAT16_((a), (b), __FILE__, __LINE__) +static OPUS_INLINE opus_int16 silk_SUB_SAT16_( opus_int16 a16, opus_int16 b16, char *file, int line ) { + opus_int16 res; + res = (opus_int16)silk_SAT16( silk_SUB32( (opus_int32)(a16), (b16) ) ); + if ( res != silk_SAT16( (opus_int32)a16 - (opus_int32)b16 ) ) + { + fprintf (stderr, "silk_SUB_SAT16(%d, %d) in %s: line %d\n", a16, b16, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return res; +} + +#undef silk_SUB_SAT32 +#define silk_SUB_SAT32(a,b) silk_SUB_SAT32_((a), (b), __FILE__, __LINE__) +static OPUS_INLINE opus_int32 silk_SUB_SAT32_( opus_int32 a32, opus_int32 b32, char *file, int line ) { + opus_int32 res; + res = ((((opus_uint32)(a32)-(opus_uint32)(b32)) & 0x80000000) == 0 ? \ + (( (a32) & ((b32)^0x80000000) & 0x80000000) ? silk_int32_MIN : (a32)-(b32)) : \ + ((((a32)^0x80000000) & (b32) & 0x80000000) ? silk_int32_MAX : (a32)-(b32)) ); + if ( res != silk_SAT32( (opus_int64)a32 - (opus_int64)b32 ) ) + { + fprintf (stderr, "silk_SUB_SAT32(%d, %d) in %s: line %d\n", a32, b32, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return res; +} + +#undef silk_SUB_SAT64 +#define silk_SUB_SAT64(a,b) silk_SUB_SAT64_((a), (b), __FILE__, __LINE__) +static OPUS_INLINE opus_int64 silk_SUB_SAT64_( opus_int64 a64, opus_int64 b64, char *file, int line ) { + opus_int64 res; + int fail = 0; + res = ((((a64)-(b64)) & 0x8000000000000000LL) == 0 ? \ + (( (a64) & ((b64)^0x8000000000000000LL) & 0x8000000000000000LL) ? silk_int64_MIN : (a64)-(b64)) : \ + ((((a64)^0x8000000000000000LL) & (b64) & 0x8000000000000000LL) ? silk_int64_MAX : (a64)-(b64)) ); + if( res != a64 - b64 ) { + /* Check that we saturated to the correct extreme value */ + if( !(( res == silk_int64_MAX && ( ( a64 >> 1 ) + ( b64 >> 1 ) > ( silk_int64_MAX >> 3 ) ) ) || + ( res == silk_int64_MIN && ( ( a64 >> 1 ) + ( b64 >> 1 ) < ( silk_int64_MIN >> 3 ) ) ) )) + { + fail = 1; + } + } else { + /* Saturation not necessary */ + fail = res != a64 - b64; + } + if ( fail ) + { + fprintf (stderr, "silk_SUB_SAT64(%lld, %lld) in %s: line %d\n", (long long)a64, (long long)b64, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return res; +} + +#undef silk_MUL +#define silk_MUL(a,b) silk_MUL_((a), (b), __FILE__, __LINE__) +static OPUS_INLINE opus_int32 silk_MUL_(opus_int32 a32, opus_int32 b32, char *file, int line){ + opus_int32 ret; + opus_int64 ret64; + ret = a32 * b32; + ret64 = (opus_int64)a32 * (opus_int64)b32; + if ( (opus_int64)ret != ret64 ) + { + fprintf (stderr, "silk_MUL(%d, %d) in %s: line %d\n", a32, b32, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return ret; +} + +#undef silk_MUL_uint +#define silk_MUL_uint(a,b) silk_MUL_uint_((a), (b), __FILE__, __LINE__) +static OPUS_INLINE opus_uint32 silk_MUL_uint_(opus_uint32 a32, opus_uint32 b32, char *file, int line){ + opus_uint32 ret; + ret = a32 * b32; + if ( (opus_uint64)ret != (opus_uint64)a32 * (opus_uint64)b32 ) + { + fprintf (stderr, "silk_MUL_uint(%u, %u) in %s: line %d\n", a32, b32, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return ret; +} + +#undef silk_MLA +#define silk_MLA(a,b,c) silk_MLA_((a), (b), (c), __FILE__, __LINE__) +static OPUS_INLINE opus_int32 silk_MLA_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){ + opus_int32 ret; + ret = a32 + b32 * c32; + if ( (opus_int64)ret != (opus_int64)a32 + (opus_int64)b32 * (opus_int64)c32 ) + { + fprintf (stderr, "silk_MLA(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return ret; +} + +#undef silk_MLA_uint +#define silk_MLA_uint(a,b,c) silk_MLA_uint_((a), (b), (c), __FILE__, __LINE__) +static OPUS_INLINE opus_int32 silk_MLA_uint_(opus_uint32 a32, opus_uint32 b32, opus_uint32 c32, char *file, int line){ + opus_uint32 ret; + ret = a32 + b32 * c32; + if ( (opus_int64)ret != (opus_int64)a32 + (opus_int64)b32 * (opus_int64)c32 ) + { + fprintf (stderr, "silk_MLA_uint(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return ret; +} + +#undef silk_SMULWB +#define silk_SMULWB(a,b) silk_SMULWB_((a), (b), __FILE__, __LINE__) +static OPUS_INLINE opus_int32 silk_SMULWB_(opus_int32 a32, opus_int32 b32, char *file, int line){ + opus_int32 ret; + ret = (a32 >> 16) * (opus_int32)((opus_int16)b32) + (((a32 & 0x0000FFFF) * (opus_int32)((opus_int16)b32)) >> 16); + if ( (opus_int64)ret != ((opus_int64)a32 * (opus_int16)b32) >> 16 ) + { + fprintf (stderr, "silk_SMULWB(%d, %d) in %s: line %d\n", a32, b32, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return ret; +} + +#undef silk_SMLAWB +#define silk_SMLAWB(a,b,c) silk_SMLAWB_((a), (b), (c), __FILE__, __LINE__) +static OPUS_INLINE opus_int32 silk_SMLAWB_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){ + opus_int32 ret; + ret = silk_ADD32( a32, silk_SMULWB( b32, c32 ) ); + if ( silk_ADD32( a32, silk_SMULWB( b32, c32 ) ) != silk_ADD_SAT32( a32, silk_SMULWB( b32, c32 ) ) ) + { + fprintf (stderr, "silk_SMLAWB(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return ret; +} + +#undef silk_SMULWT +#define silk_SMULWT(a,b) silk_SMULWT_((a), (b), __FILE__, __LINE__) +static OPUS_INLINE opus_int32 silk_SMULWT_(opus_int32 a32, opus_int32 b32, char *file, int line){ + opus_int32 ret; + ret = (a32 >> 16) * (b32 >> 16) + (((a32 & 0x0000FFFF) * (b32 >> 16)) >> 16); + if ( (opus_int64)ret != ((opus_int64)a32 * (b32 >> 16)) >> 16 ) + { + fprintf (stderr, "silk_SMULWT(%d, %d) in %s: line %d\n", a32, b32, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return ret; +} + +#undef silk_SMLAWT +#define silk_SMLAWT(a,b,c) silk_SMLAWT_((a), (b), (c), __FILE__, __LINE__) +static OPUS_INLINE opus_int32 silk_SMLAWT_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){ + opus_int32 ret; + ret = a32 + ((b32 >> 16) * (c32 >> 16)) + (((b32 & 0x0000FFFF) * ((c32 >> 16)) >> 16)); + if ( (opus_int64)ret != (opus_int64)a32 + (((opus_int64)b32 * (c32 >> 16)) >> 16) ) + { + fprintf (stderr, "silk_SMLAWT(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return ret; +} + +#undef silk_SMULL +#define silk_SMULL(a,b) silk_SMULL_((a), (b), __FILE__, __LINE__) +static OPUS_INLINE opus_int64 silk_SMULL_(opus_int64 a64, opus_int64 b64, char *file, int line){ + opus_int64 ret64; + int fail = 0; + ret64 = a64 * b64; + if( b64 != 0 ) { + fail = a64 != (ret64 / b64); + } else if( a64 != 0 ) { + fail = b64 != (ret64 / a64); + } + if ( fail ) + { + fprintf (stderr, "silk_SMULL(%lld, %lld) in %s: line %d\n", (long long)a64, (long long)b64, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return ret64; +} + +/* no checking needed for silk_SMULBB */ +#undef silk_SMLABB +#define silk_SMLABB(a,b,c) silk_SMLABB_((a), (b), (c), __FILE__, __LINE__) +static OPUS_INLINE opus_int32 silk_SMLABB_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){ + opus_int32 ret; + ret = a32 + (opus_int32)((opus_int16)b32) * (opus_int32)((opus_int16)c32); + if ( (opus_int64)ret != (opus_int64)a32 + (opus_int64)b32 * (opus_int16)c32 ) + { + fprintf (stderr, "silk_SMLABB(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return ret; +} + +/* no checking needed for silk_SMULBT */ +#undef silk_SMLABT +#define silk_SMLABT(a,b,c) silk_SMLABT_((a), (b), (c), __FILE__, __LINE__) +static OPUS_INLINE opus_int32 silk_SMLABT_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){ + opus_int32 ret; + ret = a32 + ((opus_int32)((opus_int16)b32)) * (c32 >> 16); + if ( (opus_int64)ret != (opus_int64)a32 + (opus_int64)b32 * (c32 >> 16) ) + { + fprintf (stderr, "silk_SMLABT(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return ret; +} + +/* no checking needed for silk_SMULTT */ +#undef silk_SMLATT +#define silk_SMLATT(a,b,c) silk_SMLATT_((a), (b), (c), __FILE__, __LINE__) +static OPUS_INLINE opus_int32 silk_SMLATT_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){ + opus_int32 ret; + ret = a32 + (b32 >> 16) * (c32 >> 16); + if ( (opus_int64)ret != (opus_int64)a32 + (b32 >> 16) * (c32 >> 16) ) + { + fprintf (stderr, "silk_SMLATT(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return ret; +} + +#undef silk_SMULWW +#define silk_SMULWW(a,b) silk_SMULWW_((a), (b), __FILE__, __LINE__) +static OPUS_INLINE opus_int32 silk_SMULWW_(opus_int32 a32, opus_int32 b32, char *file, int line){ + opus_int32 ret, tmp1, tmp2; + opus_int64 ret64; + int fail = 0; + + ret = silk_SMULWB( a32, b32 ); + tmp1 = silk_RSHIFT_ROUND( b32, 16 ); + tmp2 = silk_MUL( a32, tmp1 ); + + fail |= (opus_int64)tmp2 != (opus_int64) a32 * (opus_int64) tmp1; + + tmp1 = ret; + ret = silk_ADD32( tmp1, tmp2 ); + fail |= silk_ADD32( tmp1, tmp2 ) != silk_ADD_SAT32( tmp1, tmp2 ); + + ret64 = silk_RSHIFT64( silk_SMULL( a32, b32 ), 16 ); + fail |= (opus_int64)ret != ret64; + + if ( fail ) + { + fprintf (stderr, "silk_SMULWT(%d, %d) in %s: line %d\n", a32, b32, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + + return ret; +} + +#undef silk_SMLAWW +#define silk_SMLAWW(a,b,c) silk_SMLAWW_((a), (b), (c), __FILE__, __LINE__) +static OPUS_INLINE opus_int32 silk_SMLAWW_(opus_int32 a32, opus_int32 b32, opus_int32 c32, char *file, int line){ + opus_int32 ret, tmp; + + tmp = silk_SMULWW( b32, c32 ); + ret = silk_ADD32( a32, tmp ); + if ( ret != silk_ADD_SAT32( a32, tmp ) ) + { + fprintf (stderr, "silk_SMLAWW(%d, %d, %d) in %s: line %d\n", a32, b32, c32, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return ret; +} + +/* Multiply-accumulate macros that allow overflow in the addition (ie, no asserts in debug mode) */ +#undef silk_MLA_ovflw +#define silk_MLA_ovflw(a32, b32, c32) ((a32) + ((b32) * (c32))) +#undef silk_SMLABB_ovflw +#define silk_SMLABB_ovflw(a32, b32, c32) ((a32) + ((opus_int32)((opus_int16)(b32))) * (opus_int32)((opus_int16)(c32))) + +/* no checking needed for silk_SMULL + no checking needed for silk_SMLAL + no checking needed for silk_SMLALBB + no checking needed for SigProcFIX_CLZ16 + no checking needed for SigProcFIX_CLZ32*/ + +#undef silk_DIV32 +#define silk_DIV32(a,b) silk_DIV32_((a), (b), __FILE__, __LINE__) +static OPUS_INLINE opus_int32 silk_DIV32_(opus_int32 a32, opus_int32 b32, char *file, int line){ + if ( b32 == 0 ) + { + fprintf (stderr, "silk_DIV32(%d, %d) in %s: line %d\n", a32, b32, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return a32 / b32; +} + +#undef silk_DIV32_16 +#define silk_DIV32_16(a,b) silk_DIV32_16_((a), (b), __FILE__, __LINE__) +static OPUS_INLINE opus_int32 silk_DIV32_16_(opus_int32 a32, opus_int32 b32, char *file, int line){ + int fail = 0; + fail |= b32 == 0; + fail |= b32 > silk_int16_MAX; + fail |= b32 < silk_int16_MIN; + if ( fail ) + { + fprintf (stderr, "silk_DIV32_16(%d, %d) in %s: line %d\n", a32, b32, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return a32 / b32; +} + +/* no checking needed for silk_SAT8 + no checking needed for silk_SAT16 + no checking needed for silk_SAT32 + no checking needed for silk_POS_SAT32 + no checking needed for silk_ADD_POS_SAT8 + no checking needed for silk_ADD_POS_SAT16 + no checking needed for silk_ADD_POS_SAT32 + no checking needed for silk_ADD_POS_SAT64 */ + +#undef silk_LSHIFT8 +#define silk_LSHIFT8(a,b) silk_LSHIFT8_((a), (b), __FILE__, __LINE__) +static OPUS_INLINE opus_int8 silk_LSHIFT8_(opus_int8 a, opus_int32 shift, char *file, int line){ + opus_int8 ret; + int fail = 0; + ret = a << shift; + fail |= shift < 0; + fail |= shift >= 8; + fail |= (opus_int64)ret != ((opus_int64)a) << shift; + if ( fail ) + { + fprintf (stderr, "silk_LSHIFT8(%d, %d) in %s: line %d\n", a, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return ret; +} + +#undef silk_LSHIFT16 +#define silk_LSHIFT16(a,b) silk_LSHIFT16_((a), (b), __FILE__, __LINE__) +static OPUS_INLINE opus_int16 silk_LSHIFT16_(opus_int16 a, opus_int32 shift, char *file, int line){ + opus_int16 ret; + int fail = 0; + ret = a << shift; + fail |= shift < 0; + fail |= shift >= 16; + fail |= (opus_int64)ret != ((opus_int64)a) << shift; + if ( fail ) + { + fprintf (stderr, "silk_LSHIFT16(%d, %d) in %s: line %d\n", a, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return ret; +} + +#undef silk_LSHIFT32 +#define silk_LSHIFT32(a,b) silk_LSHIFT32_((a), (b), __FILE__, __LINE__) +static OPUS_INLINE opus_int32 silk_LSHIFT32_(opus_int32 a, opus_int32 shift, char *file, int line){ + opus_int32 ret; + int fail = 0; + ret = a << shift; + fail |= shift < 0; + fail |= shift >= 32; + fail |= (opus_int64)ret != ((opus_int64)a) << shift; + if ( fail ) + { + fprintf (stderr, "silk_LSHIFT32(%d, %d) in %s: line %d\n", a, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return ret; +} + +#undef silk_LSHIFT64 +#define silk_LSHIFT64(a,b) silk_LSHIFT64_((a), (b), __FILE__, __LINE__) +static OPUS_INLINE opus_int64 silk_LSHIFT64_(opus_int64 a, opus_int shift, char *file, int line){ + opus_int64 ret; + int fail = 0; + ret = a << shift; + fail |= shift < 0; + fail |= shift >= 64; + fail |= (ret>>shift) != ((opus_int64)a); + if ( fail ) + { + fprintf (stderr, "silk_LSHIFT64(%lld, %d) in %s: line %d\n", (long long)a, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return ret; +} + +#undef silk_LSHIFT_ovflw +#define silk_LSHIFT_ovflw(a,b) silk_LSHIFT_ovflw_((a), (b), __FILE__, __LINE__) +static OPUS_INLINE opus_int32 silk_LSHIFT_ovflw_(opus_int32 a, opus_int32 shift, char *file, int line){ + if ( (shift < 0) || (shift >= 32) ) /* no check for overflow */ + { + fprintf (stderr, "silk_LSHIFT_ovflw(%d, %d) in %s: line %d\n", a, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return a << shift; +} + +#undef silk_LSHIFT_uint +#define silk_LSHIFT_uint(a,b) silk_LSHIFT_uint_((a), (b), __FILE__, __LINE__) +static OPUS_INLINE opus_uint32 silk_LSHIFT_uint_(opus_uint32 a, opus_int32 shift, char *file, int line){ + opus_uint32 ret; + ret = a << shift; + if ( (shift < 0) || ((opus_int64)ret != ((opus_int64)a) << shift)) + { + fprintf (stderr, "silk_LSHIFT_uint(%u, %d) in %s: line %d\n", a, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return ret; +} + +#undef silk_RSHIFT8 +#define silk_RSHITF8(a,b) silk_RSHIFT8_((a), (b), __FILE__, __LINE__) +static OPUS_INLINE opus_int8 silk_RSHIFT8_(opus_int8 a, opus_int32 shift, char *file, int line){ + if ( (shift < 0) || (shift>=8) ) + { + fprintf (stderr, "silk_RSHITF8(%d, %d) in %s: line %d\n", a, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return a >> shift; +} + +#undef silk_RSHIFT16 +#define silk_RSHITF16(a,b) silk_RSHIFT16_((a), (b), __FILE__, __LINE__) +static OPUS_INLINE opus_int16 silk_RSHIFT16_(opus_int16 a, opus_int32 shift, char *file, int line){ + if ( (shift < 0) || (shift>=16) ) + { + fprintf (stderr, "silk_RSHITF16(%d, %d) in %s: line %d\n", a, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return a >> shift; +} + +#undef silk_RSHIFT32 +#define silk_RSHIFT32(a,b) silk_RSHIFT32_((a), (b), __FILE__, __LINE__) +static OPUS_INLINE opus_int32 silk_RSHIFT32_(opus_int32 a, opus_int32 shift, char *file, int line){ + if ( (shift < 0) || (shift>=32) ) + { + fprintf (stderr, "silk_RSHITF32(%d, %d) in %s: line %d\n", a, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return a >> shift; +} + +#undef silk_RSHIFT64 +#define silk_RSHIFT64(a,b) silk_RSHIFT64_((a), (b), __FILE__, __LINE__) +static OPUS_INLINE opus_int64 silk_RSHIFT64_(opus_int64 a, opus_int64 shift, char *file, int line){ + if ( (shift < 0) || (shift>=64) ) + { + fprintf (stderr, "silk_RSHITF64(%lld, %lld) in %s: line %d\n", (long long)a, (long long)shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return a >> shift; +} + +#undef silk_RSHIFT_uint +#define silk_RSHIFT_uint(a,b) silk_RSHIFT_uint_((a), (b), __FILE__, __LINE__) +static OPUS_INLINE opus_uint32 silk_RSHIFT_uint_(opus_uint32 a, opus_int32 shift, char *file, int line){ + if ( (shift < 0) || (shift>32) ) + { + fprintf (stderr, "silk_RSHIFT_uint(%u, %d) in %s: line %d\n", a, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return a >> shift; +} + +#undef silk_ADD_LSHIFT +#define silk_ADD_LSHIFT(a,b,c) silk_ADD_LSHIFT_((a), (b), (c), __FILE__, __LINE__) +static OPUS_INLINE int silk_ADD_LSHIFT_(int a, int b, int shift, char *file, int line){ + opus_int16 ret; + ret = a + (b << shift); + if ( (shift < 0) || (shift>15) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) << shift)) ) + { + fprintf (stderr, "silk_ADD_LSHIFT(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return ret; /* shift >= 0 */ +} + +#undef silk_ADD_LSHIFT32 +#define silk_ADD_LSHIFT32(a,b,c) silk_ADD_LSHIFT32_((a), (b), (c), __FILE__, __LINE__) +static OPUS_INLINE opus_int32 silk_ADD_LSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){ + opus_int32 ret; + ret = a + (b << shift); + if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) << shift)) ) + { + fprintf (stderr, "silk_ADD_LSHIFT32(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return ret; /* shift >= 0 */ +} + +#undef silk_ADD_LSHIFT_uint +#define silk_ADD_LSHIFT_uint(a,b,c) silk_ADD_LSHIFT_uint_((a), (b), (c), __FILE__, __LINE__) +static OPUS_INLINE opus_uint32 silk_ADD_LSHIFT_uint_(opus_uint32 a, opus_uint32 b, opus_int32 shift, char *file, int line){ + opus_uint32 ret; + ret = a + (b << shift); + if ( (shift < 0) || (shift>32) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) << shift)) ) + { + fprintf (stderr, "silk_ADD_LSHIFT_uint(%u, %u, %d) in %s: line %d\n", a, b, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return ret; /* shift >= 0 */ +} + +#undef silk_ADD_RSHIFT +#define silk_ADD_RSHIFT(a,b,c) silk_ADD_RSHIFT_((a), (b), (c), __FILE__, __LINE__) +static OPUS_INLINE int silk_ADD_RSHIFT_(int a, int b, int shift, char *file, int line){ + opus_int16 ret; + ret = a + (b >> shift); + if ( (shift < 0) || (shift>15) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) >> shift)) ) + { + fprintf (stderr, "silk_ADD_RSHIFT(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return ret; /* shift > 0 */ +} + +#undef silk_ADD_RSHIFT32 +#define silk_ADD_RSHIFT32(a,b,c) silk_ADD_RSHIFT32_((a), (b), (c), __FILE__, __LINE__) +static OPUS_INLINE opus_int32 silk_ADD_RSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){ + opus_int32 ret; + ret = a + (b >> shift); + if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) >> shift)) ) + { + fprintf (stderr, "silk_ADD_RSHIFT32(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return ret; /* shift > 0 */ +} + +#undef silk_ADD_RSHIFT_uint +#define silk_ADD_RSHIFT_uint(a,b,c) silk_ADD_RSHIFT_uint_((a), (b), (c), __FILE__, __LINE__) +static OPUS_INLINE opus_uint32 silk_ADD_RSHIFT_uint_(opus_uint32 a, opus_uint32 b, opus_int32 shift, char *file, int line){ + opus_uint32 ret; + ret = a + (b >> shift); + if ( (shift < 0) || (shift>32) || ((opus_int64)ret != (opus_int64)a + (((opus_int64)b) >> shift)) ) + { + fprintf (stderr, "silk_ADD_RSHIFT_uint(%u, %u, %d) in %s: line %d\n", a, b, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return ret; /* shift > 0 */ +} + +#undef silk_SUB_LSHIFT32 +#define silk_SUB_LSHIFT32(a,b,c) silk_SUB_LSHIFT32_((a), (b), (c), __FILE__, __LINE__) +static OPUS_INLINE opus_int32 silk_SUB_LSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){ + opus_int32 ret; + ret = a - (b << shift); + if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a - (((opus_int64)b) << shift)) ) + { + fprintf (stderr, "silk_SUB_LSHIFT32(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return ret; /* shift >= 0 */ +} + +#undef silk_SUB_RSHIFT32 +#define silk_SUB_RSHIFT32(a,b,c) silk_SUB_RSHIFT32_((a), (b), (c), __FILE__, __LINE__) +static OPUS_INLINE opus_int32 silk_SUB_RSHIFT32_(opus_int32 a, opus_int32 b, opus_int32 shift, char *file, int line){ + opus_int32 ret; + ret = a - (b >> shift); + if ( (shift < 0) || (shift>31) || ((opus_int64)ret != (opus_int64)a - (((opus_int64)b) >> shift)) ) + { + fprintf (stderr, "silk_SUB_RSHIFT32(%d, %d, %d) in %s: line %d\n", a, b, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return ret; /* shift > 0 */ +} + +#undef silk_RSHIFT_ROUND +#define silk_RSHIFT_ROUND(a,b) silk_RSHIFT_ROUND_((a), (b), __FILE__, __LINE__) +static OPUS_INLINE opus_int32 silk_RSHIFT_ROUND_(opus_int32 a, opus_int32 shift, char *file, int line){ + opus_int32 ret; + ret = shift == 1 ? (a >> 1) + (a & 1) : ((a >> (shift - 1)) + 1) >> 1; + /* the marco definition can't handle a shift of zero */ + if ( (shift <= 0) || (shift>31) || ((opus_int64)ret != ((opus_int64)a + ((opus_int64)1 << (shift - 1))) >> shift) ) + { + fprintf (stderr, "silk_RSHIFT_ROUND(%d, %d) in %s: line %d\n", a, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return ret; +} + +#undef silk_RSHIFT_ROUND64 +#define silk_RSHIFT_ROUND64(a,b) silk_RSHIFT_ROUND64_((a), (b), __FILE__, __LINE__) +static OPUS_INLINE opus_int64 silk_RSHIFT_ROUND64_(opus_int64 a, opus_int32 shift, char *file, int line){ + opus_int64 ret; + /* the marco definition can't handle a shift of zero */ + if ( (shift <= 0) || (shift>=64) ) + { + fprintf (stderr, "silk_RSHIFT_ROUND64(%lld, %d) in %s: line %d\n", (long long)a, shift, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + ret = shift == 1 ? (a >> 1) + (a & 1) : ((a >> (shift - 1)) + 1) >> 1; + return ret; +} + +/* silk_abs is used on floats also, so doesn't work... */ +/*#undef silk_abs +static OPUS_INLINE opus_int32 silk_abs(opus_int32 a){ + silk_assert(a != 0x80000000); + return (((a) > 0) ? (a) : -(a)); // Be careful, silk_abs returns wrong when input equals to silk_intXX_MIN +}*/ + +#undef silk_abs_int64 +#define silk_abs_int64(a) silk_abs_int64_((a), __FILE__, __LINE__) +static OPUS_INLINE opus_int64 silk_abs_int64_(opus_int64 a, char *file, int line){ + if ( a == silk_int64_MIN ) + { + fprintf (stderr, "silk_abs_int64(%lld) in %s: line %d\n", (long long)a, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return (((a) > 0) ? (a) : -(a)); /* Be careful, silk_abs returns wrong when input equals to silk_intXX_MIN */ +} + +#undef silk_abs_int32 +#define silk_abs_int32(a) silk_abs_int32_((a), __FILE__, __LINE__) +static OPUS_INLINE opus_int32 silk_abs_int32_(opus_int32 a, char *file, int line){ + if ( a == silk_int32_MIN ) + { + fprintf (stderr, "silk_abs_int32(%d) in %s: line %d\n", a, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return silk_abs(a); +} + +#undef silk_CHECK_FIT8 +#define silk_CHECK_FIT8(a) silk_CHECK_FIT8_((a), __FILE__, __LINE__) +static OPUS_INLINE opus_int8 silk_CHECK_FIT8_( opus_int64 a, char *file, int line ){ + opus_int8 ret; + ret = (opus_int8)a; + if ( (opus_int64)ret != a ) + { + fprintf (stderr, "silk_CHECK_FIT8(%lld) in %s: line %d\n", (long long)a, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return( ret ); +} + +#undef silk_CHECK_FIT16 +#define silk_CHECK_FIT16(a) silk_CHECK_FIT16_((a), __FILE__, __LINE__) +static OPUS_INLINE opus_int16 silk_CHECK_FIT16_( opus_int64 a, char *file, int line ){ + opus_int16 ret; + ret = (opus_int16)a; + if ( (opus_int64)ret != a ) + { + fprintf (stderr, "silk_CHECK_FIT16(%lld) in %s: line %d\n", (long long)a, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return( ret ); +} + +#undef silk_CHECK_FIT32 +#define silk_CHECK_FIT32(a) silk_CHECK_FIT32_((a), __FILE__, __LINE__) +static OPUS_INLINE opus_int32 silk_CHECK_FIT32_( opus_int64 a, char *file, int line ){ + opus_int32 ret; + ret = (opus_int32)a; + if ( (opus_int64)ret != a ) + { + fprintf (stderr, "silk_CHECK_FIT32(%lld) in %s: line %d\n", (long long)a, file, line); +#ifdef FIXED_DEBUG_ASSERT + silk_assert( 0 ); +#endif + } + return( ret ); +} + +/* no checking for silk_NSHIFT_MUL_32_32 + no checking for silk_NSHIFT_MUL_16_16 + no checking needed for silk_min + no checking needed for silk_max + no checking needed for silk_sign +*/ + +#endif +#endif /* MACRO_DEBUG_H */ diff --git a/src/opus-1.1/silk/NLSF2A.c b/src/opus-1.1/silk/NLSF2A.c new file mode 100644 index 00000000..b1c559ea --- /dev/null +++ b/src/opus-1.1/silk/NLSF2A.c @@ -0,0 +1,178 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* conversion between prediction filter coefficients and LSFs */ +/* order should be even */ +/* a piecewise linear approximation maps LSF <-> cos(LSF) */ +/* therefore the result is not accurate LSFs, but the two */ +/* functions are accurate inverses of each other */ + +#include "SigProc_FIX.h" +#include "tables.h" + +#define QA 16 + +/* helper function for NLSF2A(..) */ +static OPUS_INLINE void silk_NLSF2A_find_poly( + opus_int32 *out, /* O intermediate polynomial, QA [dd+1] */ + const opus_int32 *cLSF, /* I vector of interleaved 2*cos(LSFs), QA [d] */ + opus_int dd /* I polynomial order (= 1/2 * filter order) */ +) +{ + opus_int k, n; + opus_int32 ftmp; + + out[0] = silk_LSHIFT( 1, QA ); + out[1] = -cLSF[0]; + for( k = 1; k < dd; k++ ) { + ftmp = cLSF[2*k]; /* QA*/ + out[k+1] = silk_LSHIFT( out[k-1], 1 ) - (opus_int32)silk_RSHIFT_ROUND64( silk_SMULL( ftmp, out[k] ), QA ); + for( n = k; n > 1; n-- ) { + out[n] += out[n-2] - (opus_int32)silk_RSHIFT_ROUND64( silk_SMULL( ftmp, out[n-1] ), QA ); + } + out[1] -= ftmp; + } +} + +/* compute whitening filter coefficients from normalized line spectral frequencies */ +void silk_NLSF2A( + opus_int16 *a_Q12, /* O monic whitening filter coefficients in Q12, [ d ] */ + const opus_int16 *NLSF, /* I normalized line spectral frequencies in Q15, [ d ] */ + const opus_int d /* I filter order (should be even) */ +) +{ + /* This ordering was found to maximize quality. It improves numerical accuracy of + silk_NLSF2A_find_poly() compared to "standard" ordering. */ + static const unsigned char ordering16[16] = { + 0, 15, 8, 7, 4, 11, 12, 3, 2, 13, 10, 5, 6, 9, 14, 1 + }; + static const unsigned char ordering10[10] = { + 0, 9, 6, 3, 4, 5, 8, 1, 2, 7 + }; + const unsigned char *ordering; + opus_int k, i, dd; + opus_int32 cos_LSF_QA[ SILK_MAX_ORDER_LPC ]; + opus_int32 P[ SILK_MAX_ORDER_LPC / 2 + 1 ], Q[ SILK_MAX_ORDER_LPC / 2 + 1 ]; + opus_int32 Ptmp, Qtmp, f_int, f_frac, cos_val, delta; + opus_int32 a32_QA1[ SILK_MAX_ORDER_LPC ]; + opus_int32 maxabs, absval, idx=0, sc_Q16; + + silk_assert( LSF_COS_TAB_SZ_FIX == 128 ); + silk_assert( d==10||d==16 ); + + /* convert LSFs to 2*cos(LSF), using piecewise linear curve from table */ + ordering = d == 16 ? ordering16 : ordering10; + for( k = 0; k < d; k++ ) { + silk_assert(NLSF[k] >= 0 ); + + /* f_int on a scale 0-127 (rounded down) */ + f_int = silk_RSHIFT( NLSF[k], 15 - 7 ); + + /* f_frac, range: 0..255 */ + f_frac = NLSF[k] - silk_LSHIFT( f_int, 15 - 7 ); + + silk_assert(f_int >= 0); + silk_assert(f_int < LSF_COS_TAB_SZ_FIX ); + + /* Read start and end value from table */ + cos_val = silk_LSFCosTab_FIX_Q12[ f_int ]; /* Q12 */ + delta = silk_LSFCosTab_FIX_Q12[ f_int + 1 ] - cos_val; /* Q12, with a range of 0..200 */ + + /* Linear interpolation */ + cos_LSF_QA[ordering[k]] = silk_RSHIFT_ROUND( silk_LSHIFT( cos_val, 8 ) + silk_MUL( delta, f_frac ), 20 - QA ); /* QA */ + } + + dd = silk_RSHIFT( d, 1 ); + + /* generate even and odd polynomials using convolution */ + silk_NLSF2A_find_poly( P, &cos_LSF_QA[ 0 ], dd ); + silk_NLSF2A_find_poly( Q, &cos_LSF_QA[ 1 ], dd ); + + /* convert even and odd polynomials to opus_int32 Q12 filter coefs */ + for( k = 0; k < dd; k++ ) { + Ptmp = P[ k+1 ] + P[ k ]; + Qtmp = Q[ k+1 ] - Q[ k ]; + + /* the Ptmp and Qtmp values at this stage need to fit in int32 */ + a32_QA1[ k ] = -Qtmp - Ptmp; /* QA+1 */ + a32_QA1[ d-k-1 ] = Qtmp - Ptmp; /* QA+1 */ + } + + /* Limit the maximum absolute value of the prediction coefficients, so that they'll fit in int16 */ + for( i = 0; i < 10; i++ ) { + /* Find maximum absolute value and its index */ + maxabs = 0; + for( k = 0; k < d; k++ ) { + absval = silk_abs( a32_QA1[k] ); + if( absval > maxabs ) { + maxabs = absval; + idx = k; + } + } + maxabs = silk_RSHIFT_ROUND( maxabs, QA + 1 - 12 ); /* QA+1 -> Q12 */ + + if( maxabs > silk_int16_MAX ) { + /* Reduce magnitude of prediction coefficients */ + maxabs = silk_min( maxabs, 163838 ); /* ( silk_int32_MAX >> 14 ) + silk_int16_MAX = 163838 */ + sc_Q16 = SILK_FIX_CONST( 0.999, 16 ) - silk_DIV32( silk_LSHIFT( maxabs - silk_int16_MAX, 14 ), + silk_RSHIFT32( silk_MUL( maxabs, idx + 1), 2 ) ); + silk_bwexpander_32( a32_QA1, d, sc_Q16 ); + } else { + break; + } + } + + if( i == 10 ) { + /* Reached the last iteration, clip the coefficients */ + for( k = 0; k < d; k++ ) { + a_Q12[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ) ); /* QA+1 -> Q12 */ + a32_QA1[ k ] = silk_LSHIFT( (opus_int32)a_Q12[ k ], QA + 1 - 12 ); + } + } else { + for( k = 0; k < d; k++ ) { + a_Q12[ k ] = (opus_int16)silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ); /* QA+1 -> Q12 */ + } + } + + for( i = 0; i < MAX_LPC_STABILIZE_ITERATIONS; i++ ) { + if( silk_LPC_inverse_pred_gain( a_Q12, d ) < SILK_FIX_CONST( 1.0 / MAX_PREDICTION_POWER_GAIN, 30 ) ) { + /* Prediction coefficients are (too close to) unstable; apply bandwidth expansion */ + /* on the unscaled coefficients, convert to Q12 and measure again */ + silk_bwexpander_32( a32_QA1, d, 65536 - silk_LSHIFT( 2, i ) ); + for( k = 0; k < d; k++ ) { + a_Q12[ k ] = (opus_int16)silk_RSHIFT_ROUND( a32_QA1[ k ], QA + 1 - 12 ); /* QA+1 -> Q12 */ + } + } else { + break; + } + } +} + diff --git a/src/opus-1.1/silk/NLSF_VQ.c b/src/opus-1.1/silk/NLSF_VQ.c new file mode 100644 index 00000000..69b6e22e --- /dev/null +++ b/src/opus-1.1/silk/NLSF_VQ.c @@ -0,0 +1,68 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main.h" + +/* Compute quantization errors for an LPC_order element input vector for a VQ codebook */ +void silk_NLSF_VQ( + opus_int32 err_Q26[], /* O Quantization errors [K] */ + const opus_int16 in_Q15[], /* I Input vectors to be quantized [LPC_order] */ + const opus_uint8 pCB_Q8[], /* I Codebook vectors [K*LPC_order] */ + const opus_int K, /* I Number of codebook vectors */ + const opus_int LPC_order /* I Number of LPCs */ +) +{ + opus_int i, m; + opus_int32 diff_Q15, sum_error_Q30, sum_error_Q26; + + silk_assert( LPC_order <= 16 ); + silk_assert( ( LPC_order & 1 ) == 0 ); + + /* Loop over codebook */ + for( i = 0; i < K; i++ ) { + sum_error_Q26 = 0; + for( m = 0; m < LPC_order; m += 2 ) { + /* Compute weighted squared quantization error for index m */ + diff_Q15 = silk_SUB_LSHIFT32( in_Q15[ m ], (opus_int32)*pCB_Q8++, 7 ); /* range: [ -32767 : 32767 ]*/ + sum_error_Q30 = silk_SMULBB( diff_Q15, diff_Q15 ); + + /* Compute weighted squared quantization error for index m + 1 */ + diff_Q15 = silk_SUB_LSHIFT32( in_Q15[m + 1], (opus_int32)*pCB_Q8++, 7 ); /* range: [ -32767 : 32767 ]*/ + sum_error_Q30 = silk_SMLABB( sum_error_Q30, diff_Q15, diff_Q15 ); + + sum_error_Q26 = silk_ADD_RSHIFT32( sum_error_Q26, sum_error_Q30, 4 ); + + silk_assert( sum_error_Q26 >= 0 ); + silk_assert( sum_error_Q30 >= 0 ); + } + err_Q26[ i ] = sum_error_Q26; + } +} diff --git a/src/opus-1.1/silk/NLSF_VQ_weights_laroia.c b/src/opus-1.1/silk/NLSF_VQ_weights_laroia.c new file mode 100644 index 00000000..04894c59 --- /dev/null +++ b/src/opus-1.1/silk/NLSF_VQ_weights_laroia.c @@ -0,0 +1,80 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "define.h" +#include "SigProc_FIX.h" + +/* +R. Laroia, N. Phamdo and N. Farvardin, "Robust and Efficient Quantization of Speech LSP +Parameters Using Structured Vector Quantization", Proc. IEEE Int. Conf. Acoust., Speech, +Signal Processing, pp. 641-644, 1991. +*/ + +/* Laroia low complexity NLSF weights */ +void silk_NLSF_VQ_weights_laroia( + opus_int16 *pNLSFW_Q_OUT, /* O Pointer to input vector weights [D] */ + const opus_int16 *pNLSF_Q15, /* I Pointer to input vector [D] */ + const opus_int D /* I Input vector dimension (even) */ +) +{ + opus_int k; + opus_int32 tmp1_int, tmp2_int; + + silk_assert( D > 0 ); + silk_assert( ( D & 1 ) == 0 ); + + /* First value */ + tmp1_int = silk_max_int( pNLSF_Q15[ 0 ], 1 ); + tmp1_int = silk_DIV32_16( (opus_int32)1 << ( 15 + NLSF_W_Q ), tmp1_int ); + tmp2_int = silk_max_int( pNLSF_Q15[ 1 ] - pNLSF_Q15[ 0 ], 1 ); + tmp2_int = silk_DIV32_16( (opus_int32)1 << ( 15 + NLSF_W_Q ), tmp2_int ); + pNLSFW_Q_OUT[ 0 ] = (opus_int16)silk_min_int( tmp1_int + tmp2_int, silk_int16_MAX ); + silk_assert( pNLSFW_Q_OUT[ 0 ] > 0 ); + + /* Main loop */ + for( k = 1; k < D - 1; k += 2 ) { + tmp1_int = silk_max_int( pNLSF_Q15[ k + 1 ] - pNLSF_Q15[ k ], 1 ); + tmp1_int = silk_DIV32_16( (opus_int32)1 << ( 15 + NLSF_W_Q ), tmp1_int ); + pNLSFW_Q_OUT[ k ] = (opus_int16)silk_min_int( tmp1_int + tmp2_int, silk_int16_MAX ); + silk_assert( pNLSFW_Q_OUT[ k ] > 0 ); + + tmp2_int = silk_max_int( pNLSF_Q15[ k + 2 ] - pNLSF_Q15[ k + 1 ], 1 ); + tmp2_int = silk_DIV32_16( (opus_int32)1 << ( 15 + NLSF_W_Q ), tmp2_int ); + pNLSFW_Q_OUT[ k + 1 ] = (opus_int16)silk_min_int( tmp1_int + tmp2_int, silk_int16_MAX ); + silk_assert( pNLSFW_Q_OUT[ k + 1 ] > 0 ); + } + + /* Last value */ + tmp1_int = silk_max_int( ( 1 << 15 ) - pNLSF_Q15[ D - 1 ], 1 ); + tmp1_int = silk_DIV32_16( (opus_int32)1 << ( 15 + NLSF_W_Q ), tmp1_int ); + pNLSFW_Q_OUT[ D - 1 ] = (opus_int16)silk_min_int( tmp1_int + tmp2_int, silk_int16_MAX ); + silk_assert( pNLSFW_Q_OUT[ D - 1 ] > 0 ); +} diff --git a/src/opus-1.1/silk/NLSF_decode.c b/src/opus-1.1/silk/NLSF_decode.c new file mode 100644 index 00000000..9f715060 --- /dev/null +++ b/src/opus-1.1/silk/NLSF_decode.c @@ -0,0 +1,101 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main.h" + +/* Predictive dequantizer for NLSF residuals */ +static OPUS_INLINE void silk_NLSF_residual_dequant( /* O Returns RD value in Q30 */ + opus_int16 x_Q10[], /* O Output [ order ] */ + const opus_int8 indices[], /* I Quantization indices [ order ] */ + const opus_uint8 pred_coef_Q8[], /* I Backward predictor coefs [ order ] */ + const opus_int quant_step_size_Q16, /* I Quantization step size */ + const opus_int16 order /* I Number of input values */ +) +{ + opus_int i, out_Q10, pred_Q10; + + out_Q10 = 0; + for( i = order-1; i >= 0; i-- ) { + pred_Q10 = silk_RSHIFT( silk_SMULBB( out_Q10, (opus_int16)pred_coef_Q8[ i ] ), 8 ); + out_Q10 = silk_LSHIFT( indices[ i ], 10 ); + if( out_Q10 > 0 ) { + out_Q10 = silk_SUB16( out_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) ); + } else if( out_Q10 < 0 ) { + out_Q10 = silk_ADD16( out_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) ); + } + out_Q10 = silk_SMLAWB( pred_Q10, (opus_int32)out_Q10, quant_step_size_Q16 ); + x_Q10[ i ] = out_Q10; + } +} + + +/***********************/ +/* NLSF vector decoder */ +/***********************/ +void silk_NLSF_decode( + opus_int16 *pNLSF_Q15, /* O Quantized NLSF vector [ LPC_ORDER ] */ + opus_int8 *NLSFIndices, /* I Codebook path vector [ LPC_ORDER + 1 ] */ + const silk_NLSF_CB_struct *psNLSF_CB /* I Codebook object */ +) +{ + opus_int i; + opus_uint8 pred_Q8[ MAX_LPC_ORDER ]; + opus_int16 ec_ix[ MAX_LPC_ORDER ]; + opus_int16 res_Q10[ MAX_LPC_ORDER ]; + opus_int16 W_tmp_QW[ MAX_LPC_ORDER ]; + opus_int32 W_tmp_Q9, NLSF_Q15_tmp; + const opus_uint8 *pCB_element; + + /* Decode first stage */ + pCB_element = &psNLSF_CB->CB1_NLSF_Q8[ NLSFIndices[ 0 ] * psNLSF_CB->order ]; + for( i = 0; i < psNLSF_CB->order; i++ ) { + pNLSF_Q15[ i ] = silk_LSHIFT( (opus_int16)pCB_element[ i ], 7 ); + } + + /* Unpack entropy table indices and predictor for current CB1 index */ + silk_NLSF_unpack( ec_ix, pred_Q8, psNLSF_CB, NLSFIndices[ 0 ] ); + + /* Predictive residual dequantizer */ + silk_NLSF_residual_dequant( res_Q10, &NLSFIndices[ 1 ], pred_Q8, psNLSF_CB->quantStepSize_Q16, psNLSF_CB->order ); + + /* Weights from codebook vector */ + silk_NLSF_VQ_weights_laroia( W_tmp_QW, pNLSF_Q15, psNLSF_CB->order ); + + /* Apply inverse square-rooted weights and add to output */ + for( i = 0; i < psNLSF_CB->order; i++ ) { + W_tmp_Q9 = silk_SQRT_APPROX( silk_LSHIFT( (opus_int32)W_tmp_QW[ i ], 18 - NLSF_W_Q ) ); + NLSF_Q15_tmp = silk_ADD32( pNLSF_Q15[ i ], silk_DIV32_16( silk_LSHIFT( (opus_int32)res_Q10[ i ], 14 ), W_tmp_Q9 ) ); + pNLSF_Q15[ i ] = (opus_int16)silk_LIMIT( NLSF_Q15_tmp, 0, 32767 ); + } + + /* NLSF stabilization */ + silk_NLSF_stabilize( pNLSF_Q15, psNLSF_CB->deltaMin_Q15, psNLSF_CB->order ); +} diff --git a/src/opus-1.1/silk/NLSF_del_dec_quant.c b/src/opus-1.1/silk/NLSF_del_dec_quant.c new file mode 100644 index 00000000..504dbbd0 --- /dev/null +++ b/src/opus-1.1/silk/NLSF_del_dec_quant.c @@ -0,0 +1,207 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main.h" + +/* Delayed-decision quantizer for NLSF residuals */ +opus_int32 silk_NLSF_del_dec_quant( /* O Returns RD value in Q25 */ + opus_int8 indices[], /* O Quantization indices [ order ] */ + const opus_int16 x_Q10[], /* I Input [ order ] */ + const opus_int16 w_Q5[], /* I Weights [ order ] */ + const opus_uint8 pred_coef_Q8[], /* I Backward predictor coefs [ order ] */ + const opus_int16 ec_ix[], /* I Indices to entropy coding tables [ order ] */ + const opus_uint8 ec_rates_Q5[], /* I Rates [] */ + const opus_int quant_step_size_Q16, /* I Quantization step size */ + const opus_int16 inv_quant_step_size_Q6, /* I Inverse quantization step size */ + const opus_int32 mu_Q20, /* I R/D tradeoff */ + const opus_int16 order /* I Number of input values */ +) +{ + opus_int i, j, nStates, ind_tmp, ind_min_max, ind_max_min, in_Q10, res_Q10; + opus_int pred_Q10, diff_Q10, out0_Q10, out1_Q10, rate0_Q5, rate1_Q5; + opus_int32 RD_tmp_Q25, min_Q25, min_max_Q25, max_min_Q25, pred_coef_Q16; + opus_int ind_sort[ NLSF_QUANT_DEL_DEC_STATES ]; + opus_int8 ind[ NLSF_QUANT_DEL_DEC_STATES ][ MAX_LPC_ORDER ]; + opus_int16 prev_out_Q10[ 2 * NLSF_QUANT_DEL_DEC_STATES ]; + opus_int32 RD_Q25[ 2 * NLSF_QUANT_DEL_DEC_STATES ]; + opus_int32 RD_min_Q25[ NLSF_QUANT_DEL_DEC_STATES ]; + opus_int32 RD_max_Q25[ NLSF_QUANT_DEL_DEC_STATES ]; + const opus_uint8 *rates_Q5; + + silk_assert( (NLSF_QUANT_DEL_DEC_STATES & (NLSF_QUANT_DEL_DEC_STATES-1)) == 0 ); /* must be power of two */ + + nStates = 1; + RD_Q25[ 0 ] = 0; + prev_out_Q10[ 0 ] = 0; + for( i = order - 1; ; i-- ) { + rates_Q5 = &ec_rates_Q5[ ec_ix[ i ] ]; + pred_coef_Q16 = silk_LSHIFT( (opus_int32)pred_coef_Q8[ i ], 8 ); + in_Q10 = x_Q10[ i ]; + for( j = 0; j < nStates; j++ ) { + pred_Q10 = silk_SMULWB( pred_coef_Q16, prev_out_Q10[ j ] ); + res_Q10 = silk_SUB16( in_Q10, pred_Q10 ); + ind_tmp = silk_SMULWB( (opus_int32)inv_quant_step_size_Q6, res_Q10 ); + ind_tmp = silk_LIMIT( ind_tmp, -NLSF_QUANT_MAX_AMPLITUDE_EXT, NLSF_QUANT_MAX_AMPLITUDE_EXT-1 ); + ind[ j ][ i ] = (opus_int8)ind_tmp; + + /* compute outputs for ind_tmp and ind_tmp + 1 */ + out0_Q10 = silk_LSHIFT( ind_tmp, 10 ); + out1_Q10 = silk_ADD16( out0_Q10, 1024 ); + if( ind_tmp > 0 ) { + out0_Q10 = silk_SUB16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) ); + out1_Q10 = silk_SUB16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) ); + } else if( ind_tmp == 0 ) { + out1_Q10 = silk_SUB16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) ); + } else if( ind_tmp == -1 ) { + out0_Q10 = silk_ADD16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) ); + } else { + out0_Q10 = silk_ADD16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) ); + out1_Q10 = silk_ADD16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) ); + } + out0_Q10 = silk_SMULWB( (opus_int32)out0_Q10, quant_step_size_Q16 ); + out1_Q10 = silk_SMULWB( (opus_int32)out1_Q10, quant_step_size_Q16 ); + out0_Q10 = silk_ADD16( out0_Q10, pred_Q10 ); + out1_Q10 = silk_ADD16( out1_Q10, pred_Q10 ); + prev_out_Q10[ j ] = out0_Q10; + prev_out_Q10[ j + nStates ] = out1_Q10; + + /* compute RD for ind_tmp and ind_tmp + 1 */ + if( ind_tmp + 1 >= NLSF_QUANT_MAX_AMPLITUDE ) { + if( ind_tmp + 1 == NLSF_QUANT_MAX_AMPLITUDE ) { + rate0_Q5 = rates_Q5[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE ]; + rate1_Q5 = 280; + } else { + rate0_Q5 = silk_SMLABB( 280 - 43 * NLSF_QUANT_MAX_AMPLITUDE, 43, ind_tmp ); + rate1_Q5 = silk_ADD16( rate0_Q5, 43 ); + } + } else if( ind_tmp <= -NLSF_QUANT_MAX_AMPLITUDE ) { + if( ind_tmp == -NLSF_QUANT_MAX_AMPLITUDE ) { + rate0_Q5 = 280; + rate1_Q5 = rates_Q5[ ind_tmp + 1 + NLSF_QUANT_MAX_AMPLITUDE ]; + } else { + rate0_Q5 = silk_SMLABB( 280 - 43 * NLSF_QUANT_MAX_AMPLITUDE, -43, ind_tmp ); + rate1_Q5 = silk_SUB16( rate0_Q5, 43 ); + } + } else { + rate0_Q5 = rates_Q5[ ind_tmp + NLSF_QUANT_MAX_AMPLITUDE ]; + rate1_Q5 = rates_Q5[ ind_tmp + 1 + NLSF_QUANT_MAX_AMPLITUDE ]; + } + RD_tmp_Q25 = RD_Q25[ j ]; + diff_Q10 = silk_SUB16( in_Q10, out0_Q10 ); + RD_Q25[ j ] = silk_SMLABB( silk_MLA( RD_tmp_Q25, silk_SMULBB( diff_Q10, diff_Q10 ), w_Q5[ i ] ), mu_Q20, rate0_Q5 ); + diff_Q10 = silk_SUB16( in_Q10, out1_Q10 ); + RD_Q25[ j + nStates ] = silk_SMLABB( silk_MLA( RD_tmp_Q25, silk_SMULBB( diff_Q10, diff_Q10 ), w_Q5[ i ] ), mu_Q20, rate1_Q5 ); + } + + if( nStates <= ( NLSF_QUANT_DEL_DEC_STATES >> 1 ) ) { + /* double number of states and copy */ + for( j = 0; j < nStates; j++ ) { + ind[ j + nStates ][ i ] = ind[ j ][ i ] + 1; + } + nStates = silk_LSHIFT( nStates, 1 ); + for( j = nStates; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) { + ind[ j ][ i ] = ind[ j - nStates ][ i ]; + } + } else if( i > 0 ) { + /* sort lower and upper half of RD_Q25, pairwise */ + for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) { + if( RD_Q25[ j ] > RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ] ) { + RD_max_Q25[ j ] = RD_Q25[ j ]; + RD_min_Q25[ j ] = RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ]; + RD_Q25[ j ] = RD_min_Q25[ j ]; + RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ] = RD_max_Q25[ j ]; + /* swap prev_out values */ + out0_Q10 = prev_out_Q10[ j ]; + prev_out_Q10[ j ] = prev_out_Q10[ j + NLSF_QUANT_DEL_DEC_STATES ]; + prev_out_Q10[ j + NLSF_QUANT_DEL_DEC_STATES ] = out0_Q10; + ind_sort[ j ] = j + NLSF_QUANT_DEL_DEC_STATES; + } else { + RD_min_Q25[ j ] = RD_Q25[ j ]; + RD_max_Q25[ j ] = RD_Q25[ j + NLSF_QUANT_DEL_DEC_STATES ]; + ind_sort[ j ] = j; + } + } + /* compare the highest RD values of the winning half with the lowest one in the losing half, and copy if necessary */ + /* afterwards ind_sort[] will contain the indices of the NLSF_QUANT_DEL_DEC_STATES winning RD values */ + while( 1 ) { + min_max_Q25 = silk_int32_MAX; + max_min_Q25 = 0; + ind_min_max = 0; + ind_max_min = 0; + for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) { + if( min_max_Q25 > RD_max_Q25[ j ] ) { + min_max_Q25 = RD_max_Q25[ j ]; + ind_min_max = j; + } + if( max_min_Q25 < RD_min_Q25[ j ] ) { + max_min_Q25 = RD_min_Q25[ j ]; + ind_max_min = j; + } + } + if( min_max_Q25 >= max_min_Q25 ) { + break; + } + /* copy ind_min_max to ind_max_min */ + ind_sort[ ind_max_min ] = ind_sort[ ind_min_max ] ^ NLSF_QUANT_DEL_DEC_STATES; + RD_Q25[ ind_max_min ] = RD_Q25[ ind_min_max + NLSF_QUANT_DEL_DEC_STATES ]; + prev_out_Q10[ ind_max_min ] = prev_out_Q10[ ind_min_max + NLSF_QUANT_DEL_DEC_STATES ]; + RD_min_Q25[ ind_max_min ] = 0; + RD_max_Q25[ ind_min_max ] = silk_int32_MAX; + silk_memcpy( ind[ ind_max_min ], ind[ ind_min_max ], MAX_LPC_ORDER * sizeof( opus_int8 ) ); + } + /* increment index if it comes from the upper half */ + for( j = 0; j < NLSF_QUANT_DEL_DEC_STATES; j++ ) { + ind[ j ][ i ] += silk_RSHIFT( ind_sort[ j ], NLSF_QUANT_DEL_DEC_STATES_LOG2 ); + } + } else { /* i == 0 */ + break; + } + } + + /* last sample: find winner, copy indices and return RD value */ + ind_tmp = 0; + min_Q25 = silk_int32_MAX; + for( j = 0; j < 2 * NLSF_QUANT_DEL_DEC_STATES; j++ ) { + if( min_Q25 > RD_Q25[ j ] ) { + min_Q25 = RD_Q25[ j ]; + ind_tmp = j; + } + } + for( j = 0; j < order; j++ ) { + indices[ j ] = ind[ ind_tmp & ( NLSF_QUANT_DEL_DEC_STATES - 1 ) ][ j ]; + silk_assert( indices[ j ] >= -NLSF_QUANT_MAX_AMPLITUDE_EXT ); + silk_assert( indices[ j ] <= NLSF_QUANT_MAX_AMPLITUDE_EXT ); + } + indices[ 0 ] += silk_RSHIFT( ind_tmp, NLSF_QUANT_DEL_DEC_STATES_LOG2 ); + silk_assert( indices[ 0 ] <= NLSF_QUANT_MAX_AMPLITUDE_EXT ); + silk_assert( min_Q25 >= 0 ); + return min_Q25; +} diff --git a/src/opus-1.1/silk/NLSF_encode.c b/src/opus-1.1/silk/NLSF_encode.c new file mode 100644 index 00000000..03a036fd --- /dev/null +++ b/src/opus-1.1/silk/NLSF_encode.c @@ -0,0 +1,136 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main.h" +#include "stack_alloc.h" + +/***********************/ +/* NLSF vector encoder */ +/***********************/ +opus_int32 silk_NLSF_encode( /* O Returns RD value in Q25 */ + opus_int8 *NLSFIndices, /* I Codebook path vector [ LPC_ORDER + 1 ] */ + opus_int16 *pNLSF_Q15, /* I/O Quantized NLSF vector [ LPC_ORDER ] */ + const silk_NLSF_CB_struct *psNLSF_CB, /* I Codebook object */ + const opus_int16 *pW_QW, /* I NLSF weight vector [ LPC_ORDER ] */ + const opus_int NLSF_mu_Q20, /* I Rate weight for the RD optimization */ + const opus_int nSurvivors, /* I Max survivors after first stage */ + const opus_int signalType /* I Signal type: 0/1/2 */ +) +{ + opus_int i, s, ind1, bestIndex, prob_Q8, bits_q7; + opus_int32 W_tmp_Q9; + VARDECL( opus_int32, err_Q26 ); + VARDECL( opus_int32, RD_Q25 ); + VARDECL( opus_int, tempIndices1 ); + VARDECL( opus_int8, tempIndices2 ); + opus_int16 res_Q15[ MAX_LPC_ORDER ]; + opus_int16 res_Q10[ MAX_LPC_ORDER ]; + opus_int16 NLSF_tmp_Q15[ MAX_LPC_ORDER ]; + opus_int16 W_tmp_QW[ MAX_LPC_ORDER ]; + opus_int16 W_adj_Q5[ MAX_LPC_ORDER ]; + opus_uint8 pred_Q8[ MAX_LPC_ORDER ]; + opus_int16 ec_ix[ MAX_LPC_ORDER ]; + const opus_uint8 *pCB_element, *iCDF_ptr; + SAVE_STACK; + + silk_assert( nSurvivors <= NLSF_VQ_MAX_SURVIVORS ); + silk_assert( signalType >= 0 && signalType <= 2 ); + silk_assert( NLSF_mu_Q20 <= 32767 && NLSF_mu_Q20 >= 0 ); + + /* NLSF stabilization */ + silk_NLSF_stabilize( pNLSF_Q15, psNLSF_CB->deltaMin_Q15, psNLSF_CB->order ); + + /* First stage: VQ */ + ALLOC( err_Q26, psNLSF_CB->nVectors, opus_int32 ); + silk_NLSF_VQ( err_Q26, pNLSF_Q15, psNLSF_CB->CB1_NLSF_Q8, psNLSF_CB->nVectors, psNLSF_CB->order ); + + /* Sort the quantization errors */ + ALLOC( tempIndices1, nSurvivors, opus_int ); + silk_insertion_sort_increasing( err_Q26, tempIndices1, psNLSF_CB->nVectors, nSurvivors ); + + ALLOC( RD_Q25, nSurvivors, opus_int32 ); + ALLOC( tempIndices2, nSurvivors * MAX_LPC_ORDER, opus_int8 ); + + /* Loop over survivors */ + for( s = 0; s < nSurvivors; s++ ) { + ind1 = tempIndices1[ s ]; + + /* Residual after first stage */ + pCB_element = &psNLSF_CB->CB1_NLSF_Q8[ ind1 * psNLSF_CB->order ]; + for( i = 0; i < psNLSF_CB->order; i++ ) { + NLSF_tmp_Q15[ i ] = silk_LSHIFT16( (opus_int16)pCB_element[ i ], 7 ); + res_Q15[ i ] = pNLSF_Q15[ i ] - NLSF_tmp_Q15[ i ]; + } + + /* Weights from codebook vector */ + silk_NLSF_VQ_weights_laroia( W_tmp_QW, NLSF_tmp_Q15, psNLSF_CB->order ); + + /* Apply square-rooted weights */ + for( i = 0; i < psNLSF_CB->order; i++ ) { + W_tmp_Q9 = silk_SQRT_APPROX( silk_LSHIFT( (opus_int32)W_tmp_QW[ i ], 18 - NLSF_W_Q ) ); + res_Q10[ i ] = (opus_int16)silk_RSHIFT( silk_SMULBB( res_Q15[ i ], W_tmp_Q9 ), 14 ); + } + + /* Modify input weights accordingly */ + for( i = 0; i < psNLSF_CB->order; i++ ) { + W_adj_Q5[ i ] = silk_DIV32_16( silk_LSHIFT( (opus_int32)pW_QW[ i ], 5 ), W_tmp_QW[ i ] ); + } + + /* Unpack entropy table indices and predictor for current CB1 index */ + silk_NLSF_unpack( ec_ix, pred_Q8, psNLSF_CB, ind1 ); + + /* Trellis quantizer */ + RD_Q25[ s ] = silk_NLSF_del_dec_quant( &tempIndices2[ s * MAX_LPC_ORDER ], res_Q10, W_adj_Q5, pred_Q8, ec_ix, + psNLSF_CB->ec_Rates_Q5, psNLSF_CB->quantStepSize_Q16, psNLSF_CB->invQuantStepSize_Q6, NLSF_mu_Q20, psNLSF_CB->order ); + + /* Add rate for first stage */ + iCDF_ptr = &psNLSF_CB->CB1_iCDF[ ( signalType >> 1 ) * psNLSF_CB->nVectors ]; + if( ind1 == 0 ) { + prob_Q8 = 256 - iCDF_ptr[ ind1 ]; + } else { + prob_Q8 = iCDF_ptr[ ind1 - 1 ] - iCDF_ptr[ ind1 ]; + } + bits_q7 = ( 8 << 7 ) - silk_lin2log( prob_Q8 ); + RD_Q25[ s ] = silk_SMLABB( RD_Q25[ s ], bits_q7, silk_RSHIFT( NLSF_mu_Q20, 2 ) ); + } + + /* Find the lowest rate-distortion error */ + silk_insertion_sort_increasing( RD_Q25, &bestIndex, nSurvivors, 1 ); + + NLSFIndices[ 0 ] = (opus_int8)tempIndices1[ bestIndex ]; + silk_memcpy( &NLSFIndices[ 1 ], &tempIndices2[ bestIndex * MAX_LPC_ORDER ], psNLSF_CB->order * sizeof( opus_int8 ) ); + + /* Decode */ + silk_NLSF_decode( pNLSF_Q15, NLSFIndices, psNLSF_CB ); + + RESTORE_STACK; + return RD_Q25[ 0 ]; +} diff --git a/src/opus-1.1/silk/NLSF_stabilize.c b/src/opus-1.1/silk/NLSF_stabilize.c new file mode 100644 index 00000000..1fa1ea37 --- /dev/null +++ b/src/opus-1.1/silk/NLSF_stabilize.c @@ -0,0 +1,142 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* NLSF stabilizer: */ +/* */ +/* - Moves NLSFs further apart if they are too close */ +/* - Moves NLSFs away from borders if they are too close */ +/* - High effort to achieve a modification with minimum */ +/* Euclidean distance to input vector */ +/* - Output are sorted NLSF coefficients */ +/* */ + +#include "SigProc_FIX.h" + +/* Constant Definitions */ +#define MAX_LOOPS 20 + +/* NLSF stabilizer, for a single input data vector */ +void silk_NLSF_stabilize( + opus_int16 *NLSF_Q15, /* I/O Unstable/stabilized normalized LSF vector in Q15 [L] */ + const opus_int16 *NDeltaMin_Q15, /* I Min distance vector, NDeltaMin_Q15[L] must be >= 1 [L+1] */ + const opus_int L /* I Number of NLSF parameters in the input vector */ +) +{ + opus_int i, I=0, k, loops; + opus_int16 center_freq_Q15; + opus_int32 diff_Q15, min_diff_Q15, min_center_Q15, max_center_Q15; + + /* This is necessary to ensure an output within range of a opus_int16 */ + silk_assert( NDeltaMin_Q15[L] >= 1 ); + + for( loops = 0; loops < MAX_LOOPS; loops++ ) { + /**************************/ + /* Find smallest distance */ + /**************************/ + /* First element */ + min_diff_Q15 = NLSF_Q15[0] - NDeltaMin_Q15[0]; + I = 0; + /* Middle elements */ + for( i = 1; i <= L-1; i++ ) { + diff_Q15 = NLSF_Q15[i] - ( NLSF_Q15[i-1] + NDeltaMin_Q15[i] ); + if( diff_Q15 < min_diff_Q15 ) { + min_diff_Q15 = diff_Q15; + I = i; + } + } + /* Last element */ + diff_Q15 = ( 1 << 15 ) - ( NLSF_Q15[L-1] + NDeltaMin_Q15[L] ); + if( diff_Q15 < min_diff_Q15 ) { + min_diff_Q15 = diff_Q15; + I = L; + } + + /***************************************************/ + /* Now check if the smallest distance non-negative */ + /***************************************************/ + if( min_diff_Q15 >= 0 ) { + return; + } + + if( I == 0 ) { + /* Move away from lower limit */ + NLSF_Q15[0] = NDeltaMin_Q15[0]; + + } else if( I == L) { + /* Move away from higher limit */ + NLSF_Q15[L-1] = ( 1 << 15 ) - NDeltaMin_Q15[L]; + + } else { + /* Find the lower extreme for the location of the current center frequency */ + min_center_Q15 = 0; + for( k = 0; k < I; k++ ) { + min_center_Q15 += NDeltaMin_Q15[k]; + } + min_center_Q15 += silk_RSHIFT( NDeltaMin_Q15[I], 1 ); + + /* Find the upper extreme for the location of the current center frequency */ + max_center_Q15 = 1 << 15; + for( k = L; k > I; k-- ) { + max_center_Q15 -= NDeltaMin_Q15[k]; + } + max_center_Q15 -= silk_RSHIFT( NDeltaMin_Q15[I], 1 ); + + /* Move apart, sorted by value, keeping the same center frequency */ + center_freq_Q15 = (opus_int16)silk_LIMIT_32( silk_RSHIFT_ROUND( (opus_int32)NLSF_Q15[I-1] + (opus_int32)NLSF_Q15[I], 1 ), + min_center_Q15, max_center_Q15 ); + NLSF_Q15[I-1] = center_freq_Q15 - silk_RSHIFT( NDeltaMin_Q15[I], 1 ); + NLSF_Q15[I] = NLSF_Q15[I-1] + NDeltaMin_Q15[I]; + } + } + + /* Safe and simple fall back method, which is less ideal than the above */ + if( loops == MAX_LOOPS ) + { + /* Insertion sort (fast for already almost sorted arrays): */ + /* Best case: O(n) for an already sorted array */ + /* Worst case: O(n^2) for an inversely sorted array */ + silk_insertion_sort_increasing_all_values_int16( &NLSF_Q15[0], L ); + + /* First NLSF should be no less than NDeltaMin[0] */ + NLSF_Q15[0] = silk_max_int( NLSF_Q15[0], NDeltaMin_Q15[0] ); + + /* Keep delta_min distance between the NLSFs */ + for( i = 1; i < L; i++ ) + NLSF_Q15[i] = silk_max_int( NLSF_Q15[i], NLSF_Q15[i-1] + NDeltaMin_Q15[i] ); + + /* Last NLSF should be no higher than 1 - NDeltaMin[L] */ + NLSF_Q15[L-1] = silk_min_int( NLSF_Q15[L-1], (1<<15) - NDeltaMin_Q15[L] ); + + /* Keep NDeltaMin distance between the NLSFs */ + for( i = L-2; i >= 0; i-- ) + NLSF_Q15[i] = silk_min_int( NLSF_Q15[i], NLSF_Q15[i+1] - NDeltaMin_Q15[i+1] ); + } +} diff --git a/src/opus-1.1/silk/NLSF_unpack.c b/src/opus-1.1/silk/NLSF_unpack.c new file mode 100644 index 00000000..17bd23f7 --- /dev/null +++ b/src/opus-1.1/silk/NLSF_unpack.c @@ -0,0 +1,55 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main.h" + +/* Unpack predictor values and indices for entropy coding tables */ +void silk_NLSF_unpack( + opus_int16 ec_ix[], /* O Indices to entropy tables [ LPC_ORDER ] */ + opus_uint8 pred_Q8[], /* O LSF predictor [ LPC_ORDER ] */ + const silk_NLSF_CB_struct *psNLSF_CB, /* I Codebook object */ + const opus_int CB1_index /* I Index of vector in first LSF codebook */ +) +{ + opus_int i; + opus_uint8 entry; + const opus_uint8 *ec_sel_ptr; + + ec_sel_ptr = &psNLSF_CB->ec_sel[ CB1_index * psNLSF_CB->order / 2 ]; + for( i = 0; i < psNLSF_CB->order; i += 2 ) { + entry = *ec_sel_ptr++; + ec_ix [ i ] = silk_SMULBB( silk_RSHIFT( entry, 1 ) & 7, 2 * NLSF_QUANT_MAX_AMPLITUDE + 1 ); + pred_Q8[ i ] = psNLSF_CB->pred_Q8[ i + ( entry & 1 ) * ( psNLSF_CB->order - 1 ) ]; + ec_ix [ i + 1 ] = silk_SMULBB( silk_RSHIFT( entry, 5 ) & 7, 2 * NLSF_QUANT_MAX_AMPLITUDE + 1 ); + pred_Q8[ i + 1 ] = psNLSF_CB->pred_Q8[ i + ( silk_RSHIFT( entry, 4 ) & 1 ) * ( psNLSF_CB->order - 1 ) + 1 ]; + } +} + diff --git a/src/opus-1.1/silk/NSQ.c b/src/opus-1.1/silk/NSQ.c new file mode 100644 index 00000000..cf5b3fd5 --- /dev/null +++ b/src/opus-1.1/silk/NSQ.c @@ -0,0 +1,446 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main.h" +#include "stack_alloc.h" + +static OPUS_INLINE void silk_nsq_scale_states( + const silk_encoder_state *psEncC, /* I Encoder State */ + silk_nsq_state *NSQ, /* I/O NSQ state */ + const opus_int32 x_Q3[], /* I input in Q3 */ + opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */ + const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */ + opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ + opus_int subfr, /* I subframe number */ + const opus_int LTP_scale_Q14, /* I */ + const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ + const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ + const opus_int signal_type /* I Signal type */ +); + +static OPUS_INLINE void silk_noise_shape_quantizer( + silk_nsq_state *NSQ, /* I/O NSQ state */ + opus_int signalType, /* I Signal type */ + const opus_int32 x_sc_Q10[], /* I */ + opus_int8 pulses[], /* O */ + opus_int16 xq[], /* O */ + opus_int32 sLTP_Q15[], /* I/O LTP state */ + const opus_int16 a_Q12[], /* I Short term prediction coefs */ + const opus_int16 b_Q14[], /* I Long term prediction coefs */ + const opus_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */ + opus_int lag, /* I Pitch lag */ + opus_int32 HarmShapeFIRPacked_Q14, /* I */ + opus_int Tilt_Q14, /* I Spectral tilt */ + opus_int32 LF_shp_Q14, /* I */ + opus_int32 Gain_Q16, /* I */ + opus_int Lambda_Q10, /* I */ + opus_int offset_Q10, /* I */ + opus_int length, /* I Input length */ + opus_int shapingLPCOrder, /* I Noise shaping AR filter order */ + opus_int predictLPCOrder /* I Prediction filter order */ +); + +void silk_NSQ( + const silk_encoder_state *psEncC, /* I/O Encoder State */ + silk_nsq_state *NSQ, /* I/O NSQ state */ + SideInfoIndices *psIndices, /* I/O Quantization Indices */ + const opus_int32 x_Q3[], /* I Prefiltered input signal */ + opus_int8 pulses[], /* O Quantized pulse signal */ + const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ + const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ + const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ + const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ + const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ + const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ + const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ + const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ + const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ + const opus_int LTP_scale_Q14 /* I LTP state scaling */ +) +{ + opus_int k, lag, start_idx, LSF_interpolation_flag; + const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13; + opus_int16 *pxq; + VARDECL( opus_int32, sLTP_Q15 ); + VARDECL( opus_int16, sLTP ); + opus_int32 HarmShapeFIRPacked_Q14; + opus_int offset_Q10; + VARDECL( opus_int32, x_sc_Q10 ); + SAVE_STACK; + + NSQ->rand_seed = psIndices->Seed; + + /* Set unvoiced lag to the previous one, overwrite later for voiced */ + lag = NSQ->lagPrev; + + silk_assert( NSQ->prev_gain_Q16 != 0 ); + + offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ]; + + if( psIndices->NLSFInterpCoef_Q2 == 4 ) { + LSF_interpolation_flag = 0; + } else { + LSF_interpolation_flag = 1; + } + + ALLOC( sLTP_Q15, + psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 ); + ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 ); + ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 ); + /* Set up pointers to start of sub frame */ + NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length; + NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; + pxq = &NSQ->xq[ psEncC->ltp_mem_length ]; + for( k = 0; k < psEncC->nb_subfr; k++ ) { + A_Q12 = &PredCoef_Q12[ (( k >> 1 ) | ( 1 - LSF_interpolation_flag )) * MAX_LPC_ORDER ]; + B_Q14 = <PCoef_Q14[ k * LTP_ORDER ]; + AR_shp_Q13 = &AR2_Q13[ k * MAX_SHAPE_LPC_ORDER ]; + + /* Noise shape parameters */ + silk_assert( HarmShapeGain_Q14[ k ] >= 0 ); + HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 ); + HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 ); + + NSQ->rewhite_flag = 0; + if( psIndices->signalType == TYPE_VOICED ) { + /* Voiced */ + lag = pitchL[ k ]; + + /* Re-whitening */ + if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) { + /* Rewhiten with new A coefs */ + start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2; + silk_assert( start_idx > 0 ); + + silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ], + A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder ); + + NSQ->rewhite_flag = 1; + NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; + } + } + + silk_nsq_scale_states( psEncC, NSQ, x_Q3, x_sc_Q10, sLTP, sLTP_Q15, k, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType ); + + silk_noise_shape_quantizer( NSQ, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, A_Q12, B_Q14, + AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10, + offset_Q10, psEncC->subfr_length, psEncC->shapingLPCOrder, psEncC->predictLPCOrder ); + + x_Q3 += psEncC->subfr_length; + pulses += psEncC->subfr_length; + pxq += psEncC->subfr_length; + } + + /* Update lagPrev for next frame */ + NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ]; + + /* Save quantized speech and noise shaping signals */ + /* DEBUG_STORE_DATA( enc.pcm, &NSQ->xq[ psEncC->ltp_mem_length ], psEncC->frame_length * sizeof( opus_int16 ) ) */ + silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) ); + silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) ); + RESTORE_STACK; +} + +/***********************************/ +/* silk_noise_shape_quantizer */ +/***********************************/ +static OPUS_INLINE void silk_noise_shape_quantizer( + silk_nsq_state *NSQ, /* I/O NSQ state */ + opus_int signalType, /* I Signal type */ + const opus_int32 x_sc_Q10[], /* I */ + opus_int8 pulses[], /* O */ + opus_int16 xq[], /* O */ + opus_int32 sLTP_Q15[], /* I/O LTP state */ + const opus_int16 a_Q12[], /* I Short term prediction coefs */ + const opus_int16 b_Q14[], /* I Long term prediction coefs */ + const opus_int16 AR_shp_Q13[], /* I Noise shaping AR coefs */ + opus_int lag, /* I Pitch lag */ + opus_int32 HarmShapeFIRPacked_Q14, /* I */ + opus_int Tilt_Q14, /* I Spectral tilt */ + opus_int32 LF_shp_Q14, /* I */ + opus_int32 Gain_Q16, /* I */ + opus_int Lambda_Q10, /* I */ + opus_int offset_Q10, /* I */ + opus_int length, /* I Input length */ + opus_int shapingLPCOrder, /* I Noise shaping AR filter order */ + opus_int predictLPCOrder /* I Prediction filter order */ +) +{ + opus_int i, j; + opus_int32 LTP_pred_Q13, LPC_pred_Q10, n_AR_Q12, n_LTP_Q13; + opus_int32 n_LF_Q12, r_Q10, rr_Q10, q1_Q0, q1_Q10, q2_Q10, rd1_Q20, rd2_Q20; + opus_int32 exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10; + opus_int32 tmp1, tmp2, sLF_AR_shp_Q14; + opus_int32 *psLPC_Q14, *shp_lag_ptr, *pred_lag_ptr; + + shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ]; + pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ]; + Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 ); + + /* Set up short term AR state */ + psLPC_Q14 = &NSQ->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 ]; + + for( i = 0; i < length; i++ ) { + /* Generate dither */ + NSQ->rand_seed = silk_RAND( NSQ->rand_seed ); + + /* Short-term prediction */ + silk_assert( predictLPCOrder == 10 || predictLPCOrder == 16 ); + /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ + LPC_pred_Q10 = silk_RSHIFT( predictLPCOrder, 1 ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ 0 ], a_Q12[ 0 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -1 ], a_Q12[ 1 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -2 ], a_Q12[ 2 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -3 ], a_Q12[ 3 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -4 ], a_Q12[ 4 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -5 ], a_Q12[ 5 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -6 ], a_Q12[ 6 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -7 ], a_Q12[ 7 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -8 ], a_Q12[ 8 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -9 ], a_Q12[ 9 ] ); + if( predictLPCOrder == 16 ) { + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -10 ], a_Q12[ 10 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -11 ], a_Q12[ 11 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -12 ], a_Q12[ 12 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -13 ], a_Q12[ 13 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -14 ], a_Q12[ 14 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -15 ], a_Q12[ 15 ] ); + } + + /* Long-term prediction */ + if( signalType == TYPE_VOICED ) { + /* Unrolled loop */ + /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ + LTP_pred_Q13 = 2; + LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ 0 ], b_Q14[ 0 ] ); + LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -1 ], b_Q14[ 1 ] ); + LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -2 ], b_Q14[ 2 ] ); + LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -3 ], b_Q14[ 3 ] ); + LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -4 ], b_Q14[ 4 ] ); + pred_lag_ptr++; + } else { + LTP_pred_Q13 = 0; + } + + /* Noise shape feedback */ + silk_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */ + tmp2 = psLPC_Q14[ 0 ]; + tmp1 = NSQ->sAR2_Q14[ 0 ]; + NSQ->sAR2_Q14[ 0 ] = tmp2; + n_AR_Q12 = silk_RSHIFT( shapingLPCOrder, 1 ); + n_AR_Q12 = silk_SMLAWB( n_AR_Q12, tmp2, AR_shp_Q13[ 0 ] ); + for( j = 2; j < shapingLPCOrder; j += 2 ) { + tmp2 = NSQ->sAR2_Q14[ j - 1 ]; + NSQ->sAR2_Q14[ j - 1 ] = tmp1; + n_AR_Q12 = silk_SMLAWB( n_AR_Q12, tmp1, AR_shp_Q13[ j - 1 ] ); + tmp1 = NSQ->sAR2_Q14[ j + 0 ]; + NSQ->sAR2_Q14[ j + 0 ] = tmp2; + n_AR_Q12 = silk_SMLAWB( n_AR_Q12, tmp2, AR_shp_Q13[ j ] ); + } + NSQ->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1; + n_AR_Q12 = silk_SMLAWB( n_AR_Q12, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] ); + + n_AR_Q12 = silk_LSHIFT32( n_AR_Q12, 1 ); /* Q11 -> Q12 */ + n_AR_Q12 = silk_SMLAWB( n_AR_Q12, NSQ->sLF_AR_shp_Q14, Tilt_Q14 ); + + n_LF_Q12 = silk_SMULWB( NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - 1 ], LF_shp_Q14 ); + n_LF_Q12 = silk_SMLAWT( n_LF_Q12, NSQ->sLF_AR_shp_Q14, LF_shp_Q14 ); + + silk_assert( lag > 0 || signalType != TYPE_VOICED ); + + /* Combine prediction and noise shaping signals */ + tmp1 = silk_SUB32( silk_LSHIFT32( LPC_pred_Q10, 2 ), n_AR_Q12 ); /* Q12 */ + tmp1 = silk_SUB32( tmp1, n_LF_Q12 ); /* Q12 */ + if( lag > 0 ) { + /* Symmetric, packed FIR coefficients */ + n_LTP_Q13 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 ); + n_LTP_Q13 = silk_SMLAWT( n_LTP_Q13, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 ); + n_LTP_Q13 = silk_LSHIFT( n_LTP_Q13, 1 ); + shp_lag_ptr++; + + tmp2 = silk_SUB32( LTP_pred_Q13, n_LTP_Q13 ); /* Q13 */ + tmp1 = silk_ADD_LSHIFT32( tmp2, tmp1, 1 ); /* Q13 */ + tmp1 = silk_RSHIFT_ROUND( tmp1, 3 ); /* Q10 */ + } else { + tmp1 = silk_RSHIFT_ROUND( tmp1, 2 ); /* Q10 */ + } + + r_Q10 = silk_SUB32( x_sc_Q10[ i ], tmp1 ); /* residual error Q10 */ + + /* Flip sign depending on dither */ + if ( NSQ->rand_seed < 0 ) { + r_Q10 = -r_Q10; + } + r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 ); + + /* Find two quantization level candidates and measure their rate-distortion */ + q1_Q10 = silk_SUB32( r_Q10, offset_Q10 ); + q1_Q0 = silk_RSHIFT( q1_Q10, 10 ); + if( q1_Q0 > 0 ) { + q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); + q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 ); + q2_Q10 = silk_ADD32( q1_Q10, 1024 ); + rd1_Q20 = silk_SMULBB( q1_Q10, Lambda_Q10 ); + rd2_Q20 = silk_SMULBB( q2_Q10, Lambda_Q10 ); + } else if( q1_Q0 == 0 ) { + q1_Q10 = offset_Q10; + q2_Q10 = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 ); + rd1_Q20 = silk_SMULBB( q1_Q10, Lambda_Q10 ); + rd2_Q20 = silk_SMULBB( q2_Q10, Lambda_Q10 ); + } else if( q1_Q0 == -1 ) { + q2_Q10 = offset_Q10; + q1_Q10 = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 ); + rd1_Q20 = silk_SMULBB( -q1_Q10, Lambda_Q10 ); + rd2_Q20 = silk_SMULBB( q2_Q10, Lambda_Q10 ); + } else { /* Q1_Q0 < -1 */ + q1_Q10 = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); + q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 ); + q2_Q10 = silk_ADD32( q1_Q10, 1024 ); + rd1_Q20 = silk_SMULBB( -q1_Q10, Lambda_Q10 ); + rd2_Q20 = silk_SMULBB( -q2_Q10, Lambda_Q10 ); + } + rr_Q10 = silk_SUB32( r_Q10, q1_Q10 ); + rd1_Q20 = silk_SMLABB( rd1_Q20, rr_Q10, rr_Q10 ); + rr_Q10 = silk_SUB32( r_Q10, q2_Q10 ); + rd2_Q20 = silk_SMLABB( rd2_Q20, rr_Q10, rr_Q10 ); + + if( rd2_Q20 < rd1_Q20 ) { + q1_Q10 = q2_Q10; + } + + pulses[ i ] = (opus_int8)silk_RSHIFT_ROUND( q1_Q10, 10 ); + + /* Excitation */ + exc_Q14 = silk_LSHIFT( q1_Q10, 4 ); + if ( NSQ->rand_seed < 0 ) { + exc_Q14 = -exc_Q14; + } + + /* Add predictions */ + LPC_exc_Q14 = silk_ADD_LSHIFT32( exc_Q14, LTP_pred_Q13, 1 ); + xq_Q14 = silk_ADD_LSHIFT32( LPC_exc_Q14, LPC_pred_Q10, 4 ); + + /* Scale XQ back to normal level before saving */ + xq[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( xq_Q14, Gain_Q10 ), 8 ) ); + + /* Update states */ + psLPC_Q14++; + *psLPC_Q14 = xq_Q14; + sLF_AR_shp_Q14 = silk_SUB_LSHIFT32( xq_Q14, n_AR_Q12, 2 ); + NSQ->sLF_AR_shp_Q14 = sLF_AR_shp_Q14; + + NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx ] = silk_SUB_LSHIFT32( sLF_AR_shp_Q14, n_LF_Q12, 2 ); + sLTP_Q15[ NSQ->sLTP_buf_idx ] = silk_LSHIFT( LPC_exc_Q14, 1 ); + NSQ->sLTP_shp_buf_idx++; + NSQ->sLTP_buf_idx++; + + /* Make dither dependent on quantized signal */ + NSQ->rand_seed = silk_ADD32_ovflw( NSQ->rand_seed, pulses[ i ] ); + } + + /* Update LPC synth buffer */ + silk_memcpy( NSQ->sLPC_Q14, &NSQ->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); +} + +static OPUS_INLINE void silk_nsq_scale_states( + const silk_encoder_state *psEncC, /* I Encoder State */ + silk_nsq_state *NSQ, /* I/O NSQ state */ + const opus_int32 x_Q3[], /* I input in Q3 */ + opus_int32 x_sc_Q10[], /* O input scaled with 1/Gain */ + const opus_int16 sLTP[], /* I re-whitened LTP state in Q0 */ + opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ + opus_int subfr, /* I subframe number */ + const opus_int LTP_scale_Q14, /* I */ + const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ + const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ + const opus_int signal_type /* I Signal type */ +) +{ + opus_int i, lag; + opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q23; + + lag = pitchL[ subfr ]; + inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 ); + silk_assert( inv_gain_Q31 != 0 ); + + /* Calculate gain adjustment factor */ + if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) { + gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 ); + } else { + gain_adj_Q16 = (opus_int32)1 << 16; + } + + /* Scale input */ + inv_gain_Q23 = silk_RSHIFT_ROUND( inv_gain_Q31, 8 ); + for( i = 0; i < psEncC->subfr_length; i++ ) { + x_sc_Q10[ i ] = silk_SMULWW( x_Q3[ i ], inv_gain_Q23 ); + } + + /* Save inverse gain */ + NSQ->prev_gain_Q16 = Gains_Q16[ subfr ]; + + /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */ + if( NSQ->rewhite_flag ) { + if( subfr == 0 ) { + /* Do LTP downscaling */ + inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 ); + } + for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) { + silk_assert( i < MAX_FRAME_LENGTH ); + sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] ); + } + } + + /* Adjust for changing gain */ + if( gain_adj_Q16 != (opus_int32)1 << 16 ) { + /* Scale long-term shaping state */ + for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx; i++ ) { + NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] ); + } + + /* Scale long-term prediction state */ + if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) { + for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) { + sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] ); + } + } + + NSQ->sLF_AR_shp_Q14 = silk_SMULWW( gain_adj_Q16, NSQ->sLF_AR_shp_Q14 ); + + /* Scale short-term prediction and shaping states */ + for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) { + NSQ->sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLPC_Q14[ i ] ); + } + for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) { + NSQ->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sAR2_Q14[ i ] ); + } + } +} diff --git a/src/opus-1.1/silk/NSQ_del_dec.c b/src/opus-1.1/silk/NSQ_del_dec.c new file mode 100644 index 00000000..522be406 --- /dev/null +++ b/src/opus-1.1/silk/NSQ_del_dec.c @@ -0,0 +1,719 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main.h" +#include "stack_alloc.h" + +typedef struct { + opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ]; + opus_int32 RandState[ DECISION_DELAY ]; + opus_int32 Q_Q10[ DECISION_DELAY ]; + opus_int32 Xq_Q14[ DECISION_DELAY ]; + opus_int32 Pred_Q15[ DECISION_DELAY ]; + opus_int32 Shape_Q14[ DECISION_DELAY ]; + opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ]; + opus_int32 LF_AR_Q14; + opus_int32 Seed; + opus_int32 SeedInit; + opus_int32 RD_Q10; +} NSQ_del_dec_struct; + +typedef struct { + opus_int32 Q_Q10; + opus_int32 RD_Q10; + opus_int32 xq_Q14; + opus_int32 LF_AR_Q14; + opus_int32 sLTP_shp_Q14; + opus_int32 LPC_exc_Q14; +} NSQ_sample_struct; + +typedef NSQ_sample_struct NSQ_sample_pair[ 2 ]; + +static OPUS_INLINE void silk_nsq_del_dec_scale_states( + const silk_encoder_state *psEncC, /* I Encoder State */ + silk_nsq_state *NSQ, /* I/O NSQ state */ + NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ + const opus_int32 x_Q3[], /* I Input in Q3 */ + opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */ + const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */ + opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ + opus_int subfr, /* I Subframe number */ + opus_int nStatesDelayedDecision, /* I Number of del dec states */ + const opus_int LTP_scale_Q14, /* I LTP state scaling */ + const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ + const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ + const opus_int signal_type, /* I Signal type */ + const opus_int decisionDelay /* I Decision delay */ +); + +/******************************************/ +/* Noise shape quantizer for one subframe */ +/******************************************/ +static OPUS_INLINE void silk_noise_shape_quantizer_del_dec( + silk_nsq_state *NSQ, /* I/O NSQ state */ + NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ + opus_int signalType, /* I Signal type */ + const opus_int32 x_Q10[], /* I */ + opus_int8 pulses[], /* O */ + opus_int16 xq[], /* O */ + opus_int32 sLTP_Q15[], /* I/O LTP filter state */ + opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */ + const opus_int16 a_Q12[], /* I Short term prediction coefs */ + const opus_int16 b_Q14[], /* I Long term prediction coefs */ + const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */ + opus_int lag, /* I Pitch lag */ + opus_int32 HarmShapeFIRPacked_Q14, /* I */ + opus_int Tilt_Q14, /* I Spectral tilt */ + opus_int32 LF_shp_Q14, /* I */ + opus_int32 Gain_Q16, /* I */ + opus_int Lambda_Q10, /* I */ + opus_int offset_Q10, /* I */ + opus_int length, /* I Input length */ + opus_int subfr, /* I Subframe number */ + opus_int shapingLPCOrder, /* I Shaping LPC filter order */ + opus_int predictLPCOrder, /* I Prediction filter order */ + opus_int warping_Q16, /* I */ + opus_int nStatesDelayedDecision, /* I Number of states in decision tree */ + opus_int *smpl_buf_idx, /* I Index to newest samples in buffers */ + opus_int decisionDelay /* I */ +); + +void silk_NSQ_del_dec( + const silk_encoder_state *psEncC, /* I/O Encoder State */ + silk_nsq_state *NSQ, /* I/O NSQ state */ + SideInfoIndices *psIndices, /* I/O Quantization Indices */ + const opus_int32 x_Q3[], /* I Prefiltered input signal */ + opus_int8 pulses[], /* O Quantized pulse signal */ + const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ + const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ + const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ + const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ + const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ + const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ + const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ + const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ + const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ + const opus_int LTP_scale_Q14 /* I LTP state scaling */ +) +{ + opus_int i, k, lag, start_idx, LSF_interpolation_flag, Winner_ind, subfr; + opus_int last_smple_idx, smpl_buf_idx, decisionDelay; + const opus_int16 *A_Q12, *B_Q14, *AR_shp_Q13; + opus_int16 *pxq; + VARDECL( opus_int32, sLTP_Q15 ); + VARDECL( opus_int16, sLTP ); + opus_int32 HarmShapeFIRPacked_Q14; + opus_int offset_Q10; + opus_int32 RDmin_Q10, Gain_Q10; + VARDECL( opus_int32, x_sc_Q10 ); + VARDECL( opus_int32, delayedGain_Q10 ); + VARDECL( NSQ_del_dec_struct, psDelDec ); + NSQ_del_dec_struct *psDD; + SAVE_STACK; + + /* Set unvoiced lag to the previous one, overwrite later for voiced */ + lag = NSQ->lagPrev; + + silk_assert( NSQ->prev_gain_Q16 != 0 ); + + /* Initialize delayed decision states */ + ALLOC( psDelDec, psEncC->nStatesDelayedDecision, NSQ_del_dec_struct ); + silk_memset( psDelDec, 0, psEncC->nStatesDelayedDecision * sizeof( NSQ_del_dec_struct ) ); + for( k = 0; k < psEncC->nStatesDelayedDecision; k++ ) { + psDD = &psDelDec[ k ]; + psDD->Seed = ( k + psIndices->Seed ) & 3; + psDD->SeedInit = psDD->Seed; + psDD->RD_Q10 = 0; + psDD->LF_AR_Q14 = NSQ->sLF_AR_shp_Q14; + psDD->Shape_Q14[ 0 ] = NSQ->sLTP_shp_Q14[ psEncC->ltp_mem_length - 1 ]; + silk_memcpy( psDD->sLPC_Q14, NSQ->sLPC_Q14, NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); + silk_memcpy( psDD->sAR2_Q14, NSQ->sAR2_Q14, sizeof( NSQ->sAR2_Q14 ) ); + } + + offset_Q10 = silk_Quantization_Offsets_Q10[ psIndices->signalType >> 1 ][ psIndices->quantOffsetType ]; + smpl_buf_idx = 0; /* index of oldest samples */ + + decisionDelay = silk_min_int( DECISION_DELAY, psEncC->subfr_length ); + + /* For voiced frames limit the decision delay to lower than the pitch lag */ + if( psIndices->signalType == TYPE_VOICED ) { + for( k = 0; k < psEncC->nb_subfr; k++ ) { + decisionDelay = silk_min_int( decisionDelay, pitchL[ k ] - LTP_ORDER / 2 - 1 ); + } + } else { + if( lag > 0 ) { + decisionDelay = silk_min_int( decisionDelay, lag - LTP_ORDER / 2 - 1 ); + } + } + + if( psIndices->NLSFInterpCoef_Q2 == 4 ) { + LSF_interpolation_flag = 0; + } else { + LSF_interpolation_flag = 1; + } + + ALLOC( sLTP_Q15, + psEncC->ltp_mem_length + psEncC->frame_length, opus_int32 ); + ALLOC( sLTP, psEncC->ltp_mem_length + psEncC->frame_length, opus_int16 ); + ALLOC( x_sc_Q10, psEncC->subfr_length, opus_int32 ); + ALLOC( delayedGain_Q10, DECISION_DELAY, opus_int32 ); + /* Set up pointers to start of sub frame */ + pxq = &NSQ->xq[ psEncC->ltp_mem_length ]; + NSQ->sLTP_shp_buf_idx = psEncC->ltp_mem_length; + NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; + subfr = 0; + for( k = 0; k < psEncC->nb_subfr; k++ ) { + A_Q12 = &PredCoef_Q12[ ( ( k >> 1 ) | ( 1 - LSF_interpolation_flag ) ) * MAX_LPC_ORDER ]; + B_Q14 = <PCoef_Q14[ k * LTP_ORDER ]; + AR_shp_Q13 = &AR2_Q13[ k * MAX_SHAPE_LPC_ORDER ]; + + /* Noise shape parameters */ + silk_assert( HarmShapeGain_Q14[ k ] >= 0 ); + HarmShapeFIRPacked_Q14 = silk_RSHIFT( HarmShapeGain_Q14[ k ], 2 ); + HarmShapeFIRPacked_Q14 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q14[ k ], 1 ), 16 ); + + NSQ->rewhite_flag = 0; + if( psIndices->signalType == TYPE_VOICED ) { + /* Voiced */ + lag = pitchL[ k ]; + + /* Re-whitening */ + if( ( k & ( 3 - silk_LSHIFT( LSF_interpolation_flag, 1 ) ) ) == 0 ) { + if( k == 2 ) { + /* RESET DELAYED DECISIONS */ + /* Find winner */ + RDmin_Q10 = psDelDec[ 0 ].RD_Q10; + Winner_ind = 0; + for( i = 1; i < psEncC->nStatesDelayedDecision; i++ ) { + if( psDelDec[ i ].RD_Q10 < RDmin_Q10 ) { + RDmin_Q10 = psDelDec[ i ].RD_Q10; + Winner_ind = i; + } + } + for( i = 0; i < psEncC->nStatesDelayedDecision; i++ ) { + if( i != Winner_ind ) { + psDelDec[ i ].RD_Q10 += ( silk_int32_MAX >> 4 ); + silk_assert( psDelDec[ i ].RD_Q10 >= 0 ); + } + } + + /* Copy final part of signals from winner state to output and long-term filter states */ + psDD = &psDelDec[ Winner_ind ]; + last_smple_idx = smpl_buf_idx + decisionDelay; + for( i = 0; i < decisionDelay; i++ ) { + last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK; + pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 ); + pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( + silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gains_Q16[ 1 ] ), 14 ) ); + NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q14[ last_smple_idx ]; + } + + subfr = 0; + } + + /* Rewhiten with new A coefs */ + start_idx = psEncC->ltp_mem_length - lag - psEncC->predictLPCOrder - LTP_ORDER / 2; + silk_assert( start_idx > 0 ); + + silk_LPC_analysis_filter( &sLTP[ start_idx ], &NSQ->xq[ start_idx + k * psEncC->subfr_length ], + A_Q12, psEncC->ltp_mem_length - start_idx, psEncC->predictLPCOrder ); + + NSQ->sLTP_buf_idx = psEncC->ltp_mem_length; + NSQ->rewhite_flag = 1; + } + } + + silk_nsq_del_dec_scale_states( psEncC, NSQ, psDelDec, x_Q3, x_sc_Q10, sLTP, sLTP_Q15, k, + psEncC->nStatesDelayedDecision, LTP_scale_Q14, Gains_Q16, pitchL, psIndices->signalType, decisionDelay ); + + silk_noise_shape_quantizer_del_dec( NSQ, psDelDec, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, + delayedGain_Q10, A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], + Gains_Q16[ k ], Lambda_Q10, offset_Q10, psEncC->subfr_length, subfr++, psEncC->shapingLPCOrder, + psEncC->predictLPCOrder, psEncC->warping_Q16, psEncC->nStatesDelayedDecision, &smpl_buf_idx, decisionDelay ); + + x_Q3 += psEncC->subfr_length; + pulses += psEncC->subfr_length; + pxq += psEncC->subfr_length; + } + + /* Find winner */ + RDmin_Q10 = psDelDec[ 0 ].RD_Q10; + Winner_ind = 0; + for( k = 1; k < psEncC->nStatesDelayedDecision; k++ ) { + if( psDelDec[ k ].RD_Q10 < RDmin_Q10 ) { + RDmin_Q10 = psDelDec[ k ].RD_Q10; + Winner_ind = k; + } + } + + /* Copy final part of signals from winner state to output and long-term filter states */ + psDD = &psDelDec[ Winner_ind ]; + psIndices->Seed = psDD->SeedInit; + last_smple_idx = smpl_buf_idx + decisionDelay; + Gain_Q10 = silk_RSHIFT32( Gains_Q16[ psEncC->nb_subfr - 1 ], 6 ); + for( i = 0; i < decisionDelay; i++ ) { + last_smple_idx = ( last_smple_idx - 1 ) & DECISION_DELAY_MASK; + pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 ); + pxq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( + silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], Gain_Q10 ), 8 ) ); + NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay + i ] = psDD->Shape_Q14[ last_smple_idx ]; + } + silk_memcpy( NSQ->sLPC_Q14, &psDD->sLPC_Q14[ psEncC->subfr_length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); + silk_memcpy( NSQ->sAR2_Q14, psDD->sAR2_Q14, sizeof( psDD->sAR2_Q14 ) ); + + /* Update states */ + NSQ->sLF_AR_shp_Q14 = psDD->LF_AR_Q14; + NSQ->lagPrev = pitchL[ psEncC->nb_subfr - 1 ]; + + /* Save quantized speech signal */ + /* DEBUG_STORE_DATA( enc.pcm, &NSQ->xq[psEncC->ltp_mem_length], psEncC->frame_length * sizeof( opus_int16 ) ) */ + silk_memmove( NSQ->xq, &NSQ->xq[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int16 ) ); + silk_memmove( NSQ->sLTP_shp_Q14, &NSQ->sLTP_shp_Q14[ psEncC->frame_length ], psEncC->ltp_mem_length * sizeof( opus_int32 ) ); + RESTORE_STACK; +} + +/******************************************/ +/* Noise shape quantizer for one subframe */ +/******************************************/ +static OPUS_INLINE void silk_noise_shape_quantizer_del_dec( + silk_nsq_state *NSQ, /* I/O NSQ state */ + NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ + opus_int signalType, /* I Signal type */ + const opus_int32 x_Q10[], /* I */ + opus_int8 pulses[], /* O */ + opus_int16 xq[], /* O */ + opus_int32 sLTP_Q15[], /* I/O LTP filter state */ + opus_int32 delayedGain_Q10[], /* I/O Gain delay buffer */ + const opus_int16 a_Q12[], /* I Short term prediction coefs */ + const opus_int16 b_Q14[], /* I Long term prediction coefs */ + const opus_int16 AR_shp_Q13[], /* I Noise shaping coefs */ + opus_int lag, /* I Pitch lag */ + opus_int32 HarmShapeFIRPacked_Q14, /* I */ + opus_int Tilt_Q14, /* I Spectral tilt */ + opus_int32 LF_shp_Q14, /* I */ + opus_int32 Gain_Q16, /* I */ + opus_int Lambda_Q10, /* I */ + opus_int offset_Q10, /* I */ + opus_int length, /* I Input length */ + opus_int subfr, /* I Subframe number */ + opus_int shapingLPCOrder, /* I Shaping LPC filter order */ + opus_int predictLPCOrder, /* I Prediction filter order */ + opus_int warping_Q16, /* I */ + opus_int nStatesDelayedDecision, /* I Number of states in decision tree */ + opus_int *smpl_buf_idx, /* I Index to newest samples in buffers */ + opus_int decisionDelay /* I */ +) +{ + opus_int i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx; + opus_int32 Winner_rand_state; + opus_int32 LTP_pred_Q14, LPC_pred_Q14, n_AR_Q14, n_LTP_Q14; + opus_int32 n_LF_Q14, r_Q10, rr_Q10, rd1_Q10, rd2_Q10, RDmin_Q10, RDmax_Q10; + opus_int32 q1_Q0, q1_Q10, q2_Q10, exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10; + opus_int32 tmp1, tmp2, sLF_AR_shp_Q14; + opus_int32 *pred_lag_ptr, *shp_lag_ptr, *psLPC_Q14; + VARDECL( NSQ_sample_pair, psSampleState ); + NSQ_del_dec_struct *psDD; + NSQ_sample_struct *psSS; + SAVE_STACK; + + silk_assert( nStatesDelayedDecision > 0 ); + ALLOC( psSampleState, nStatesDelayedDecision, NSQ_sample_pair ); + + shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ]; + pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ]; + Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 ); + + for( i = 0; i < length; i++ ) { + /* Perform common calculations used in all states */ + + /* Long-term prediction */ + if( signalType == TYPE_VOICED ) { + /* Unrolled loop */ + /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ + LTP_pred_Q14 = 2; + LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ 0 ], b_Q14[ 0 ] ); + LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], b_Q14[ 1 ] ); + LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], b_Q14[ 2 ] ); + LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], b_Q14[ 3 ] ); + LTP_pred_Q14 = silk_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], b_Q14[ 4 ] ); + LTP_pred_Q14 = silk_LSHIFT( LTP_pred_Q14, 1 ); /* Q13 -> Q14 */ + pred_lag_ptr++; + } else { + LTP_pred_Q14 = 0; + } + + /* Long-term shaping */ + if( lag > 0 ) { + /* Symmetric, packed FIR coefficients */ + n_LTP_Q14 = silk_SMULWB( silk_ADD32( shp_lag_ptr[ 0 ], shp_lag_ptr[ -2 ] ), HarmShapeFIRPacked_Q14 ); + n_LTP_Q14 = silk_SMLAWT( n_LTP_Q14, shp_lag_ptr[ -1 ], HarmShapeFIRPacked_Q14 ); + n_LTP_Q14 = silk_SUB_LSHIFT32( LTP_pred_Q14, n_LTP_Q14, 2 ); /* Q12 -> Q14 */ + shp_lag_ptr++; + } else { + n_LTP_Q14 = 0; + } + + for( k = 0; k < nStatesDelayedDecision; k++ ) { + /* Delayed decision state */ + psDD = &psDelDec[ k ]; + + /* Sample state */ + psSS = psSampleState[ k ]; + + /* Generate dither */ + psDD->Seed = silk_RAND( psDD->Seed ); + + /* Pointer used in short term prediction and shaping */ + psLPC_Q14 = &psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 + i ]; + /* Short-term prediction */ + silk_assert( predictLPCOrder == 10 || predictLPCOrder == 16 ); + /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ + LPC_pred_Q14 = silk_RSHIFT( predictLPCOrder, 1 ); + LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ 0 ], a_Q12[ 0 ] ); + LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -1 ], a_Q12[ 1 ] ); + LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -2 ], a_Q12[ 2 ] ); + LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -3 ], a_Q12[ 3 ] ); + LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -4 ], a_Q12[ 4 ] ); + LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -5 ], a_Q12[ 5 ] ); + LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -6 ], a_Q12[ 6 ] ); + LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -7 ], a_Q12[ 7 ] ); + LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -8 ], a_Q12[ 8 ] ); + LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -9 ], a_Q12[ 9 ] ); + if( predictLPCOrder == 16 ) { + LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -10 ], a_Q12[ 10 ] ); + LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -11 ], a_Q12[ 11 ] ); + LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -12 ], a_Q12[ 12 ] ); + LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -13 ], a_Q12[ 13 ] ); + LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -14 ], a_Q12[ 14 ] ); + LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -15 ], a_Q12[ 15 ] ); + } + LPC_pred_Q14 = silk_LSHIFT( LPC_pred_Q14, 4 ); /* Q10 -> Q14 */ + + /* Noise shape feedback */ + silk_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */ + /* Output of lowpass section */ + tmp2 = silk_SMLAWB( psLPC_Q14[ 0 ], psDD->sAR2_Q14[ 0 ], warping_Q16 ); + /* Output of allpass section */ + tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ 0 ], psDD->sAR2_Q14[ 1 ] - tmp2, warping_Q16 ); + psDD->sAR2_Q14[ 0 ] = tmp2; + n_AR_Q14 = silk_RSHIFT( shapingLPCOrder, 1 ); + n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp2, AR_shp_Q13[ 0 ] ); + /* Loop over allpass sections */ + for( j = 2; j < shapingLPCOrder; j += 2 ) { + /* Output of allpass section */ + tmp2 = silk_SMLAWB( psDD->sAR2_Q14[ j - 1 ], psDD->sAR2_Q14[ j + 0 ] - tmp1, warping_Q16 ); + psDD->sAR2_Q14[ j - 1 ] = tmp1; + n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp1, AR_shp_Q13[ j - 1 ] ); + /* Output of allpass section */ + tmp1 = silk_SMLAWB( psDD->sAR2_Q14[ j + 0 ], psDD->sAR2_Q14[ j + 1 ] - tmp2, warping_Q16 ); + psDD->sAR2_Q14[ j + 0 ] = tmp2; + n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp2, AR_shp_Q13[ j ] ); + } + psDD->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1; + n_AR_Q14 = silk_SMLAWB( n_AR_Q14, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] ); + + n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 1 ); /* Q11 -> Q12 */ + n_AR_Q14 = silk_SMLAWB( n_AR_Q14, psDD->LF_AR_Q14, Tilt_Q14 ); /* Q12 */ + n_AR_Q14 = silk_LSHIFT( n_AR_Q14, 2 ); /* Q12 -> Q14 */ + + n_LF_Q14 = silk_SMULWB( psDD->Shape_Q14[ *smpl_buf_idx ], LF_shp_Q14 ); /* Q12 */ + n_LF_Q14 = silk_SMLAWT( n_LF_Q14, psDD->LF_AR_Q14, LF_shp_Q14 ); /* Q12 */ + n_LF_Q14 = silk_LSHIFT( n_LF_Q14, 2 ); /* Q12 -> Q14 */ + + /* Input minus prediction plus noise feedback */ + /* r = x[ i ] - LTP_pred - LPC_pred + n_AR + n_Tilt + n_LF + n_LTP */ + tmp1 = silk_ADD32( n_AR_Q14, n_LF_Q14 ); /* Q14 */ + tmp2 = silk_ADD32( n_LTP_Q14, LPC_pred_Q14 ); /* Q13 */ + tmp1 = silk_SUB32( tmp2, tmp1 ); /* Q13 */ + tmp1 = silk_RSHIFT_ROUND( tmp1, 4 ); /* Q10 */ + + r_Q10 = silk_SUB32( x_Q10[ i ], tmp1 ); /* residual error Q10 */ + + /* Flip sign depending on dither */ + if ( psDD->Seed < 0 ) { + r_Q10 = -r_Q10; + } + r_Q10 = silk_LIMIT_32( r_Q10, -(31 << 10), 30 << 10 ); + + /* Find two quantization level candidates and measure their rate-distortion */ + q1_Q10 = silk_SUB32( r_Q10, offset_Q10 ); + q1_Q0 = silk_RSHIFT( q1_Q10, 10 ); + if( q1_Q0 > 0 ) { + q1_Q10 = silk_SUB32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); + q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 ); + q2_Q10 = silk_ADD32( q1_Q10, 1024 ); + rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 ); + rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 ); + } else if( q1_Q0 == 0 ) { + q1_Q10 = offset_Q10; + q2_Q10 = silk_ADD32( q1_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 ); + rd1_Q10 = silk_SMULBB( q1_Q10, Lambda_Q10 ); + rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 ); + } else if( q1_Q0 == -1 ) { + q2_Q10 = offset_Q10; + q1_Q10 = silk_SUB32( q2_Q10, 1024 - QUANT_LEVEL_ADJUST_Q10 ); + rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 ); + rd2_Q10 = silk_SMULBB( q2_Q10, Lambda_Q10 ); + } else { /* q1_Q0 < -1 */ + q1_Q10 = silk_ADD32( silk_LSHIFT( q1_Q0, 10 ), QUANT_LEVEL_ADJUST_Q10 ); + q1_Q10 = silk_ADD32( q1_Q10, offset_Q10 ); + q2_Q10 = silk_ADD32( q1_Q10, 1024 ); + rd1_Q10 = silk_SMULBB( -q1_Q10, Lambda_Q10 ); + rd2_Q10 = silk_SMULBB( -q2_Q10, Lambda_Q10 ); + } + rr_Q10 = silk_SUB32( r_Q10, q1_Q10 ); + rd1_Q10 = silk_RSHIFT( silk_SMLABB( rd1_Q10, rr_Q10, rr_Q10 ), 10 ); + rr_Q10 = silk_SUB32( r_Q10, q2_Q10 ); + rd2_Q10 = silk_RSHIFT( silk_SMLABB( rd2_Q10, rr_Q10, rr_Q10 ), 10 ); + + if( rd1_Q10 < rd2_Q10 ) { + psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 ); + psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 ); + psSS[ 0 ].Q_Q10 = q1_Q10; + psSS[ 1 ].Q_Q10 = q2_Q10; + } else { + psSS[ 0 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd2_Q10 ); + psSS[ 1 ].RD_Q10 = silk_ADD32( psDD->RD_Q10, rd1_Q10 ); + psSS[ 0 ].Q_Q10 = q2_Q10; + psSS[ 1 ].Q_Q10 = q1_Q10; + } + + /* Update states for best quantization */ + + /* Quantized excitation */ + exc_Q14 = silk_LSHIFT32( psSS[ 0 ].Q_Q10, 4 ); + if ( psDD->Seed < 0 ) { + exc_Q14 = -exc_Q14; + } + + /* Add predictions */ + LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 ); + xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 ); + + /* Update states */ + sLF_AR_shp_Q14 = silk_SUB32( xq_Q14, n_AR_Q14 ); + psSS[ 0 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 ); + psSS[ 0 ].LF_AR_Q14 = sLF_AR_shp_Q14; + psSS[ 0 ].LPC_exc_Q14 = LPC_exc_Q14; + psSS[ 0 ].xq_Q14 = xq_Q14; + + /* Update states for second best quantization */ + + /* Quantized excitation */ + exc_Q14 = silk_LSHIFT32( psSS[ 1 ].Q_Q10, 4 ); + if ( psDD->Seed < 0 ) { + exc_Q14 = -exc_Q14; + } + + + /* Add predictions */ + LPC_exc_Q14 = silk_ADD32( exc_Q14, LTP_pred_Q14 ); + xq_Q14 = silk_ADD32( LPC_exc_Q14, LPC_pred_Q14 ); + + /* Update states */ + sLF_AR_shp_Q14 = silk_SUB32( xq_Q14, n_AR_Q14 ); + psSS[ 1 ].sLTP_shp_Q14 = silk_SUB32( sLF_AR_shp_Q14, n_LF_Q14 ); + psSS[ 1 ].LF_AR_Q14 = sLF_AR_shp_Q14; + psSS[ 1 ].LPC_exc_Q14 = LPC_exc_Q14; + psSS[ 1 ].xq_Q14 = xq_Q14; + } + + *smpl_buf_idx = ( *smpl_buf_idx - 1 ) & DECISION_DELAY_MASK; /* Index to newest samples */ + last_smple_idx = ( *smpl_buf_idx + decisionDelay ) & DECISION_DELAY_MASK; /* Index to decisionDelay old samples */ + + /* Find winner */ + RDmin_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10; + Winner_ind = 0; + for( k = 1; k < nStatesDelayedDecision; k++ ) { + if( psSampleState[ k ][ 0 ].RD_Q10 < RDmin_Q10 ) { + RDmin_Q10 = psSampleState[ k ][ 0 ].RD_Q10; + Winner_ind = k; + } + } + + /* Increase RD values of expired states */ + Winner_rand_state = psDelDec[ Winner_ind ].RandState[ last_smple_idx ]; + for( k = 0; k < nStatesDelayedDecision; k++ ) { + if( psDelDec[ k ].RandState[ last_smple_idx ] != Winner_rand_state ) { + psSampleState[ k ][ 0 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 0 ].RD_Q10, silk_int32_MAX >> 4 ); + psSampleState[ k ][ 1 ].RD_Q10 = silk_ADD32( psSampleState[ k ][ 1 ].RD_Q10, silk_int32_MAX >> 4 ); + silk_assert( psSampleState[ k ][ 0 ].RD_Q10 >= 0 ); + } + } + + /* Find worst in first set and best in second set */ + RDmax_Q10 = psSampleState[ 0 ][ 0 ].RD_Q10; + RDmin_Q10 = psSampleState[ 0 ][ 1 ].RD_Q10; + RDmax_ind = 0; + RDmin_ind = 0; + for( k = 1; k < nStatesDelayedDecision; k++ ) { + /* find worst in first set */ + if( psSampleState[ k ][ 0 ].RD_Q10 > RDmax_Q10 ) { + RDmax_Q10 = psSampleState[ k ][ 0 ].RD_Q10; + RDmax_ind = k; + } + /* find best in second set */ + if( psSampleState[ k ][ 1 ].RD_Q10 < RDmin_Q10 ) { + RDmin_Q10 = psSampleState[ k ][ 1 ].RD_Q10; + RDmin_ind = k; + } + } + + /* Replace a state if best from second set outperforms worst in first set */ + if( RDmin_Q10 < RDmax_Q10 ) { + silk_memcpy( ( (opus_int32 *)&psDelDec[ RDmax_ind ] ) + i, + ( (opus_int32 *)&psDelDec[ RDmin_ind ] ) + i, sizeof( NSQ_del_dec_struct ) - i * sizeof( opus_int32) ); + silk_memcpy( &psSampleState[ RDmax_ind ][ 0 ], &psSampleState[ RDmin_ind ][ 1 ], sizeof( NSQ_sample_struct ) ); + } + + /* Write samples from winner to output and long-term filter states */ + psDD = &psDelDec[ Winner_ind ]; + if( subfr > 0 || i >= decisionDelay ) { + pulses[ i - decisionDelay ] = (opus_int8)silk_RSHIFT_ROUND( psDD->Q_Q10[ last_smple_idx ], 10 ); + xq[ i - decisionDelay ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( + silk_SMULWW( psDD->Xq_Q14[ last_smple_idx ], delayedGain_Q10[ last_smple_idx ] ), 8 ) ); + NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - decisionDelay ] = psDD->Shape_Q14[ last_smple_idx ]; + sLTP_Q15[ NSQ->sLTP_buf_idx - decisionDelay ] = psDD->Pred_Q15[ last_smple_idx ]; + } + NSQ->sLTP_shp_buf_idx++; + NSQ->sLTP_buf_idx++; + + /* Update states */ + for( k = 0; k < nStatesDelayedDecision; k++ ) { + psDD = &psDelDec[ k ]; + psSS = &psSampleState[ k ][ 0 ]; + psDD->LF_AR_Q14 = psSS->LF_AR_Q14; + psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH + i ] = psSS->xq_Q14; + psDD->Xq_Q14[ *smpl_buf_idx ] = psSS->xq_Q14; + psDD->Q_Q10[ *smpl_buf_idx ] = psSS->Q_Q10; + psDD->Pred_Q15[ *smpl_buf_idx ] = silk_LSHIFT32( psSS->LPC_exc_Q14, 1 ); + psDD->Shape_Q14[ *smpl_buf_idx ] = psSS->sLTP_shp_Q14; + psDD->Seed = silk_ADD32_ovflw( psDD->Seed, silk_RSHIFT_ROUND( psSS->Q_Q10, 10 ) ); + psDD->RandState[ *smpl_buf_idx ] = psDD->Seed; + psDD->RD_Q10 = psSS->RD_Q10; + } + delayedGain_Q10[ *smpl_buf_idx ] = Gain_Q10; + } + /* Update LPC states */ + for( k = 0; k < nStatesDelayedDecision; k++ ) { + psDD = &psDelDec[ k ]; + silk_memcpy( psDD->sLPC_Q14, &psDD->sLPC_Q14[ length ], NSQ_LPC_BUF_LENGTH * sizeof( opus_int32 ) ); + } + RESTORE_STACK; +} + +static OPUS_INLINE void silk_nsq_del_dec_scale_states( + const silk_encoder_state *psEncC, /* I Encoder State */ + silk_nsq_state *NSQ, /* I/O NSQ state */ + NSQ_del_dec_struct psDelDec[], /* I/O Delayed decision states */ + const opus_int32 x_Q3[], /* I Input in Q3 */ + opus_int32 x_sc_Q10[], /* O Input scaled with 1/Gain in Q10 */ + const opus_int16 sLTP[], /* I Re-whitened LTP state in Q0 */ + opus_int32 sLTP_Q15[], /* O LTP state matching scaled input */ + opus_int subfr, /* I Subframe number */ + opus_int nStatesDelayedDecision, /* I Number of del dec states */ + const opus_int LTP_scale_Q14, /* I LTP state scaling */ + const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I */ + const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag */ + const opus_int signal_type, /* I Signal type */ + const opus_int decisionDelay /* I Decision delay */ +) +{ + opus_int i, k, lag; + opus_int32 gain_adj_Q16, inv_gain_Q31, inv_gain_Q23; + NSQ_del_dec_struct *psDD; + + lag = pitchL[ subfr ]; + inv_gain_Q31 = silk_INVERSE32_varQ( silk_max( Gains_Q16[ subfr ], 1 ), 47 ); + silk_assert( inv_gain_Q31 != 0 ); + + /* Calculate gain adjustment factor */ + if( Gains_Q16[ subfr ] != NSQ->prev_gain_Q16 ) { + gain_adj_Q16 = silk_DIV32_varQ( NSQ->prev_gain_Q16, Gains_Q16[ subfr ], 16 ); + } else { + gain_adj_Q16 = (opus_int32)1 << 16; + } + + /* Scale input */ + inv_gain_Q23 = silk_RSHIFT_ROUND( inv_gain_Q31, 8 ); + for( i = 0; i < psEncC->subfr_length; i++ ) { + x_sc_Q10[ i ] = silk_SMULWW( x_Q3[ i ], inv_gain_Q23 ); + } + + /* Save inverse gain */ + NSQ->prev_gain_Q16 = Gains_Q16[ subfr ]; + + /* After rewhitening the LTP state is un-scaled, so scale with inv_gain_Q16 */ + if( NSQ->rewhite_flag ) { + if( subfr == 0 ) { + /* Do LTP downscaling */ + inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, LTP_scale_Q14 ), 2 ); + } + for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx; i++ ) { + silk_assert( i < MAX_FRAME_LENGTH ); + sLTP_Q15[ i ] = silk_SMULWB( inv_gain_Q31, sLTP[ i ] ); + } + } + + /* Adjust for changing gain */ + if( gain_adj_Q16 != (opus_int32)1 << 16 ) { + /* Scale long-term shaping state */ + for( i = NSQ->sLTP_shp_buf_idx - psEncC->ltp_mem_length; i < NSQ->sLTP_shp_buf_idx; i++ ) { + NSQ->sLTP_shp_Q14[ i ] = silk_SMULWW( gain_adj_Q16, NSQ->sLTP_shp_Q14[ i ] ); + } + + /* Scale long-term prediction state */ + if( signal_type == TYPE_VOICED && NSQ->rewhite_flag == 0 ) { + for( i = NSQ->sLTP_buf_idx - lag - LTP_ORDER / 2; i < NSQ->sLTP_buf_idx - decisionDelay; i++ ) { + sLTP_Q15[ i ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ i ] ); + } + } + + for( k = 0; k < nStatesDelayedDecision; k++ ) { + psDD = &psDelDec[ k ]; + + /* Scale scalar states */ + psDD->LF_AR_Q14 = silk_SMULWW( gain_adj_Q16, psDD->LF_AR_Q14 ); + + /* Scale short-term prediction and shaping states */ + for( i = 0; i < NSQ_LPC_BUF_LENGTH; i++ ) { + psDD->sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->sLPC_Q14[ i ] ); + } + for( i = 0; i < MAX_SHAPE_LPC_ORDER; i++ ) { + psDD->sAR2_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->sAR2_Q14[ i ] ); + } + for( i = 0; i < DECISION_DELAY; i++ ) { + psDD->Pred_Q15[ i ] = silk_SMULWW( gain_adj_Q16, psDD->Pred_Q15[ i ] ); + psDD->Shape_Q14[ i ] = silk_SMULWW( gain_adj_Q16, psDD->Shape_Q14[ i ] ); + } + } + } +} diff --git a/src/opus-1.1/silk/PLC.c b/src/opus-1.1/silk/PLC.c new file mode 100644 index 00000000..01f40014 --- /dev/null +++ b/src/opus-1.1/silk/PLC.c @@ -0,0 +1,423 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main.h" +#include "stack_alloc.h" +#include "PLC.h" + +#define NB_ATT 2 +static const opus_int16 HARM_ATT_Q15[NB_ATT] = { 32440, 31130 }; /* 0.99, 0.95 */ +static const opus_int16 PLC_RAND_ATTENUATE_V_Q15[NB_ATT] = { 31130, 26214 }; /* 0.95, 0.8 */ +static const opus_int16 PLC_RAND_ATTENUATE_UV_Q15[NB_ATT] = { 32440, 29491 }; /* 0.99, 0.9 */ + +static OPUS_INLINE void silk_PLC_update( + silk_decoder_state *psDec, /* I/O Decoder state */ + silk_decoder_control *psDecCtrl /* I/O Decoder control */ +); + +static OPUS_INLINE void silk_PLC_conceal( + silk_decoder_state *psDec, /* I/O Decoder state */ + silk_decoder_control *psDecCtrl, /* I/O Decoder control */ + opus_int16 frame[] /* O LPC residual signal */ +); + + +void silk_PLC_Reset( + silk_decoder_state *psDec /* I/O Decoder state */ +) +{ + psDec->sPLC.pitchL_Q8 = silk_LSHIFT( psDec->frame_length, 8 - 1 ); + psDec->sPLC.prevGain_Q16[ 0 ] = SILK_FIX_CONST( 1, 16 ); + psDec->sPLC.prevGain_Q16[ 1 ] = SILK_FIX_CONST( 1, 16 ); + psDec->sPLC.subfr_length = 20; + psDec->sPLC.nb_subfr = 2; +} + +void silk_PLC( + silk_decoder_state *psDec, /* I/O Decoder state */ + silk_decoder_control *psDecCtrl, /* I/O Decoder control */ + opus_int16 frame[], /* I/O signal */ + opus_int lost /* I Loss flag */ +) +{ + /* PLC control function */ + if( psDec->fs_kHz != psDec->sPLC.fs_kHz ) { + silk_PLC_Reset( psDec ); + psDec->sPLC.fs_kHz = psDec->fs_kHz; + } + + if( lost ) { + /****************************/ + /* Generate Signal */ + /****************************/ + silk_PLC_conceal( psDec, psDecCtrl, frame ); + + psDec->lossCnt++; + } else { + /****************************/ + /* Update state */ + /****************************/ + silk_PLC_update( psDec, psDecCtrl ); + } +} + +/**************************************************/ +/* Update state of PLC */ +/**************************************************/ +static OPUS_INLINE void silk_PLC_update( + silk_decoder_state *psDec, /* I/O Decoder state */ + silk_decoder_control *psDecCtrl /* I/O Decoder control */ +) +{ + opus_int32 LTP_Gain_Q14, temp_LTP_Gain_Q14; + opus_int i, j; + silk_PLC_struct *psPLC; + + psPLC = &psDec->sPLC; + + /* Update parameters used in case of packet loss */ + psDec->prevSignalType = psDec->indices.signalType; + LTP_Gain_Q14 = 0; + if( psDec->indices.signalType == TYPE_VOICED ) { + /* Find the parameters for the last subframe which contains a pitch pulse */ + for( j = 0; j * psDec->subfr_length < psDecCtrl->pitchL[ psDec->nb_subfr - 1 ]; j++ ) { + if( j == psDec->nb_subfr ) { + break; + } + temp_LTP_Gain_Q14 = 0; + for( i = 0; i < LTP_ORDER; i++ ) { + temp_LTP_Gain_Q14 += psDecCtrl->LTPCoef_Q14[ ( psDec->nb_subfr - 1 - j ) * LTP_ORDER + i ]; + } + if( temp_LTP_Gain_Q14 > LTP_Gain_Q14 ) { + LTP_Gain_Q14 = temp_LTP_Gain_Q14; + silk_memcpy( psPLC->LTPCoef_Q14, + &psDecCtrl->LTPCoef_Q14[ silk_SMULBB( psDec->nb_subfr - 1 - j, LTP_ORDER ) ], + LTP_ORDER * sizeof( opus_int16 ) ); + + psPLC->pitchL_Q8 = silk_LSHIFT( psDecCtrl->pitchL[ psDec->nb_subfr - 1 - j ], 8 ); + } + } + + silk_memset( psPLC->LTPCoef_Q14, 0, LTP_ORDER * sizeof( opus_int16 ) ); + psPLC->LTPCoef_Q14[ LTP_ORDER / 2 ] = LTP_Gain_Q14; + + /* Limit LT coefs */ + if( LTP_Gain_Q14 < V_PITCH_GAIN_START_MIN_Q14 ) { + opus_int scale_Q10; + opus_int32 tmp; + + tmp = silk_LSHIFT( V_PITCH_GAIN_START_MIN_Q14, 10 ); + scale_Q10 = silk_DIV32( tmp, silk_max( LTP_Gain_Q14, 1 ) ); + for( i = 0; i < LTP_ORDER; i++ ) { + psPLC->LTPCoef_Q14[ i ] = silk_RSHIFT( silk_SMULBB( psPLC->LTPCoef_Q14[ i ], scale_Q10 ), 10 ); + } + } else if( LTP_Gain_Q14 > V_PITCH_GAIN_START_MAX_Q14 ) { + opus_int scale_Q14; + opus_int32 tmp; + + tmp = silk_LSHIFT( V_PITCH_GAIN_START_MAX_Q14, 14 ); + scale_Q14 = silk_DIV32( tmp, silk_max( LTP_Gain_Q14, 1 ) ); + for( i = 0; i < LTP_ORDER; i++ ) { + psPLC->LTPCoef_Q14[ i ] = silk_RSHIFT( silk_SMULBB( psPLC->LTPCoef_Q14[ i ], scale_Q14 ), 14 ); + } + } + } else { + psPLC->pitchL_Q8 = silk_LSHIFT( silk_SMULBB( psDec->fs_kHz, 18 ), 8 ); + silk_memset( psPLC->LTPCoef_Q14, 0, LTP_ORDER * sizeof( opus_int16 )); + } + + /* Save LPC coeficients */ + silk_memcpy( psPLC->prevLPC_Q12, psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order * sizeof( opus_int16 ) ); + psPLC->prevLTP_scale_Q14 = psDecCtrl->LTP_scale_Q14; + + /* Save last two gains */ + silk_memcpy( psPLC->prevGain_Q16, &psDecCtrl->Gains_Q16[ psDec->nb_subfr - 2 ], 2 * sizeof( opus_int32 ) ); + + psPLC->subfr_length = psDec->subfr_length; + psPLC->nb_subfr = psDec->nb_subfr; +} + +static OPUS_INLINE void silk_PLC_conceal( + silk_decoder_state *psDec, /* I/O Decoder state */ + silk_decoder_control *psDecCtrl, /* I/O Decoder control */ + opus_int16 frame[] /* O LPC residual signal */ +) +{ + opus_int i, j, k; + opus_int lag, idx, sLTP_buf_idx, shift1, shift2; + opus_int32 rand_seed, harm_Gain_Q15, rand_Gain_Q15, inv_gain_Q30; + opus_int32 energy1, energy2, *rand_ptr, *pred_lag_ptr; + opus_int32 LPC_pred_Q10, LTP_pred_Q12; + opus_int16 rand_scale_Q14; + opus_int16 *B_Q14, *exc_buf_ptr; + opus_int32 *sLPC_Q14_ptr; + VARDECL( opus_int16, exc_buf ); + opus_int16 A_Q12[ MAX_LPC_ORDER ]; + VARDECL( opus_int16, sLTP ); + VARDECL( opus_int32, sLTP_Q14 ); + silk_PLC_struct *psPLC = &psDec->sPLC; + opus_int32 prevGain_Q10[2]; + SAVE_STACK; + + ALLOC( exc_buf, 2*psPLC->subfr_length, opus_int16 ); + ALLOC( sLTP, psDec->ltp_mem_length, opus_int16 ); + ALLOC( sLTP_Q14, psDec->ltp_mem_length + psDec->frame_length, opus_int32 ); + + prevGain_Q10[0] = silk_RSHIFT( psPLC->prevGain_Q16[ 0 ], 6); + prevGain_Q10[1] = silk_RSHIFT( psPLC->prevGain_Q16[ 1 ], 6); + + if( psDec->first_frame_after_reset ) { + silk_memset( psPLC->prevLPC_Q12, 0, sizeof( psPLC->prevLPC_Q12 ) ); + } + + /* Find random noise component */ + /* Scale previous excitation signal */ + exc_buf_ptr = exc_buf; + for( k = 0; k < 2; k++ ) { + for( i = 0; i < psPLC->subfr_length; i++ ) { + exc_buf_ptr[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT( + silk_SMULWW( psDec->exc_Q14[ i + ( k + psPLC->nb_subfr - 2 ) * psPLC->subfr_length ], prevGain_Q10[ k ] ), 8 ) ); + } + exc_buf_ptr += psPLC->subfr_length; + } + /* Find the subframe with lowest energy of the last two and use that as random noise generator */ + silk_sum_sqr_shift( &energy1, &shift1, exc_buf, psPLC->subfr_length ); + silk_sum_sqr_shift( &energy2, &shift2, &exc_buf[ psPLC->subfr_length ], psPLC->subfr_length ); + + if( silk_RSHIFT( energy1, shift2 ) < silk_RSHIFT( energy2, shift1 ) ) { + /* First sub-frame has lowest energy */ + rand_ptr = &psDec->exc_Q14[ silk_max_int( 0, ( psPLC->nb_subfr - 1 ) * psPLC->subfr_length - RAND_BUF_SIZE ) ]; + } else { + /* Second sub-frame has lowest energy */ + rand_ptr = &psDec->exc_Q14[ silk_max_int( 0, psPLC->nb_subfr * psPLC->subfr_length - RAND_BUF_SIZE ) ]; + } + + /* Set up Gain to random noise component */ + B_Q14 = psPLC->LTPCoef_Q14; + rand_scale_Q14 = psPLC->randScale_Q14; + + /* Set up attenuation gains */ + harm_Gain_Q15 = HARM_ATT_Q15[ silk_min_int( NB_ATT - 1, psDec->lossCnt ) ]; + if( psDec->prevSignalType == TYPE_VOICED ) { + rand_Gain_Q15 = PLC_RAND_ATTENUATE_V_Q15[ silk_min_int( NB_ATT - 1, psDec->lossCnt ) ]; + } else { + rand_Gain_Q15 = PLC_RAND_ATTENUATE_UV_Q15[ silk_min_int( NB_ATT - 1, psDec->lossCnt ) ]; + } + + /* LPC concealment. Apply BWE to previous LPC */ + silk_bwexpander( psPLC->prevLPC_Q12, psDec->LPC_order, SILK_FIX_CONST( BWE_COEF, 16 ) ); + + /* Preload LPC coeficients to array on stack. Gives small performance gain */ + silk_memcpy( A_Q12, psPLC->prevLPC_Q12, psDec->LPC_order * sizeof( opus_int16 ) ); + + /* First Lost frame */ + if( psDec->lossCnt == 0 ) { + rand_scale_Q14 = 1 << 14; + + /* Reduce random noise Gain for voiced frames */ + if( psDec->prevSignalType == TYPE_VOICED ) { + for( i = 0; i < LTP_ORDER; i++ ) { + rand_scale_Q14 -= B_Q14[ i ]; + } + rand_scale_Q14 = silk_max_16( 3277, rand_scale_Q14 ); /* 0.2 */ + rand_scale_Q14 = (opus_int16)silk_RSHIFT( silk_SMULBB( rand_scale_Q14, psPLC->prevLTP_scale_Q14 ), 14 ); + } else { + /* Reduce random noise for unvoiced frames with high LPC gain */ + opus_int32 invGain_Q30, down_scale_Q30; + + invGain_Q30 = silk_LPC_inverse_pred_gain( psPLC->prevLPC_Q12, psDec->LPC_order ); + + down_scale_Q30 = silk_min_32( silk_RSHIFT( (opus_int32)1 << 30, LOG2_INV_LPC_GAIN_HIGH_THRES ), invGain_Q30 ); + down_scale_Q30 = silk_max_32( silk_RSHIFT( (opus_int32)1 << 30, LOG2_INV_LPC_GAIN_LOW_THRES ), down_scale_Q30 ); + down_scale_Q30 = silk_LSHIFT( down_scale_Q30, LOG2_INV_LPC_GAIN_HIGH_THRES ); + + rand_Gain_Q15 = silk_RSHIFT( silk_SMULWB( down_scale_Q30, rand_Gain_Q15 ), 14 ); + } + } + + rand_seed = psPLC->rand_seed; + lag = silk_RSHIFT_ROUND( psPLC->pitchL_Q8, 8 ); + sLTP_buf_idx = psDec->ltp_mem_length; + + /* Rewhiten LTP state */ + idx = psDec->ltp_mem_length - lag - psDec->LPC_order - LTP_ORDER / 2; + silk_assert( idx > 0 ); + silk_LPC_analysis_filter( &sLTP[ idx ], &psDec->outBuf[ idx ], A_Q12, psDec->ltp_mem_length - idx, psDec->LPC_order ); + /* Scale LTP state */ + inv_gain_Q30 = silk_INVERSE32_varQ( psPLC->prevGain_Q16[ 1 ], 46 ); + inv_gain_Q30 = silk_min( inv_gain_Q30, silk_int32_MAX >> 1 ); + for( i = idx + psDec->LPC_order; i < psDec->ltp_mem_length; i++ ) { + sLTP_Q14[ i ] = silk_SMULWB( inv_gain_Q30, sLTP[ i ] ); + } + + /***************************/ + /* LTP synthesis filtering */ + /***************************/ + for( k = 0; k < psDec->nb_subfr; k++ ) { + /* Set up pointer */ + pred_lag_ptr = &sLTP_Q14[ sLTP_buf_idx - lag + LTP_ORDER / 2 ]; + for( i = 0; i < psDec->subfr_length; i++ ) { + /* Unrolled loop */ + /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ + LTP_pred_Q12 = 2; + LTP_pred_Q12 = silk_SMLAWB( LTP_pred_Q12, pred_lag_ptr[ 0 ], B_Q14[ 0 ] ); + LTP_pred_Q12 = silk_SMLAWB( LTP_pred_Q12, pred_lag_ptr[ -1 ], B_Q14[ 1 ] ); + LTP_pred_Q12 = silk_SMLAWB( LTP_pred_Q12, pred_lag_ptr[ -2 ], B_Q14[ 2 ] ); + LTP_pred_Q12 = silk_SMLAWB( LTP_pred_Q12, pred_lag_ptr[ -3 ], B_Q14[ 3 ] ); + LTP_pred_Q12 = silk_SMLAWB( LTP_pred_Q12, pred_lag_ptr[ -4 ], B_Q14[ 4 ] ); + pred_lag_ptr++; + + /* Generate LPC excitation */ + rand_seed = silk_RAND( rand_seed ); + idx = silk_RSHIFT( rand_seed, 25 ) & RAND_BUF_MASK; + sLTP_Q14[ sLTP_buf_idx ] = silk_LSHIFT32( silk_SMLAWB( LTP_pred_Q12, rand_ptr[ idx ], rand_scale_Q14 ), 2 ); + sLTP_buf_idx++; + } + + /* Gradually reduce LTP gain */ + for( j = 0; j < LTP_ORDER; j++ ) { + B_Q14[ j ] = silk_RSHIFT( silk_SMULBB( harm_Gain_Q15, B_Q14[ j ] ), 15 ); + } + /* Gradually reduce excitation gain */ + rand_scale_Q14 = silk_RSHIFT( silk_SMULBB( rand_scale_Q14, rand_Gain_Q15 ), 15 ); + + /* Slowly increase pitch lag */ + psPLC->pitchL_Q8 = silk_SMLAWB( psPLC->pitchL_Q8, psPLC->pitchL_Q8, PITCH_DRIFT_FAC_Q16 ); + psPLC->pitchL_Q8 = silk_min_32( psPLC->pitchL_Q8, silk_LSHIFT( silk_SMULBB( MAX_PITCH_LAG_MS, psDec->fs_kHz ), 8 ) ); + lag = silk_RSHIFT_ROUND( psPLC->pitchL_Q8, 8 ); + } + + /***************************/ + /* LPC synthesis filtering */ + /***************************/ + sLPC_Q14_ptr = &sLTP_Q14[ psDec->ltp_mem_length - MAX_LPC_ORDER ]; + + /* Copy LPC state */ + silk_memcpy( sLPC_Q14_ptr, psDec->sLPC_Q14_buf, MAX_LPC_ORDER * sizeof( opus_int32 ) ); + + silk_assert( psDec->LPC_order >= 10 ); /* check that unrolling works */ + for( i = 0; i < psDec->frame_length; i++ ) { + /* partly unrolled */ + /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ + LPC_pred_Q10 = silk_RSHIFT( psDec->LPC_order, 1 ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 1 ], A_Q12[ 0 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 2 ], A_Q12[ 1 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 3 ], A_Q12[ 2 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 4 ], A_Q12[ 3 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 5 ], A_Q12[ 4 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 6 ], A_Q12[ 5 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 7 ], A_Q12[ 6 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 8 ], A_Q12[ 7 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 9 ], A_Q12[ 8 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - 10 ], A_Q12[ 9 ] ); + for( j = 10; j < psDec->LPC_order; j++ ) { + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14_ptr[ MAX_LPC_ORDER + i - j - 1 ], A_Q12[ j ] ); + } + + /* Add prediction to LPC excitation */ + sLPC_Q14_ptr[ MAX_LPC_ORDER + i ] = silk_ADD_LSHIFT32( sLPC_Q14_ptr[ MAX_LPC_ORDER + i ], LPC_pred_Q10, 4 ); + + /* Scale with Gain */ + frame[ i ] = (opus_int16)silk_SAT16( silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( sLPC_Q14_ptr[ MAX_LPC_ORDER + i ], prevGain_Q10[ 1 ] ), 8 ) ) ); + } + + /* Save LPC state */ + silk_memcpy( psDec->sLPC_Q14_buf, &sLPC_Q14_ptr[ psDec->frame_length ], MAX_LPC_ORDER * sizeof( opus_int32 ) ); + + /**************************************/ + /* Update states */ + /**************************************/ + psPLC->rand_seed = rand_seed; + psPLC->randScale_Q14 = rand_scale_Q14; + for( i = 0; i < MAX_NB_SUBFR; i++ ) { + psDecCtrl->pitchL[ i ] = lag; + } + RESTORE_STACK; +} + +/* Glues concealed frames with new good received frames */ +void silk_PLC_glue_frames( + silk_decoder_state *psDec, /* I/O decoder state */ + opus_int16 frame[], /* I/O signal */ + opus_int length /* I length of signal */ +) +{ + opus_int i, energy_shift; + opus_int32 energy; + silk_PLC_struct *psPLC; + psPLC = &psDec->sPLC; + + if( psDec->lossCnt ) { + /* Calculate energy in concealed residual */ + silk_sum_sqr_shift( &psPLC->conc_energy, &psPLC->conc_energy_shift, frame, length ); + + psPLC->last_frame_lost = 1; + } else { + if( psDec->sPLC.last_frame_lost ) { + /* Calculate residual in decoded signal if last frame was lost */ + silk_sum_sqr_shift( &energy, &energy_shift, frame, length ); + + /* Normalize energies */ + if( energy_shift > psPLC->conc_energy_shift ) { + psPLC->conc_energy = silk_RSHIFT( psPLC->conc_energy, energy_shift - psPLC->conc_energy_shift ); + } else if( energy_shift < psPLC->conc_energy_shift ) { + energy = silk_RSHIFT( energy, psPLC->conc_energy_shift - energy_shift ); + } + + /* Fade in the energy difference */ + if( energy > psPLC->conc_energy ) { + opus_int32 frac_Q24, LZ; + opus_int32 gain_Q16, slope_Q16; + + LZ = silk_CLZ32( psPLC->conc_energy ); + LZ = LZ - 1; + psPLC->conc_energy = silk_LSHIFT( psPLC->conc_energy, LZ ); + energy = silk_RSHIFT( energy, silk_max_32( 24 - LZ, 0 ) ); + + frac_Q24 = silk_DIV32( psPLC->conc_energy, silk_max( energy, 1 ) ); + + gain_Q16 = silk_LSHIFT( silk_SQRT_APPROX( frac_Q24 ), 4 ); + slope_Q16 = silk_DIV32_16( ( (opus_int32)1 << 16 ) - gain_Q16, length ); + /* Make slope 4x steeper to avoid missing onsets after DTX */ + slope_Q16 = silk_LSHIFT( slope_Q16, 2 ); + + for( i = 0; i < length; i++ ) { + frame[ i ] = silk_SMULWB( gain_Q16, frame[ i ] ); + gain_Q16 += slope_Q16; + if( gain_Q16 > (opus_int32)1 << 16 ) { + break; + } + } + } + } + psPLC->last_frame_lost = 0; + } +} diff --git a/src/opus-1.1/silk/PLC.h b/src/opus-1.1/silk/PLC.h new file mode 100644 index 00000000..f1e2eccc --- /dev/null +++ b/src/opus-1.1/silk/PLC.h @@ -0,0 +1,61 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifndef SILK_PLC_H +#define SILK_PLC_H + +#include "main.h" + +#define BWE_COEF 0.99 +#define V_PITCH_GAIN_START_MIN_Q14 11469 /* 0.7 in Q14 */ +#define V_PITCH_GAIN_START_MAX_Q14 15565 /* 0.95 in Q14 */ +#define MAX_PITCH_LAG_MS 18 +#define RAND_BUF_SIZE 128 +#define RAND_BUF_MASK ( RAND_BUF_SIZE - 1 ) +#define LOG2_INV_LPC_GAIN_HIGH_THRES 3 /* 2^3 = 8 dB LPC gain */ +#define LOG2_INV_LPC_GAIN_LOW_THRES 8 /* 2^8 = 24 dB LPC gain */ +#define PITCH_DRIFT_FAC_Q16 655 /* 0.01 in Q16 */ + +void silk_PLC_Reset( + silk_decoder_state *psDec /* I/O Decoder state */ +); + +void silk_PLC( + silk_decoder_state *psDec, /* I/O Decoder state */ + silk_decoder_control *psDecCtrl, /* I/O Decoder control */ + opus_int16 frame[], /* I/O signal */ + opus_int lost /* I Loss flag */ +); + +void silk_PLC_glue_frames( + silk_decoder_state *psDec, /* I/O decoder state */ + opus_int16 frame[], /* I/O signal */ + opus_int length /* I length of signal */ +); + +#endif + diff --git a/src/opus-1.1/silk/SigProc_FIX.h b/src/opus-1.1/silk/SigProc_FIX.h new file mode 100644 index 00000000..1b580579 --- /dev/null +++ b/src/opus-1.1/silk/SigProc_FIX.h @@ -0,0 +1,594 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifndef SILK_SIGPROC_FIX_H +#define SILK_SIGPROC_FIX_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/*#define silk_MACRO_COUNT */ /* Used to enable WMOPS counting */ + +#define SILK_MAX_ORDER_LPC 16 /* max order of the LPC analysis in schur() and k2a() */ + +#include /* for memset(), memcpy(), memmove() */ +#include "typedef.h" +#include "resampler_structs.h" +#include "macros.h" + + +/********************************************************************/ +/* SIGNAL PROCESSING FUNCTIONS */ +/********************************************************************/ + +/*! + * Initialize/reset the resampler state for a given pair of input/output sampling rates +*/ +opus_int silk_resampler_init( + silk_resampler_state_struct *S, /* I/O Resampler state */ + opus_int32 Fs_Hz_in, /* I Input sampling rate (Hz) */ + opus_int32 Fs_Hz_out, /* I Output sampling rate (Hz) */ + opus_int forEnc /* I If 1: encoder; if 0: decoder */ +); + +/*! + * Resampler: convert from one sampling rate to another + */ +opus_int silk_resampler( + silk_resampler_state_struct *S, /* I/O Resampler state */ + opus_int16 out[], /* O Output signal */ + const opus_int16 in[], /* I Input signal */ + opus_int32 inLen /* I Number of input samples */ +); + +/*! +* Downsample 2x, mediocre quality +*/ +void silk_resampler_down2( + opus_int32 *S, /* I/O State vector [ 2 ] */ + opus_int16 *out, /* O Output signal [ len ] */ + const opus_int16 *in, /* I Input signal [ floor(len/2) ] */ + opus_int32 inLen /* I Number of input samples */ +); + +/*! + * Downsample by a factor 2/3, low quality +*/ +void silk_resampler_down2_3( + opus_int32 *S, /* I/O State vector [ 6 ] */ + opus_int16 *out, /* O Output signal [ floor(2*inLen/3) ] */ + const opus_int16 *in, /* I Input signal [ inLen ] */ + opus_int32 inLen /* I Number of input samples */ +); + +/*! + * second order ARMA filter; + * slower than biquad() but uses more precise coefficients + * can handle (slowly) varying coefficients + */ +void silk_biquad_alt( + const opus_int16 *in, /* I input signal */ + const opus_int32 *B_Q28, /* I MA coefficients [3] */ + const opus_int32 *A_Q28, /* I AR coefficients [2] */ + opus_int32 *S, /* I/O State vector [2] */ + opus_int16 *out, /* O output signal */ + const opus_int32 len, /* I signal length (must be even) */ + opus_int stride /* I Operate on interleaved signal if > 1 */ +); + +/* Variable order MA prediction error filter. */ +void silk_LPC_analysis_filter( + opus_int16 *out, /* O Output signal */ + const opus_int16 *in, /* I Input signal */ + const opus_int16 *B, /* I MA prediction coefficients, Q12 [order] */ + const opus_int32 len, /* I Signal length */ + const opus_int32 d /* I Filter order */ +); + +/* Chirp (bandwidth expand) LP AR filter */ +void silk_bwexpander( + opus_int16 *ar, /* I/O AR filter to be expanded (without leading 1) */ + const opus_int d, /* I Length of ar */ + opus_int32 chirp_Q16 /* I Chirp factor (typically in the range 0 to 1) */ +); + +/* Chirp (bandwidth expand) LP AR filter */ +void silk_bwexpander_32( + opus_int32 *ar, /* I/O AR filter to be expanded (without leading 1) */ + const opus_int d, /* I Length of ar */ + opus_int32 chirp_Q16 /* I Chirp factor in Q16 */ +); + +/* Compute inverse of LPC prediction gain, and */ +/* test if LPC coefficients are stable (all poles within unit circle) */ +opus_int32 silk_LPC_inverse_pred_gain( /* O Returns inverse prediction gain in energy domain, Q30 */ + const opus_int16 *A_Q12, /* I Prediction coefficients, Q12 [order] */ + const opus_int order /* I Prediction order */ +); + +/* For input in Q24 domain */ +opus_int32 silk_LPC_inverse_pred_gain_Q24( /* O Returns inverse prediction gain in energy domain, Q30 */ + const opus_int32 *A_Q24, /* I Prediction coefficients [order] */ + const opus_int order /* I Prediction order */ +); + +/* Split signal in two decimated bands using first-order allpass filters */ +void silk_ana_filt_bank_1( + const opus_int16 *in, /* I Input signal [N] */ + opus_int32 *S, /* I/O State vector [2] */ + opus_int16 *outL, /* O Low band [N/2] */ + opus_int16 *outH, /* O High band [N/2] */ + const opus_int32 N /* I Number of input samples */ +); + +/********************************************************************/ +/* SCALAR FUNCTIONS */ +/********************************************************************/ + +/* Approximation of 128 * log2() (exact inverse of approx 2^() below) */ +/* Convert input to a log scale */ +opus_int32 silk_lin2log( + const opus_int32 inLin /* I input in linear scale */ +); + +/* Approximation of a sigmoid function */ +opus_int silk_sigm_Q15( + opus_int in_Q5 /* I */ +); + +/* Approximation of 2^() (exact inverse of approx log2() above) */ +/* Convert input to a linear scale */ +opus_int32 silk_log2lin( + const opus_int32 inLog_Q7 /* I input on log scale */ +); + +/* Compute number of bits to right shift the sum of squares of a vector */ +/* of int16s to make it fit in an int32 */ +void silk_sum_sqr_shift( + opus_int32 *energy, /* O Energy of x, after shifting to the right */ + opus_int *shift, /* O Number of bits right shift applied to energy */ + const opus_int16 *x, /* I Input vector */ + opus_int len /* I Length of input vector */ +); + +/* Calculates the reflection coefficients from the correlation sequence */ +/* Faster than schur64(), but much less accurate. */ +/* uses SMLAWB(), requiring armv5E and higher. */ +opus_int32 silk_schur( /* O Returns residual energy */ + opus_int16 *rc_Q15, /* O reflection coefficients [order] Q15 */ + const opus_int32 *c, /* I correlations [order+1] */ + const opus_int32 order /* I prediction order */ +); + +/* Calculates the reflection coefficients from the correlation sequence */ +/* Slower than schur(), but more accurate. */ +/* Uses SMULL(), available on armv4 */ +opus_int32 silk_schur64( /* O returns residual energy */ + opus_int32 rc_Q16[], /* O Reflection coefficients [order] Q16 */ + const opus_int32 c[], /* I Correlations [order+1] */ + opus_int32 order /* I Prediction order */ +); + +/* Step up function, converts reflection coefficients to prediction coefficients */ +void silk_k2a( + opus_int32 *A_Q24, /* O Prediction coefficients [order] Q24 */ + const opus_int16 *rc_Q15, /* I Reflection coefficients [order] Q15 */ + const opus_int32 order /* I Prediction order */ +); + +/* Step up function, converts reflection coefficients to prediction coefficients */ +void silk_k2a_Q16( + opus_int32 *A_Q24, /* O Prediction coefficients [order] Q24 */ + const opus_int32 *rc_Q16, /* I Reflection coefficients [order] Q16 */ + const opus_int32 order /* I Prediction order */ +); + +/* Apply sine window to signal vector. */ +/* Window types: */ +/* 1 -> sine window from 0 to pi/2 */ +/* 2 -> sine window from pi/2 to pi */ +/* every other sample of window is linearly interpolated, for speed */ +void silk_apply_sine_window( + opus_int16 px_win[], /* O Pointer to windowed signal */ + const opus_int16 px[], /* I Pointer to input signal */ + const opus_int win_type, /* I Selects a window type */ + const opus_int length /* I Window length, multiple of 4 */ +); + +/* Compute autocorrelation */ +void silk_autocorr( + opus_int32 *results, /* O Result (length correlationCount) */ + opus_int *scale, /* O Scaling of the correlation vector */ + const opus_int16 *inputData, /* I Input data to correlate */ + const opus_int inputDataSize, /* I Length of input */ + const opus_int correlationCount, /* I Number of correlation taps to compute */ + int arch /* I Run-time architecture */ +); + +void silk_decode_pitch( + opus_int16 lagIndex, /* I */ + opus_int8 contourIndex, /* O */ + opus_int pitch_lags[], /* O 4 pitch values */ + const opus_int Fs_kHz, /* I sampling frequency (kHz) */ + const opus_int nb_subfr /* I number of sub frames */ +); + +opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0 voiced, 1 unvoiced */ + const opus_int16 *frame, /* I Signal of length PE_FRAME_LENGTH_MS*Fs_kHz */ + opus_int *pitch_out, /* O 4 pitch lag values */ + opus_int16 *lagIndex, /* O Lag Index */ + opus_int8 *contourIndex, /* O Pitch contour Index */ + opus_int *LTPCorr_Q15, /* I/O Normalized correlation; input: value from previous frame */ + opus_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */ + const opus_int32 search_thres1_Q16, /* I First stage threshold for lag candidates 0 - 1 */ + const opus_int search_thres2_Q13, /* I Final threshold for lag candidates 0 - 1 */ + const opus_int Fs_kHz, /* I Sample frequency (kHz) */ + const opus_int complexity, /* I Complexity setting, 0-2, where 2 is highest */ + const opus_int nb_subfr, /* I number of 5 ms subframes */ + int arch /* I Run-time architecture */ +); + +/* Compute Normalized Line Spectral Frequencies (NLSFs) from whitening filter coefficients */ +/* If not all roots are found, the a_Q16 coefficients are bandwidth expanded until convergence. */ +void silk_A2NLSF( + opus_int16 *NLSF, /* O Normalized Line Spectral Frequencies in Q15 (0..2^15-1) [d] */ + opus_int32 *a_Q16, /* I/O Monic whitening filter coefficients in Q16 [d] */ + const opus_int d /* I Filter order (must be even) */ +); + +/* compute whitening filter coefficients from normalized line spectral frequencies */ +void silk_NLSF2A( + opus_int16 *a_Q12, /* O monic whitening filter coefficients in Q12, [ d ] */ + const opus_int16 *NLSF, /* I normalized line spectral frequencies in Q15, [ d ] */ + const opus_int d /* I filter order (should be even) */ +); + +void silk_insertion_sort_increasing( + opus_int32 *a, /* I/O Unsorted / Sorted vector */ + opus_int *idx, /* O Index vector for the sorted elements */ + const opus_int L, /* I Vector length */ + const opus_int K /* I Number of correctly sorted positions */ +); + +void silk_insertion_sort_decreasing_int16( + opus_int16 *a, /* I/O Unsorted / Sorted vector */ + opus_int *idx, /* O Index vector for the sorted elements */ + const opus_int L, /* I Vector length */ + const opus_int K /* I Number of correctly sorted positions */ +); + +void silk_insertion_sort_increasing_all_values_int16( + opus_int16 *a, /* I/O Unsorted / Sorted vector */ + const opus_int L /* I Vector length */ +); + +/* NLSF stabilizer, for a single input data vector */ +void silk_NLSF_stabilize( + opus_int16 *NLSF_Q15, /* I/O Unstable/stabilized normalized LSF vector in Q15 [L] */ + const opus_int16 *NDeltaMin_Q15, /* I Min distance vector, NDeltaMin_Q15[L] must be >= 1 [L+1] */ + const opus_int L /* I Number of NLSF parameters in the input vector */ +); + +/* Laroia low complexity NLSF weights */ +void silk_NLSF_VQ_weights_laroia( + opus_int16 *pNLSFW_Q_OUT, /* O Pointer to input vector weights [D] */ + const opus_int16 *pNLSF_Q15, /* I Pointer to input vector [D] */ + const opus_int D /* I Input vector dimension (even) */ +); + +/* Compute reflection coefficients from input signal */ +void silk_burg_modified( + opus_int32 *res_nrg, /* O Residual energy */ + opus_int *res_nrg_Q, /* O Residual energy Q value */ + opus_int32 A_Q16[], /* O Prediction coefficients (length order) */ + const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */ + const opus_int32 minInvGain_Q30, /* I Inverse of max prediction gain */ + const opus_int subfr_length, /* I Input signal subframe length (incl. D preceding samples) */ + const opus_int nb_subfr, /* I Number of subframes stacked in x */ + const opus_int D, /* I Order */ + int arch /* I Run-time architecture */ +); + +/* Copy and multiply a vector by a constant */ +void silk_scale_copy_vector16( + opus_int16 *data_out, + const opus_int16 *data_in, + opus_int32 gain_Q16, /* I Gain in Q16 */ + const opus_int dataSize /* I Length */ +); + +/* Some for the LTP related function requires Q26 to work.*/ +void silk_scale_vector32_Q26_lshift_18( + opus_int32 *data1, /* I/O Q0/Q18 */ + opus_int32 gain_Q26, /* I Q26 */ + opus_int dataSize /* I length */ +); + +/********************************************************************/ +/* INLINE ARM MATH */ +/********************************************************************/ + +/* return sum( inVec1[i] * inVec2[i] ) */ +opus_int32 silk_inner_prod_aligned( + const opus_int16 *const inVec1, /* I input vector 1 */ + const opus_int16 *const inVec2, /* I input vector 2 */ + const opus_int len /* I vector lengths */ +); + +opus_int32 silk_inner_prod_aligned_scale( + const opus_int16 *const inVec1, /* I input vector 1 */ + const opus_int16 *const inVec2, /* I input vector 2 */ + const opus_int scale, /* I number of bits to shift */ + const opus_int len /* I vector lengths */ +); + +opus_int64 silk_inner_prod16_aligned_64( + const opus_int16 *inVec1, /* I input vector 1 */ + const opus_int16 *inVec2, /* I input vector 2 */ + const opus_int len /* I vector lengths */ +); + +/********************************************************************/ +/* MACROS */ +/********************************************************************/ + +/* Rotate a32 right by 'rot' bits. Negative rot values result in rotating + left. Output is 32bit int. + Note: contemporary compilers recognize the C expression below and + compile it into a 'ror' instruction if available. No need for OPUS_INLINE ASM! */ +static OPUS_INLINE opus_int32 silk_ROR32( opus_int32 a32, opus_int rot ) +{ + opus_uint32 x = (opus_uint32) a32; + opus_uint32 r = (opus_uint32) rot; + opus_uint32 m = (opus_uint32) -rot; + if( rot == 0 ) { + return a32; + } else if( rot < 0 ) { + return (opus_int32) ((x << m) | (x >> (32 - m))); + } else { + return (opus_int32) ((x << (32 - r)) | (x >> r)); + } +} + +/* Allocate opus_int16 aligned to 4-byte memory address */ +#if EMBEDDED_ARM +#define silk_DWORD_ALIGN __attribute__((aligned(4))) +#else +#define silk_DWORD_ALIGN +#endif + +/* Useful Macros that can be adjusted to other platforms */ +#define silk_memcpy(dest, src, size) memcpy((dest), (src), (size)) +#define silk_memset(dest, src, size) memset((dest), (src), (size)) +#define silk_memmove(dest, src, size) memmove((dest), (src), (size)) + +/* Fixed point macros */ + +/* (a32 * b32) output have to be 32bit int */ +#define silk_MUL(a32, b32) ((a32) * (b32)) + +/* (a32 * b32) output have to be 32bit uint */ +#define silk_MUL_uint(a32, b32) silk_MUL(a32, b32) + +/* a32 + (b32 * c32) output have to be 32bit int */ +#define silk_MLA(a32, b32, c32) silk_ADD32((a32),((b32) * (c32))) + +/* a32 + (b32 * c32) output have to be 32bit uint */ +#define silk_MLA_uint(a32, b32, c32) silk_MLA(a32, b32, c32) + +/* ((a32 >> 16) * (b32 >> 16)) output have to be 32bit int */ +#define silk_SMULTT(a32, b32) (((a32) >> 16) * ((b32) >> 16)) + +/* a32 + ((a32 >> 16) * (b32 >> 16)) output have to be 32bit int */ +#define silk_SMLATT(a32, b32, c32) silk_ADD32((a32),((b32) >> 16) * ((c32) >> 16)) + +#define silk_SMLALBB(a64, b16, c16) silk_ADD64((a64),(opus_int64)((opus_int32)(b16) * (opus_int32)(c16))) + +/* (a32 * b32) */ +#define silk_SMULL(a32, b32) ((opus_int64)(a32) * /*(opus_int64)*/(b32)) + +/* Adds two signed 32-bit values in a way that can overflow, while not relying on undefined behaviour + (just standard two's complement implementation-specific behaviour) */ +#define silk_ADD32_ovflw(a, b) ((opus_int32)((opus_uint32)(a) + (opus_uint32)(b))) +/* Subtractss two signed 32-bit values in a way that can overflow, while not relying on undefined behaviour + (just standard two's complement implementation-specific behaviour) */ +#define silk_SUB32_ovflw(a, b) ((opus_int32)((opus_uint32)(a) - (opus_uint32)(b))) + +/* Multiply-accumulate macros that allow overflow in the addition (ie, no asserts in debug mode) */ +#define silk_MLA_ovflw(a32, b32, c32) silk_ADD32_ovflw((a32), (opus_uint32)(b32) * (opus_uint32)(c32)) +#define silk_SMLABB_ovflw(a32, b32, c32) (silk_ADD32_ovflw((a32) , ((opus_int32)((opus_int16)(b32))) * (opus_int32)((opus_int16)(c32)))) + +#define silk_DIV32_16(a32, b16) ((opus_int32)((a32) / (b16))) +#define silk_DIV32(a32, b32) ((opus_int32)((a32) / (b32))) + +/* These macros enables checking for overflow in silk_API_Debug.h*/ +#define silk_ADD16(a, b) ((a) + (b)) +#define silk_ADD32(a, b) ((a) + (b)) +#define silk_ADD64(a, b) ((a) + (b)) + +#define silk_SUB16(a, b) ((a) - (b)) +#define silk_SUB32(a, b) ((a) - (b)) +#define silk_SUB64(a, b) ((a) - (b)) + +#define silk_SAT8(a) ((a) > silk_int8_MAX ? silk_int8_MAX : \ + ((a) < silk_int8_MIN ? silk_int8_MIN : (a))) +#define silk_SAT16(a) ((a) > silk_int16_MAX ? silk_int16_MAX : \ + ((a) < silk_int16_MIN ? silk_int16_MIN : (a))) +#define silk_SAT32(a) ((a) > silk_int32_MAX ? silk_int32_MAX : \ + ((a) < silk_int32_MIN ? silk_int32_MIN : (a))) + +#define silk_CHECK_FIT8(a) (a) +#define silk_CHECK_FIT16(a) (a) +#define silk_CHECK_FIT32(a) (a) + +#define silk_ADD_SAT16(a, b) (opus_int16)silk_SAT16( silk_ADD32( (opus_int32)(a), (b) ) ) +#define silk_ADD_SAT64(a, b) ((((a) + (b)) & 0x8000000000000000LL) == 0 ? \ + ((((a) & (b)) & 0x8000000000000000LL) != 0 ? silk_int64_MIN : (a)+(b)) : \ + ((((a) | (b)) & 0x8000000000000000LL) == 0 ? silk_int64_MAX : (a)+(b)) ) + +#define silk_SUB_SAT16(a, b) (opus_int16)silk_SAT16( silk_SUB32( (opus_int32)(a), (b) ) ) +#define silk_SUB_SAT64(a, b) ((((a)-(b)) & 0x8000000000000000LL) == 0 ? \ + (( (a) & ((b)^0x8000000000000000LL) & 0x8000000000000000LL) ? silk_int64_MIN : (a)-(b)) : \ + ((((a)^0x8000000000000000LL) & (b) & 0x8000000000000000LL) ? silk_int64_MAX : (a)-(b)) ) + +/* Saturation for positive input values */ +#define silk_POS_SAT32(a) ((a) > silk_int32_MAX ? silk_int32_MAX : (a)) + +/* Add with saturation for positive input values */ +#define silk_ADD_POS_SAT8(a, b) ((((a)+(b)) & 0x80) ? silk_int8_MAX : ((a)+(b))) +#define silk_ADD_POS_SAT16(a, b) ((((a)+(b)) & 0x8000) ? silk_int16_MAX : ((a)+(b))) +#define silk_ADD_POS_SAT32(a, b) ((((a)+(b)) & 0x80000000) ? silk_int32_MAX : ((a)+(b))) +#define silk_ADD_POS_SAT64(a, b) ((((a)+(b)) & 0x8000000000000000LL) ? silk_int64_MAX : ((a)+(b))) + +#define silk_LSHIFT8(a, shift) ((opus_int8)((opus_uint8)(a)<<(shift))) /* shift >= 0, shift < 8 */ +#define silk_LSHIFT16(a, shift) ((opus_int16)((opus_uint16)(a)<<(shift))) /* shift >= 0, shift < 16 */ +#define silk_LSHIFT32(a, shift) ((opus_int32)((opus_uint32)(a)<<(shift))) /* shift >= 0, shift < 32 */ +#define silk_LSHIFT64(a, shift) ((opus_int64)((opus_uint64)(a)<<(shift))) /* shift >= 0, shift < 64 */ +#define silk_LSHIFT(a, shift) silk_LSHIFT32(a, shift) /* shift >= 0, shift < 32 */ + +#define silk_RSHIFT8(a, shift) ((a)>>(shift)) /* shift >= 0, shift < 8 */ +#define silk_RSHIFT16(a, shift) ((a)>>(shift)) /* shift >= 0, shift < 16 */ +#define silk_RSHIFT32(a, shift) ((a)>>(shift)) /* shift >= 0, shift < 32 */ +#define silk_RSHIFT64(a, shift) ((a)>>(shift)) /* shift >= 0, shift < 64 */ +#define silk_RSHIFT(a, shift) silk_RSHIFT32(a, shift) /* shift >= 0, shift < 32 */ + +/* saturates before shifting */ +#define silk_LSHIFT_SAT32(a, shift) (silk_LSHIFT32( silk_LIMIT( (a), silk_RSHIFT32( silk_int32_MIN, (shift) ), \ + silk_RSHIFT32( silk_int32_MAX, (shift) ) ), (shift) )) + +#define silk_LSHIFT_ovflw(a, shift) ((opus_int32)((opus_uint32)(a) << (shift))) /* shift >= 0, allowed to overflow */ +#define silk_LSHIFT_uint(a, shift) ((a) << (shift)) /* shift >= 0 */ +#define silk_RSHIFT_uint(a, shift) ((a) >> (shift)) /* shift >= 0 */ + +#define silk_ADD_LSHIFT(a, b, shift) ((a) + silk_LSHIFT((b), (shift))) /* shift >= 0 */ +#define silk_ADD_LSHIFT32(a, b, shift) silk_ADD32((a), silk_LSHIFT32((b), (shift))) /* shift >= 0 */ +#define silk_ADD_LSHIFT_uint(a, b, shift) ((a) + silk_LSHIFT_uint((b), (shift))) /* shift >= 0 */ +#define silk_ADD_RSHIFT(a, b, shift) ((a) + silk_RSHIFT((b), (shift))) /* shift >= 0 */ +#define silk_ADD_RSHIFT32(a, b, shift) silk_ADD32((a), silk_RSHIFT32((b), (shift))) /* shift >= 0 */ +#define silk_ADD_RSHIFT_uint(a, b, shift) ((a) + silk_RSHIFT_uint((b), (shift))) /* shift >= 0 */ +#define silk_SUB_LSHIFT32(a, b, shift) silk_SUB32((a), silk_LSHIFT32((b), (shift))) /* shift >= 0 */ +#define silk_SUB_RSHIFT32(a, b, shift) silk_SUB32((a), silk_RSHIFT32((b), (shift))) /* shift >= 0 */ + +/* Requires that shift > 0 */ +#define silk_RSHIFT_ROUND(a, shift) ((shift) == 1 ? ((a) >> 1) + ((a) & 1) : (((a) >> ((shift) - 1)) + 1) >> 1) +#define silk_RSHIFT_ROUND64(a, shift) ((shift) == 1 ? ((a) >> 1) + ((a) & 1) : (((a) >> ((shift) - 1)) + 1) >> 1) + +/* Number of rightshift required to fit the multiplication */ +#define silk_NSHIFT_MUL_32_32(a, b) ( -(31- (32-silk_CLZ32(silk_abs(a)) + (32-silk_CLZ32(silk_abs(b))))) ) +#define silk_NSHIFT_MUL_16_16(a, b) ( -(15- (16-silk_CLZ16(silk_abs(a)) + (16-silk_CLZ16(silk_abs(b))))) ) + + +#define silk_min(a, b) (((a) < (b)) ? (a) : (b)) +#define silk_max(a, b) (((a) > (b)) ? (a) : (b)) + +/* Macro to convert floating-point constants to fixed-point */ +#define SILK_FIX_CONST( C, Q ) ((opus_int32)((C) * ((opus_int64)1 << (Q)) + 0.5)) + +/* silk_min() versions with typecast in the function call */ +static OPUS_INLINE opus_int silk_min_int(opus_int a, opus_int b) +{ + return (((a) < (b)) ? (a) : (b)); +} +static OPUS_INLINE opus_int16 silk_min_16(opus_int16 a, opus_int16 b) +{ + return (((a) < (b)) ? (a) : (b)); +} +static OPUS_INLINE opus_int32 silk_min_32(opus_int32 a, opus_int32 b) +{ + return (((a) < (b)) ? (a) : (b)); +} +static OPUS_INLINE opus_int64 silk_min_64(opus_int64 a, opus_int64 b) +{ + return (((a) < (b)) ? (a) : (b)); +} + +/* silk_min() versions with typecast in the function call */ +static OPUS_INLINE opus_int silk_max_int(opus_int a, opus_int b) +{ + return (((a) > (b)) ? (a) : (b)); +} +static OPUS_INLINE opus_int16 silk_max_16(opus_int16 a, opus_int16 b) +{ + return (((a) > (b)) ? (a) : (b)); +} +static OPUS_INLINE opus_int32 silk_max_32(opus_int32 a, opus_int32 b) +{ + return (((a) > (b)) ? (a) : (b)); +} +static OPUS_INLINE opus_int64 silk_max_64(opus_int64 a, opus_int64 b) +{ + return (((a) > (b)) ? (a) : (b)); +} + +#define silk_LIMIT( a, limit1, limit2) ((limit1) > (limit2) ? ((a) > (limit1) ? (limit1) : ((a) < (limit2) ? (limit2) : (a))) \ + : ((a) > (limit2) ? (limit2) : ((a) < (limit1) ? (limit1) : (a)))) + +#define silk_LIMIT_int silk_LIMIT +#define silk_LIMIT_16 silk_LIMIT +#define silk_LIMIT_32 silk_LIMIT + +#define silk_abs(a) (((a) > 0) ? (a) : -(a)) /* Be careful, silk_abs returns wrong when input equals to silk_intXX_MIN */ +#define silk_abs_int(a) (((a) ^ ((a) >> (8 * sizeof(a) - 1))) - ((a) >> (8 * sizeof(a) - 1))) +#define silk_abs_int32(a) (((a) ^ ((a) >> 31)) - ((a) >> 31)) +#define silk_abs_int64(a) (((a) > 0) ? (a) : -(a)) + +#define silk_sign(a) ((a) > 0 ? 1 : ( (a) < 0 ? -1 : 0 )) + +/* PSEUDO-RANDOM GENERATOR */ +/* Make sure to store the result as the seed for the next call (also in between */ +/* frames), otherwise result won't be random at all. When only using some of the */ +/* bits, take the most significant bits by right-shifting. */ +#define silk_RAND(seed) (silk_MLA_ovflw(907633515, (seed), 196314165)) + +/* Add some multiplication functions that can be easily mapped to ARM. */ + +/* silk_SMMUL: Signed top word multiply. + ARMv6 2 instruction cycles. + ARMv3M+ 3 instruction cycles. use SMULL and ignore LSB registers.(except xM)*/ +/*#define silk_SMMUL(a32, b32) (opus_int32)silk_RSHIFT(silk_SMLAL(silk_SMULWB((a32), (b32)), (a32), silk_RSHIFT_ROUND((b32), 16)), 16)*/ +/* the following seems faster on x86 */ +#define silk_SMMUL(a32, b32) (opus_int32)silk_RSHIFT64(silk_SMULL((a32), (b32)), 32) + +#include "Inlines.h" +#include "MacroCount.h" +#include "MacroDebug.h" + +#ifdef OPUS_ARM_INLINE_ASM +#include "arm/SigProc_FIX_armv4.h" +#endif + +#ifdef OPUS_ARM_INLINE_EDSP +#include "arm/SigProc_FIX_armv5e.h" +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* SILK_SIGPROC_FIX_H */ diff --git a/src/opus-1.1/silk/VAD.c b/src/opus-1.1/silk/VAD.c new file mode 100644 index 00000000..a8090981 --- /dev/null +++ b/src/opus-1.1/silk/VAD.c @@ -0,0 +1,357 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main.h" +#include "stack_alloc.h" + +/* Silk VAD noise level estimation */ +static OPUS_INLINE void silk_VAD_GetNoiseLevels( + const opus_int32 pX[ VAD_N_BANDS ], /* I subband energies */ + silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */ +); + +/**********************************/ +/* Initialization of the Silk VAD */ +/**********************************/ +opus_int silk_VAD_Init( /* O Return value, 0 if success */ + silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */ +) +{ + opus_int b, ret = 0; + + /* reset state memory */ + silk_memset( psSilk_VAD, 0, sizeof( silk_VAD_state ) ); + + /* init noise levels */ + /* Initialize array with approx pink noise levels (psd proportional to inverse of frequency) */ + for( b = 0; b < VAD_N_BANDS; b++ ) { + psSilk_VAD->NoiseLevelBias[ b ] = silk_max_32( silk_DIV32_16( VAD_NOISE_LEVELS_BIAS, b + 1 ), 1 ); + } + + /* Initialize state */ + for( b = 0; b < VAD_N_BANDS; b++ ) { + psSilk_VAD->NL[ b ] = silk_MUL( 100, psSilk_VAD->NoiseLevelBias[ b ] ); + psSilk_VAD->inv_NL[ b ] = silk_DIV32( silk_int32_MAX, psSilk_VAD->NL[ b ] ); + } + psSilk_VAD->counter = 15; + + /* init smoothed energy-to-noise ratio*/ + for( b = 0; b < VAD_N_BANDS; b++ ) { + psSilk_VAD->NrgRatioSmth_Q8[ b ] = 100 * 256; /* 100 * 256 --> 20 dB SNR */ + } + + return( ret ); +} + +/* Weighting factors for tilt measure */ +static const opus_int32 tiltWeights[ VAD_N_BANDS ] = { 30000, 6000, -12000, -12000 }; + +/***************************************/ +/* Get the speech activity level in Q8 */ +/***************************************/ +opus_int silk_VAD_GetSA_Q8( /* O Return value, 0 if success */ + silk_encoder_state *psEncC, /* I/O Encoder state */ + const opus_int16 pIn[] /* I PCM input */ +) +{ + opus_int SA_Q15, pSNR_dB_Q7, input_tilt; + opus_int decimated_framelength1, decimated_framelength2; + opus_int decimated_framelength; + opus_int dec_subframe_length, dec_subframe_offset, SNR_Q7, i, b, s; + opus_int32 sumSquared, smooth_coef_Q16; + opus_int16 HPstateTmp; + VARDECL( opus_int16, X ); + opus_int32 Xnrg[ VAD_N_BANDS ]; + opus_int32 NrgToNoiseRatio_Q8[ VAD_N_BANDS ]; + opus_int32 speech_nrg, x_tmp; + opus_int X_offset[ VAD_N_BANDS ]; + opus_int ret = 0; + silk_VAD_state *psSilk_VAD = &psEncC->sVAD; + SAVE_STACK; + + /* Safety checks */ + silk_assert( VAD_N_BANDS == 4 ); + silk_assert( MAX_FRAME_LENGTH >= psEncC->frame_length ); + silk_assert( psEncC->frame_length <= 512 ); + silk_assert( psEncC->frame_length == 8 * silk_RSHIFT( psEncC->frame_length, 3 ) ); + + /***********************/ + /* Filter and Decimate */ + /***********************/ + decimated_framelength1 = silk_RSHIFT( psEncC->frame_length, 1 ); + decimated_framelength2 = silk_RSHIFT( psEncC->frame_length, 2 ); + decimated_framelength = silk_RSHIFT( psEncC->frame_length, 3 ); + /* Decimate into 4 bands: + 0 L 3L L 3L 5L + - -- - -- -- + 8 8 2 4 4 + + [0-1 kHz| temp. |1-2 kHz| 2-4 kHz | 4-8 kHz | + + They're arranged to allow the minimal ( frame_length / 4 ) extra + scratch space during the downsampling process */ + X_offset[ 0 ] = 0; + X_offset[ 1 ] = decimated_framelength + decimated_framelength2; + X_offset[ 2 ] = X_offset[ 1 ] + decimated_framelength; + X_offset[ 3 ] = X_offset[ 2 ] + decimated_framelength2; + ALLOC( X, X_offset[ 3 ] + decimated_framelength1, opus_int16 ); + + /* 0-8 kHz to 0-4 kHz and 4-8 kHz */ + silk_ana_filt_bank_1( pIn, &psSilk_VAD->AnaState[ 0 ], + X, &X[ X_offset[ 3 ] ], psEncC->frame_length ); + + /* 0-4 kHz to 0-2 kHz and 2-4 kHz */ + silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState1[ 0 ], + X, &X[ X_offset[ 2 ] ], decimated_framelength1 ); + + /* 0-2 kHz to 0-1 kHz and 1-2 kHz */ + silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState2[ 0 ], + X, &X[ X_offset[ 1 ] ], decimated_framelength2 ); + + /*********************************************/ + /* HP filter on lowest band (differentiator) */ + /*********************************************/ + X[ decimated_framelength - 1 ] = silk_RSHIFT( X[ decimated_framelength - 1 ], 1 ); + HPstateTmp = X[ decimated_framelength - 1 ]; + for( i = decimated_framelength - 1; i > 0; i-- ) { + X[ i - 1 ] = silk_RSHIFT( X[ i - 1 ], 1 ); + X[ i ] -= X[ i - 1 ]; + } + X[ 0 ] -= psSilk_VAD->HPstate; + psSilk_VAD->HPstate = HPstateTmp; + + /*************************************/ + /* Calculate the energy in each band */ + /*************************************/ + for( b = 0; b < VAD_N_BANDS; b++ ) { + /* Find the decimated framelength in the non-uniformly divided bands */ + decimated_framelength = silk_RSHIFT( psEncC->frame_length, silk_min_int( VAD_N_BANDS - b, VAD_N_BANDS - 1 ) ); + + /* Split length into subframe lengths */ + dec_subframe_length = silk_RSHIFT( decimated_framelength, VAD_INTERNAL_SUBFRAMES_LOG2 ); + dec_subframe_offset = 0; + + /* Compute energy per sub-frame */ + /* initialize with summed energy of last subframe */ + Xnrg[ b ] = psSilk_VAD->XnrgSubfr[ b ]; + for( s = 0; s < VAD_INTERNAL_SUBFRAMES; s++ ) { + sumSquared = 0; + for( i = 0; i < dec_subframe_length; i++ ) { + /* The energy will be less than dec_subframe_length * ( silk_int16_MIN / 8 ) ^ 2. */ + /* Therefore we can accumulate with no risk of overflow (unless dec_subframe_length > 128) */ + x_tmp = silk_RSHIFT( + X[ X_offset[ b ] + i + dec_subframe_offset ], 3 ); + sumSquared = silk_SMLABB( sumSquared, x_tmp, x_tmp ); + + /* Safety check */ + silk_assert( sumSquared >= 0 ); + } + + /* Add/saturate summed energy of current subframe */ + if( s < VAD_INTERNAL_SUBFRAMES - 1 ) { + Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], sumSquared ); + } else { + /* Look-ahead subframe */ + Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], silk_RSHIFT( sumSquared, 1 ) ); + } + + dec_subframe_offset += dec_subframe_length; + } + psSilk_VAD->XnrgSubfr[ b ] = sumSquared; + } + + /********************/ + /* Noise estimation */ + /********************/ + silk_VAD_GetNoiseLevels( &Xnrg[ 0 ], psSilk_VAD ); + + /***********************************************/ + /* Signal-plus-noise to noise ratio estimation */ + /***********************************************/ + sumSquared = 0; + input_tilt = 0; + for( b = 0; b < VAD_N_BANDS; b++ ) { + speech_nrg = Xnrg[ b ] - psSilk_VAD->NL[ b ]; + if( speech_nrg > 0 ) { + /* Divide, with sufficient resolution */ + if( ( Xnrg[ b ] & 0xFF800000 ) == 0 ) { + NrgToNoiseRatio_Q8[ b ] = silk_DIV32( silk_LSHIFT( Xnrg[ b ], 8 ), psSilk_VAD->NL[ b ] + 1 ); + } else { + NrgToNoiseRatio_Q8[ b ] = silk_DIV32( Xnrg[ b ], silk_RSHIFT( psSilk_VAD->NL[ b ], 8 ) + 1 ); + } + + /* Convert to log domain */ + SNR_Q7 = silk_lin2log( NrgToNoiseRatio_Q8[ b ] ) - 8 * 128; + + /* Sum-of-squares */ + sumSquared = silk_SMLABB( sumSquared, SNR_Q7, SNR_Q7 ); /* Q14 */ + + /* Tilt measure */ + if( speech_nrg < ( (opus_int32)1 << 20 ) ) { + /* Scale down SNR value for small subband speech energies */ + SNR_Q7 = silk_SMULWB( silk_LSHIFT( silk_SQRT_APPROX( speech_nrg ), 6 ), SNR_Q7 ); + } + input_tilt = silk_SMLAWB( input_tilt, tiltWeights[ b ], SNR_Q7 ); + } else { + NrgToNoiseRatio_Q8[ b ] = 256; + } + } + + /* Mean-of-squares */ + sumSquared = silk_DIV32_16( sumSquared, VAD_N_BANDS ); /* Q14 */ + + /* Root-mean-square approximation, scale to dBs, and write to output pointer */ + pSNR_dB_Q7 = (opus_int16)( 3 * silk_SQRT_APPROX( sumSquared ) ); /* Q7 */ + + /*********************************/ + /* Speech Probability Estimation */ + /*********************************/ + SA_Q15 = silk_sigm_Q15( silk_SMULWB( VAD_SNR_FACTOR_Q16, pSNR_dB_Q7 ) - VAD_NEGATIVE_OFFSET_Q5 ); + + /**************************/ + /* Frequency Tilt Measure */ + /**************************/ + psEncC->input_tilt_Q15 = silk_LSHIFT( silk_sigm_Q15( input_tilt ) - 16384, 1 ); + + /**************************************************/ + /* Scale the sigmoid output based on power levels */ + /**************************************************/ + speech_nrg = 0; + for( b = 0; b < VAD_N_BANDS; b++ ) { + /* Accumulate signal-without-noise energies, higher frequency bands have more weight */ + speech_nrg += ( b + 1 ) * silk_RSHIFT( Xnrg[ b ] - psSilk_VAD->NL[ b ], 4 ); + } + + /* Power scaling */ + if( speech_nrg <= 0 ) { + SA_Q15 = silk_RSHIFT( SA_Q15, 1 ); + } else if( speech_nrg < 32768 ) { + if( psEncC->frame_length == 10 * psEncC->fs_kHz ) { + speech_nrg = silk_LSHIFT_SAT32( speech_nrg, 16 ); + } else { + speech_nrg = silk_LSHIFT_SAT32( speech_nrg, 15 ); + } + + /* square-root */ + speech_nrg = silk_SQRT_APPROX( speech_nrg ); + SA_Q15 = silk_SMULWB( 32768 + speech_nrg, SA_Q15 ); + } + + /* Copy the resulting speech activity in Q8 */ + psEncC->speech_activity_Q8 = silk_min_int( silk_RSHIFT( SA_Q15, 7 ), silk_uint8_MAX ); + + /***********************************/ + /* Energy Level and SNR estimation */ + /***********************************/ + /* Smoothing coefficient */ + smooth_coef_Q16 = silk_SMULWB( VAD_SNR_SMOOTH_COEF_Q18, silk_SMULWB( (opus_int32)SA_Q15, SA_Q15 ) ); + + if( psEncC->frame_length == 10 * psEncC->fs_kHz ) { + smooth_coef_Q16 >>= 1; + } + + for( b = 0; b < VAD_N_BANDS; b++ ) { + /* compute smoothed energy-to-noise ratio per band */ + psSilk_VAD->NrgRatioSmth_Q8[ b ] = silk_SMLAWB( psSilk_VAD->NrgRatioSmth_Q8[ b ], + NrgToNoiseRatio_Q8[ b ] - psSilk_VAD->NrgRatioSmth_Q8[ b ], smooth_coef_Q16 ); + + /* signal to noise ratio in dB per band */ + SNR_Q7 = 3 * ( silk_lin2log( psSilk_VAD->NrgRatioSmth_Q8[b] ) - 8 * 128 ); + /* quality = sigmoid( 0.25 * ( SNR_dB - 16 ) ); */ + psEncC->input_quality_bands_Q15[ b ] = silk_sigm_Q15( silk_RSHIFT( SNR_Q7 - 16 * 128, 4 ) ); + } + + RESTORE_STACK; + return( ret ); +} + +/**************************/ +/* Noise level estimation */ +/**************************/ +static OPUS_INLINE void silk_VAD_GetNoiseLevels( + const opus_int32 pX[ VAD_N_BANDS ], /* I subband energies */ + silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */ +) +{ + opus_int k; + opus_int32 nl, nrg, inv_nrg; + opus_int coef, min_coef; + + /* Initially faster smoothing */ + if( psSilk_VAD->counter < 1000 ) { /* 1000 = 20 sec */ + min_coef = silk_DIV32_16( silk_int16_MAX, silk_RSHIFT( psSilk_VAD->counter, 4 ) + 1 ); + } else { + min_coef = 0; + } + + for( k = 0; k < VAD_N_BANDS; k++ ) { + /* Get old noise level estimate for current band */ + nl = psSilk_VAD->NL[ k ]; + silk_assert( nl >= 0 ); + + /* Add bias */ + nrg = silk_ADD_POS_SAT32( pX[ k ], psSilk_VAD->NoiseLevelBias[ k ] ); + silk_assert( nrg > 0 ); + + /* Invert energies */ + inv_nrg = silk_DIV32( silk_int32_MAX, nrg ); + silk_assert( inv_nrg >= 0 ); + + /* Less update when subband energy is high */ + if( nrg > silk_LSHIFT( nl, 3 ) ) { + coef = VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 >> 3; + } else if( nrg < nl ) { + coef = VAD_NOISE_LEVEL_SMOOTH_COEF_Q16; + } else { + coef = silk_SMULWB( silk_SMULWW( inv_nrg, nl ), VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 << 1 ); + } + + /* Initially faster smoothing */ + coef = silk_max_int( coef, min_coef ); + + /* Smooth inverse energies */ + psSilk_VAD->inv_NL[ k ] = silk_SMLAWB( psSilk_VAD->inv_NL[ k ], inv_nrg - psSilk_VAD->inv_NL[ k ], coef ); + silk_assert( psSilk_VAD->inv_NL[ k ] >= 0 ); + + /* Compute noise level by inverting again */ + nl = silk_DIV32( silk_int32_MAX, psSilk_VAD->inv_NL[ k ] ); + silk_assert( nl >= 0 ); + + /* Limit noise levels (guarantee 7 bits of head room) */ + nl = silk_min( nl, 0x00FFFFFF ); + + /* Store as part of state */ + psSilk_VAD->NL[ k ] = nl; + } + + /* Increment frame counter */ + psSilk_VAD->counter++; +} diff --git a/src/opus-1.1/silk/VQ_WMat_EC.c b/src/opus-1.1/silk/VQ_WMat_EC.c new file mode 100644 index 00000000..13d5d34e --- /dev/null +++ b/src/opus-1.1/silk/VQ_WMat_EC.c @@ -0,0 +1,120 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main.h" + +/* Entropy constrained matrix-weighted VQ, hard-coded to 5-element vectors, for a single input data vector */ +void silk_VQ_WMat_EC( + opus_int8 *ind, /* O index of best codebook vector */ + opus_int32 *rate_dist_Q14, /* O best weighted quant error + mu * rate */ + opus_int *gain_Q7, /* O sum of absolute LTP coefficients */ + const opus_int16 *in_Q14, /* I input vector to be quantized */ + const opus_int32 *W_Q18, /* I weighting matrix */ + const opus_int8 *cb_Q7, /* I codebook */ + const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */ + const opus_uint8 *cl_Q5, /* I code length for each codebook vector */ + const opus_int mu_Q9, /* I tradeoff betw. weighted error and rate */ + const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */ + opus_int L /* I number of vectors in codebook */ +) +{ + opus_int k, gain_tmp_Q7; + const opus_int8 *cb_row_Q7; + opus_int16 diff_Q14[ 5 ]; + opus_int32 sum1_Q14, sum2_Q16; + + /* Loop over codebook */ + *rate_dist_Q14 = silk_int32_MAX; + cb_row_Q7 = cb_Q7; + for( k = 0; k < L; k++ ) { + gain_tmp_Q7 = cb_gain_Q7[k]; + + diff_Q14[ 0 ] = in_Q14[ 0 ] - silk_LSHIFT( cb_row_Q7[ 0 ], 7 ); + diff_Q14[ 1 ] = in_Q14[ 1 ] - silk_LSHIFT( cb_row_Q7[ 1 ], 7 ); + diff_Q14[ 2 ] = in_Q14[ 2 ] - silk_LSHIFT( cb_row_Q7[ 2 ], 7 ); + diff_Q14[ 3 ] = in_Q14[ 3 ] - silk_LSHIFT( cb_row_Q7[ 3 ], 7 ); + diff_Q14[ 4 ] = in_Q14[ 4 ] - silk_LSHIFT( cb_row_Q7[ 4 ], 7 ); + + /* Weighted rate */ + sum1_Q14 = silk_SMULBB( mu_Q9, cl_Q5[ k ] ); + + /* Penalty for too large gain */ + sum1_Q14 = silk_ADD_LSHIFT32( sum1_Q14, silk_max( silk_SUB32( gain_tmp_Q7, max_gain_Q7 ), 0 ), 10 ); + + silk_assert( sum1_Q14 >= 0 ); + + /* first row of W_Q18 */ + sum2_Q16 = silk_SMULWB( W_Q18[ 1 ], diff_Q14[ 1 ] ); + sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 2 ], diff_Q14[ 2 ] ); + sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 3 ], diff_Q14[ 3 ] ); + sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 4 ], diff_Q14[ 4 ] ); + sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 ); + sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 0 ], diff_Q14[ 0 ] ); + sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 0 ] ); + + /* second row of W_Q18 */ + sum2_Q16 = silk_SMULWB( W_Q18[ 7 ], diff_Q14[ 2 ] ); + sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 8 ], diff_Q14[ 3 ] ); + sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 9 ], diff_Q14[ 4 ] ); + sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 ); + sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 6 ], diff_Q14[ 1 ] ); + sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 1 ] ); + + /* third row of W_Q18 */ + sum2_Q16 = silk_SMULWB( W_Q18[ 13 ], diff_Q14[ 3 ] ); + sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 14 ], diff_Q14[ 4 ] ); + sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 ); + sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 12 ], diff_Q14[ 2 ] ); + sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 2 ] ); + + /* fourth row of W_Q18 */ + sum2_Q16 = silk_SMULWB( W_Q18[ 19 ], diff_Q14[ 4 ] ); + sum2_Q16 = silk_LSHIFT( sum2_Q16, 1 ); + sum2_Q16 = silk_SMLAWB( sum2_Q16, W_Q18[ 18 ], diff_Q14[ 3 ] ); + sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 3 ] ); + + /* last row of W_Q18 */ + sum2_Q16 = silk_SMULWB( W_Q18[ 24 ], diff_Q14[ 4 ] ); + sum1_Q14 = silk_SMLAWB( sum1_Q14, sum2_Q16, diff_Q14[ 4 ] ); + + silk_assert( sum1_Q14 >= 0 ); + + /* find best */ + if( sum1_Q14 < *rate_dist_Q14 ) { + *rate_dist_Q14 = sum1_Q14; + *ind = (opus_int8)k; + *gain_Q7 = gain_tmp_Q7; + } + + /* Go to next cbk vector */ + cb_row_Q7 += LTP_ORDER; + } +} diff --git a/src/opus-1.1/silk/ana_filt_bank_1.c b/src/opus-1.1/silk/ana_filt_bank_1.c new file mode 100644 index 00000000..24cfb03f --- /dev/null +++ b/src/opus-1.1/silk/ana_filt_bank_1.c @@ -0,0 +1,74 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SigProc_FIX.h" + +/* Coefficients for 2-band filter bank based on first-order allpass filters */ +static opus_int16 A_fb1_20 = 5394 << 1; +static opus_int16 A_fb1_21 = -24290; /* (opus_int16)(20623 << 1) */ + +/* Split signal into two decimated bands using first-order allpass filters */ +void silk_ana_filt_bank_1( + const opus_int16 *in, /* I Input signal [N] */ + opus_int32 *S, /* I/O State vector [2] */ + opus_int16 *outL, /* O Low band [N/2] */ + opus_int16 *outH, /* O High band [N/2] */ + const opus_int32 N /* I Number of input samples */ +) +{ + opus_int k, N2 = silk_RSHIFT( N, 1 ); + opus_int32 in32, X, Y, out_1, out_2; + + /* Internal variables and state are in Q10 format */ + for( k = 0; k < N2; k++ ) { + /* Convert to Q10 */ + in32 = silk_LSHIFT( (opus_int32)in[ 2 * k ], 10 ); + + /* All-pass section for even input sample */ + Y = silk_SUB32( in32, S[ 0 ] ); + X = silk_SMLAWB( Y, Y, A_fb1_21 ); + out_1 = silk_ADD32( S[ 0 ], X ); + S[ 0 ] = silk_ADD32( in32, X ); + + /* Convert to Q10 */ + in32 = silk_LSHIFT( (opus_int32)in[ 2 * k + 1 ], 10 ); + + /* All-pass section for odd input sample, and add to output of previous section */ + Y = silk_SUB32( in32, S[ 1 ] ); + X = silk_SMULWB( Y, A_fb1_20 ); + out_2 = silk_ADD32( S[ 1 ], X ); + S[ 1 ] = silk_ADD32( in32, X ); + + /* Add/subtract, convert back to int16 and store to output */ + outL[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_ADD32( out_2, out_1 ), 11 ) ); + outH[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SUB32( out_2, out_1 ), 11 ) ); + } +} diff --git a/src/opus-1.1/silk/arm/SigProc_FIX_armv4.h b/src/opus-1.1/silk/arm/SigProc_FIX_armv4.h new file mode 100644 index 00000000..ff62b1e5 --- /dev/null +++ b/src/opus-1.1/silk/arm/SigProc_FIX_armv4.h @@ -0,0 +1,47 @@ +/*********************************************************************** +Copyright (C) 2013 Xiph.Org Foundation and contributors +Copyright (c) 2013 Parrot +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifndef SILK_SIGPROC_FIX_ARMv4_H +#define SILK_SIGPROC_FIX_ARMv4_H + +#undef silk_MLA +static OPUS_INLINE opus_int32 silk_MLA_armv4(opus_int32 a, opus_int32 b, + opus_int32 c) +{ + opus_int32 res; + __asm__( + "#silk_MLA\n\t" + "mla %0, %1, %2, %3\n\t" + : "=&r"(res) + : "r"(b), "r"(c), "r"(a) + ); + return res; +} +#define silk_MLA(a, b, c) (silk_MLA_armv4(a, b, c)) + +#endif diff --git a/src/opus-1.1/silk/arm/SigProc_FIX_armv5e.h b/src/opus-1.1/silk/arm/SigProc_FIX_armv5e.h new file mode 100644 index 00000000..617a09ca --- /dev/null +++ b/src/opus-1.1/silk/arm/SigProc_FIX_armv5e.h @@ -0,0 +1,61 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Copyright (c) 2013 Parrot +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifndef SILK_SIGPROC_FIX_ARMv5E_H +#define SILK_SIGPROC_FIX_ARMv5E_H + +#undef silk_SMULTT +static OPUS_INLINE opus_int32 silk_SMULTT_armv5e(opus_int32 a, opus_int32 b) +{ + opus_int32 res; + __asm__( + "#silk_SMULTT\n\t" + "smultt %0, %1, %2\n\t" + : "=r"(res) + : "%r"(a), "r"(b) + ); + return res; +} +#define silk_SMULTT(a, b) (silk_SMULTT_armv5e(a, b)) + +#undef silk_SMLATT +static OPUS_INLINE opus_int32 silk_SMLATT_armv5e(opus_int32 a, opus_int32 b, + opus_int32 c) +{ + opus_int32 res; + __asm__( + "#silk_SMLATT\n\t" + "smlatt %0, %1, %2, %3\n\t" + : "=r"(res) + : "%r"(b), "r"(c), "r"(a) + ); + return res; +} +#define silk_SMLATT(a, b, c) (silk_SMLATT_armv5e(a, b, c)) + +#endif diff --git a/src/opus-1.1/silk/arm/macros_armv4.h b/src/opus-1.1/silk/arm/macros_armv4.h new file mode 100644 index 00000000..3f30e972 --- /dev/null +++ b/src/opus-1.1/silk/arm/macros_armv4.h @@ -0,0 +1,103 @@ +/*********************************************************************** +Copyright (C) 2013 Xiph.Org Foundation and contributors. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifndef SILK_MACROS_ARMv4_H +#define SILK_MACROS_ARMv4_H + +/* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */ +#undef silk_SMULWB +static OPUS_INLINE opus_int32 silk_SMULWB_armv4(opus_int32 a, opus_int16 b) +{ + unsigned rd_lo; + int rd_hi; + __asm__( + "#silk_SMULWB\n\t" + "smull %0, %1, %2, %3\n\t" + : "=&r"(rd_lo), "=&r"(rd_hi) + : "%r"(a), "r"(b<<16) + ); + return rd_hi; +} +#define silk_SMULWB(a, b) (silk_SMULWB_armv4(a, b)) + +/* a32 + (b32 * (opus_int32)((opus_int16)(c32))) >> 16 output have to be 32bit int */ +#undef silk_SMLAWB +#define silk_SMLAWB(a, b, c) ((a) + silk_SMULWB(b, c)) + +/* (a32 * (b32 >> 16)) >> 16 */ +#undef silk_SMULWT +static OPUS_INLINE opus_int32 silk_SMULWT_armv4(opus_int32 a, opus_int32 b) +{ + unsigned rd_lo; + int rd_hi; + __asm__( + "#silk_SMULWT\n\t" + "smull %0, %1, %2, %3\n\t" + : "=&r"(rd_lo), "=&r"(rd_hi) + : "%r"(a), "r"(b&~0xFFFF) + ); + return rd_hi; +} +#define silk_SMULWT(a, b) (silk_SMULWT_armv4(a, b)) + +/* a32 + (b32 * (c32 >> 16)) >> 16 */ +#undef silk_SMLAWT +#define silk_SMLAWT(a, b, c) ((a) + silk_SMULWT(b, c)) + +/* (a32 * b32) >> 16 */ +#undef silk_SMULWW +static OPUS_INLINE opus_int32 silk_SMULWW_armv4(opus_int32 a, opus_int32 b) +{ + unsigned rd_lo; + int rd_hi; + __asm__( + "#silk_SMULWW\n\t" + "smull %0, %1, %2, %3\n\t" + : "=&r"(rd_lo), "=&r"(rd_hi) + : "%r"(a), "r"(b) + ); + return (rd_hi<<16)+(rd_lo>>16); +} +#define silk_SMULWW(a, b) (silk_SMULWW_armv4(a, b)) + +#undef silk_SMLAWW +static OPUS_INLINE opus_int32 silk_SMLAWW_armv4(opus_int32 a, opus_int32 b, + opus_int32 c) +{ + unsigned rd_lo; + int rd_hi; + __asm__( + "#silk_SMLAWW\n\t" + "smull %0, %1, %2, %3\n\t" + : "=&r"(rd_lo), "=&r"(rd_hi) + : "%r"(b), "r"(c) + ); + return a+(rd_hi<<16)+(rd_lo>>16); +} +#define silk_SMLAWW(a, b, c) (silk_SMLAWW_armv4(a, b, c)) + +#endif /* SILK_MACROS_ARMv4_H */ diff --git a/src/opus-1.1/silk/arm/macros_armv5e.h b/src/opus-1.1/silk/arm/macros_armv5e.h new file mode 100644 index 00000000..aad4117e --- /dev/null +++ b/src/opus-1.1/silk/arm/macros_armv5e.h @@ -0,0 +1,213 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Copyright (c) 2013 Parrot +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifndef SILK_MACROS_ARMv5E_H +#define SILK_MACROS_ARMv5E_H + +/* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */ +#undef silk_SMULWB +static OPUS_INLINE opus_int32 silk_SMULWB_armv5e(opus_int32 a, opus_int16 b) +{ + int res; + __asm__( + "#silk_SMULWB\n\t" + "smulwb %0, %1, %2\n\t" + : "=r"(res) + : "r"(a), "r"(b) + ); + return res; +} +#define silk_SMULWB(a, b) (silk_SMULWB_armv5e(a, b)) + +/* a32 + (b32 * (opus_int32)((opus_int16)(c32))) >> 16 output have to be 32bit int */ +#undef silk_SMLAWB +static OPUS_INLINE opus_int32 silk_SMLAWB_armv5e(opus_int32 a, opus_int32 b, + opus_int16 c) +{ + int res; + __asm__( + "#silk_SMLAWB\n\t" + "smlawb %0, %1, %2, %3\n\t" + : "=r"(res) + : "r"(b), "r"(c), "r"(a) + ); + return res; +} +#define silk_SMLAWB(a, b, c) (silk_SMLAWB_armv5e(a, b, c)) + +/* (a32 * (b32 >> 16)) >> 16 */ +#undef silk_SMULWT +static OPUS_INLINE opus_int32 silk_SMULWT_armv5e(opus_int32 a, opus_int32 b) +{ + int res; + __asm__( + "#silk_SMULWT\n\t" + "smulwt %0, %1, %2\n\t" + : "=r"(res) + : "r"(a), "r"(b) + ); + return res; +} +#define silk_SMULWT(a, b) (silk_SMULWT_armv5e(a, b)) + +/* a32 + (b32 * (c32 >> 16)) >> 16 */ +#undef silk_SMLAWT +static OPUS_INLINE opus_int32 silk_SMLAWT_armv5e(opus_int32 a, opus_int32 b, + opus_int32 c) +{ + int res; + __asm__( + "#silk_SMLAWT\n\t" + "smlawt %0, %1, %2, %3\n\t" + : "=r"(res) + : "r"(b), "r"(c), "r"(a) + ); + return res; +} +#define silk_SMLAWT(a, b, c) (silk_SMLAWT_armv5e(a, b, c)) + +/* (opus_int32)((opus_int16)(a3))) * (opus_int32)((opus_int16)(b32)) output have to be 32bit int */ +#undef silk_SMULBB +static OPUS_INLINE opus_int32 silk_SMULBB_armv5e(opus_int32 a, opus_int32 b) +{ + int res; + __asm__( + "#silk_SMULBB\n\t" + "smulbb %0, %1, %2\n\t" + : "=r"(res) + : "%r"(a), "r"(b) + ); + return res; +} +#define silk_SMULBB(a, b) (silk_SMULBB_armv5e(a, b)) + +/* a32 + (opus_int32)((opus_int16)(b32)) * (opus_int32)((opus_int16)(c32)) output have to be 32bit int */ +#undef silk_SMLABB +static OPUS_INLINE opus_int32 silk_SMLABB_armv5e(opus_int32 a, opus_int32 b, + opus_int32 c) +{ + int res; + __asm__( + "#silk_SMLABB\n\t" + "smlabb %0, %1, %2, %3\n\t" + : "=r"(res) + : "%r"(b), "r"(c), "r"(a) + ); + return res; +} +#define silk_SMLABB(a, b, c) (silk_SMLABB_armv5e(a, b, c)) + +/* (opus_int32)((opus_int16)(a32)) * (b32 >> 16) */ +#undef silk_SMULBT +static OPUS_INLINE opus_int32 silk_SMULBT_armv5e(opus_int32 a, opus_int32 b) +{ + int res; + __asm__( + "#silk_SMULBT\n\t" + "smulbt %0, %1, %2\n\t" + : "=r"(res) + : "r"(a), "r"(b) + ); + return res; +} +#define silk_SMULBT(a, b) (silk_SMULBT_armv5e(a, b)) + +/* a32 + (opus_int32)((opus_int16)(b32)) * (c32 >> 16) */ +#undef silk_SMLABT +static OPUS_INLINE opus_int32 silk_SMLABT_armv5e(opus_int32 a, opus_int32 b, + opus_int32 c) +{ + int res; + __asm__( + "#silk_SMLABT\n\t" + "smlabt %0, %1, %2, %3\n\t" + : "=r"(res) + : "r"(b), "r"(c), "r"(a) + ); + return res; +} +#define silk_SMLABT(a, b, c) (silk_SMLABT_armv5e(a, b, c)) + +/* add/subtract with output saturated */ +#undef silk_ADD_SAT32 +static OPUS_INLINE opus_int32 silk_ADD_SAT32_armv5e(opus_int32 a, opus_int32 b) +{ + int res; + __asm__( + "#silk_ADD_SAT32\n\t" + "qadd %0, %1, %2\n\t" + : "=r"(res) + : "%r"(a), "r"(b) + ); + return res; +} +#define silk_ADD_SAT32(a, b) (silk_ADD_SAT32_armv5e(a, b)) + +#undef silk_SUB_SAT32 +static OPUS_INLINE opus_int32 silk_SUB_SAT32_armv5e(opus_int32 a, opus_int32 b) +{ + int res; + __asm__( + "#silk_SUB_SAT32\n\t" + "qsub %0, %1, %2\n\t" + : "=r"(res) + : "r"(a), "r"(b) + ); + return res; +} +#define silk_SUB_SAT32(a, b) (silk_SUB_SAT32_armv5e(a, b)) + +#undef silk_CLZ16 +static OPUS_INLINE opus_int32 silk_CLZ16_armv5(opus_int16 in16) +{ + int res; + __asm__( + "#silk_CLZ16\n\t" + "clz %0, %1;\n" + : "=r"(res) + : "r"(in16<<16|0x8000) + ); + return res; +} +#define silk_CLZ16(in16) (silk_CLZ16_armv5(in16)) + +#undef silk_CLZ32 +static OPUS_INLINE opus_int32 silk_CLZ32_armv5(opus_int32 in32) +{ + int res; + __asm__( + "#silk_CLZ32\n\t" + "clz %0, %1\n\t" + : "=r"(res) + : "r"(in32) + ); + return res; +} +#define silk_CLZ32(in32) (silk_CLZ32_armv5(in32)) + +#endif /* SILK_MACROS_ARMv5E_H */ diff --git a/src/opus-1.1/silk/biquad_alt.c b/src/opus-1.1/silk/biquad_alt.c new file mode 100644 index 00000000..d55f5ee9 --- /dev/null +++ b/src/opus-1.1/silk/biquad_alt.c @@ -0,0 +1,78 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +/* * + * silk_biquad_alt.c * + * * + * Second order ARMA filter * + * Can handle slowly varying filter coefficients * + * */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SigProc_FIX.h" + +/* Second order ARMA filter, alternative implementation */ +void silk_biquad_alt( + const opus_int16 *in, /* I input signal */ + const opus_int32 *B_Q28, /* I MA coefficients [3] */ + const opus_int32 *A_Q28, /* I AR coefficients [2] */ + opus_int32 *S, /* I/O State vector [2] */ + opus_int16 *out, /* O output signal */ + const opus_int32 len, /* I signal length (must be even) */ + opus_int stride /* I Operate on interleaved signal if > 1 */ +) +{ + /* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */ + opus_int k; + opus_int32 inval, A0_U_Q28, A0_L_Q28, A1_U_Q28, A1_L_Q28, out32_Q14; + + /* Negate A_Q28 values and split in two parts */ + A0_L_Q28 = ( -A_Q28[ 0 ] ) & 0x00003FFF; /* lower part */ + A0_U_Q28 = silk_RSHIFT( -A_Q28[ 0 ], 14 ); /* upper part */ + A1_L_Q28 = ( -A_Q28[ 1 ] ) & 0x00003FFF; /* lower part */ + A1_U_Q28 = silk_RSHIFT( -A_Q28[ 1 ], 14 ); /* upper part */ + + for( k = 0; k < len; k++ ) { + /* S[ 0 ], S[ 1 ]: Q12 */ + inval = in[ k * stride ]; + out32_Q14 = silk_LSHIFT( silk_SMLAWB( S[ 0 ], B_Q28[ 0 ], inval ), 2 ); + + S[ 0 ] = S[1] + silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14, A0_L_Q28 ), 14 ); + S[ 0 ] = silk_SMLAWB( S[ 0 ], out32_Q14, A0_U_Q28 ); + S[ 0 ] = silk_SMLAWB( S[ 0 ], B_Q28[ 1 ], inval); + + S[ 1 ] = silk_RSHIFT_ROUND( silk_SMULWB( out32_Q14, A1_L_Q28 ), 14 ); + S[ 1 ] = silk_SMLAWB( S[ 1 ], out32_Q14, A1_U_Q28 ); + S[ 1 ] = silk_SMLAWB( S[ 1 ], B_Q28[ 2 ], inval ); + + /* Scale back to Q0 and saturate */ + out[ k * stride ] = (opus_int16)silk_SAT16( silk_RSHIFT( out32_Q14 + (1<<14) - 1, 14 ) ); + } +} diff --git a/src/opus-1.1/silk/bwexpander.c b/src/opus-1.1/silk/bwexpander.c new file mode 100644 index 00000000..2eb44566 --- /dev/null +++ b/src/opus-1.1/silk/bwexpander.c @@ -0,0 +1,51 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SigProc_FIX.h" + +/* Chirp (bandwidth expand) LP AR filter */ +void silk_bwexpander( + opus_int16 *ar, /* I/O AR filter to be expanded (without leading 1) */ + const opus_int d, /* I Length of ar */ + opus_int32 chirp_Q16 /* I Chirp factor (typically in the range 0 to 1) */ +) +{ + opus_int i; + opus_int32 chirp_minus_one_Q16 = chirp_Q16 - 65536; + + /* NB: Dont use silk_SMULWB, instead of silk_RSHIFT_ROUND( silk_MUL(), 16 ), below. */ + /* Bias in silk_SMULWB can lead to unstable filters */ + for( i = 0; i < d - 1; i++ ) { + ar[ i ] = (opus_int16)silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, ar[ i ] ), 16 ); + chirp_Q16 += silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, chirp_minus_one_Q16 ), 16 ); + } + ar[ d - 1 ] = (opus_int16)silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, ar[ d - 1 ] ), 16 ); +} diff --git a/src/opus-1.1/silk/bwexpander_32.c b/src/opus-1.1/silk/bwexpander_32.c new file mode 100644 index 00000000..d0010f73 --- /dev/null +++ b/src/opus-1.1/silk/bwexpander_32.c @@ -0,0 +1,50 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SigProc_FIX.h" + +/* Chirp (bandwidth expand) LP AR filter */ +void silk_bwexpander_32( + opus_int32 *ar, /* I/O AR filter to be expanded (without leading 1) */ + const opus_int d, /* I Length of ar */ + opus_int32 chirp_Q16 /* I Chirp factor in Q16 */ +) +{ + opus_int i; + opus_int32 chirp_minus_one_Q16 = chirp_Q16 - 65536; + + for( i = 0; i < d - 1; i++ ) { + ar[ i ] = silk_SMULWW( chirp_Q16, ar[ i ] ); + chirp_Q16 += silk_RSHIFT_ROUND( silk_MUL( chirp_Q16, chirp_minus_one_Q16 ), 16 ); + } + ar[ d - 1 ] = silk_SMULWW( chirp_Q16, ar[ d - 1 ] ); +} + diff --git a/src/opus-1.1/silk/check_control_input.c b/src/opus-1.1/silk/check_control_input.c new file mode 100644 index 00000000..b5de9ce4 --- /dev/null +++ b/src/opus-1.1/silk/check_control_input.c @@ -0,0 +1,106 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main.h" +#include "control.h" +#include "errors.h" + +/* Check encoder control struct */ +opus_int check_control_input( + silk_EncControlStruct *encControl /* I Control structure */ +) +{ + silk_assert( encControl != NULL ); + + if( ( ( encControl->API_sampleRate != 8000 ) && + ( encControl->API_sampleRate != 12000 ) && + ( encControl->API_sampleRate != 16000 ) && + ( encControl->API_sampleRate != 24000 ) && + ( encControl->API_sampleRate != 32000 ) && + ( encControl->API_sampleRate != 44100 ) && + ( encControl->API_sampleRate != 48000 ) ) || + ( ( encControl->desiredInternalSampleRate != 8000 ) && + ( encControl->desiredInternalSampleRate != 12000 ) && + ( encControl->desiredInternalSampleRate != 16000 ) ) || + ( ( encControl->maxInternalSampleRate != 8000 ) && + ( encControl->maxInternalSampleRate != 12000 ) && + ( encControl->maxInternalSampleRate != 16000 ) ) || + ( ( encControl->minInternalSampleRate != 8000 ) && + ( encControl->minInternalSampleRate != 12000 ) && + ( encControl->minInternalSampleRate != 16000 ) ) || + ( encControl->minInternalSampleRate > encControl->desiredInternalSampleRate ) || + ( encControl->maxInternalSampleRate < encControl->desiredInternalSampleRate ) || + ( encControl->minInternalSampleRate > encControl->maxInternalSampleRate ) ) { + silk_assert( 0 ); + return SILK_ENC_FS_NOT_SUPPORTED; + } + if( encControl->payloadSize_ms != 10 && + encControl->payloadSize_ms != 20 && + encControl->payloadSize_ms != 40 && + encControl->payloadSize_ms != 60 ) { + silk_assert( 0 ); + return SILK_ENC_PACKET_SIZE_NOT_SUPPORTED; + } + if( encControl->packetLossPercentage < 0 || encControl->packetLossPercentage > 100 ) { + silk_assert( 0 ); + return SILK_ENC_INVALID_LOSS_RATE; + } + if( encControl->useDTX < 0 || encControl->useDTX > 1 ) { + silk_assert( 0 ); + return SILK_ENC_INVALID_DTX_SETTING; + } + if( encControl->useCBR < 0 || encControl->useCBR > 1 ) { + silk_assert( 0 ); + return SILK_ENC_INVALID_CBR_SETTING; + } + if( encControl->useInBandFEC < 0 || encControl->useInBandFEC > 1 ) { + silk_assert( 0 ); + return SILK_ENC_INVALID_INBAND_FEC_SETTING; + } + if( encControl->nChannelsAPI < 1 || encControl->nChannelsAPI > ENCODER_NUM_CHANNELS ) { + silk_assert( 0 ); + return SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR; + } + if( encControl->nChannelsInternal < 1 || encControl->nChannelsInternal > ENCODER_NUM_CHANNELS ) { + silk_assert( 0 ); + return SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR; + } + if( encControl->nChannelsInternal > encControl->nChannelsAPI ) { + silk_assert( 0 ); + return SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR; + } + if( encControl->complexity < 0 || encControl->complexity > 10 ) { + silk_assert( 0 ); + return SILK_ENC_INVALID_COMPLEXITY_SETTING; + } + + return SILK_NO_ERROR; +} diff --git a/src/opus-1.1/silk/code_signs.c b/src/opus-1.1/silk/code_signs.c new file mode 100644 index 00000000..0419ea26 --- /dev/null +++ b/src/opus-1.1/silk/code_signs.c @@ -0,0 +1,115 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main.h" + +/*#define silk_enc_map(a) ((a) > 0 ? 1 : 0)*/ +/*#define silk_dec_map(a) ((a) > 0 ? 1 : -1)*/ +/* shifting avoids if-statement */ +#define silk_enc_map(a) ( silk_RSHIFT( (a), 15 ) + 1 ) +#define silk_dec_map(a) ( silk_LSHIFT( (a), 1 ) - 1 ) + +/* Encodes signs of excitation */ +void silk_encode_signs( + ec_enc *psRangeEnc, /* I/O Compressor data structure */ + const opus_int8 pulses[], /* I pulse signal */ + opus_int length, /* I length of input */ + const opus_int signalType, /* I Signal type */ + const opus_int quantOffsetType, /* I Quantization offset type */ + const opus_int sum_pulses[ MAX_NB_SHELL_BLOCKS ] /* I Sum of absolute pulses per block */ +) +{ + opus_int i, j, p; + opus_uint8 icdf[ 2 ]; + const opus_int8 *q_ptr; + const opus_uint8 *icdf_ptr; + + icdf[ 1 ] = 0; + q_ptr = pulses; + i = silk_SMULBB( 7, silk_ADD_LSHIFT( quantOffsetType, signalType, 1 ) ); + icdf_ptr = &silk_sign_iCDF[ i ]; + length = silk_RSHIFT( length + SHELL_CODEC_FRAME_LENGTH/2, LOG2_SHELL_CODEC_FRAME_LENGTH ); + for( i = 0; i < length; i++ ) { + p = sum_pulses[ i ]; + if( p > 0 ) { + icdf[ 0 ] = icdf_ptr[ silk_min( p & 0x1F, 6 ) ]; + for( j = 0; j < SHELL_CODEC_FRAME_LENGTH; j++ ) { + if( q_ptr[ j ] != 0 ) { + ec_enc_icdf( psRangeEnc, silk_enc_map( q_ptr[ j ]), icdf, 8 ); + } + } + } + q_ptr += SHELL_CODEC_FRAME_LENGTH; + } +} + +/* Decodes signs of excitation */ +void silk_decode_signs( + ec_dec *psRangeDec, /* I/O Compressor data structure */ + opus_int pulses[], /* I/O pulse signal */ + opus_int length, /* I length of input */ + const opus_int signalType, /* I Signal type */ + const opus_int quantOffsetType, /* I Quantization offset type */ + const opus_int sum_pulses[ MAX_NB_SHELL_BLOCKS ] /* I Sum of absolute pulses per block */ +) +{ + opus_int i, j, p; + opus_uint8 icdf[ 2 ]; + opus_int *q_ptr; + const opus_uint8 *icdf_ptr; + + icdf[ 1 ] = 0; + q_ptr = pulses; + i = silk_SMULBB( 7, silk_ADD_LSHIFT( quantOffsetType, signalType, 1 ) ); + icdf_ptr = &silk_sign_iCDF[ i ]; + length = silk_RSHIFT( length + SHELL_CODEC_FRAME_LENGTH/2, LOG2_SHELL_CODEC_FRAME_LENGTH ); + for( i = 0; i < length; i++ ) { + p = sum_pulses[ i ]; + if( p > 0 ) { + icdf[ 0 ] = icdf_ptr[ silk_min( p & 0x1F, 6 ) ]; + for( j = 0; j < SHELL_CODEC_FRAME_LENGTH; j++ ) { + if( q_ptr[ j ] > 0 ) { + /* attach sign */ +#if 0 + /* conditional implementation */ + if( ec_dec_icdf( psRangeDec, icdf, 8 ) == 0 ) { + q_ptr[ j ] = -q_ptr[ j ]; + } +#else + /* implementation with shift, subtraction, multiplication */ + q_ptr[ j ] *= silk_dec_map( ec_dec_icdf( psRangeDec, icdf, 8 ) ); +#endif + } + } + } + q_ptr += SHELL_CODEC_FRAME_LENGTH; + } +} diff --git a/src/opus-1.1/silk/control.h b/src/opus-1.1/silk/control.h new file mode 100644 index 00000000..747e5426 --- /dev/null +++ b/src/opus-1.1/silk/control.h @@ -0,0 +1,142 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifndef SILK_CONTROL_H +#define SILK_CONTROL_H + +#include "typedef.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Decoder API flags */ +#define FLAG_DECODE_NORMAL 0 +#define FLAG_PACKET_LOST 1 +#define FLAG_DECODE_LBRR 2 + +/***********************************************/ +/* Structure for controlling encoder operation */ +/***********************************************/ +typedef struct { + /* I: Number of channels; 1/2 */ + opus_int32 nChannelsAPI; + + /* I: Number of channels; 1/2 */ + opus_int32 nChannelsInternal; + + /* I: Input signal sampling rate in Hertz; 8000/12000/16000/24000/32000/44100/48000 */ + opus_int32 API_sampleRate; + + /* I: Maximum internal sampling rate in Hertz; 8000/12000/16000 */ + opus_int32 maxInternalSampleRate; + + /* I: Minimum internal sampling rate in Hertz; 8000/12000/16000 */ + opus_int32 minInternalSampleRate; + + /* I: Soft request for internal sampling rate in Hertz; 8000/12000/16000 */ + opus_int32 desiredInternalSampleRate; + + /* I: Number of samples per packet in milliseconds; 10/20/40/60 */ + opus_int payloadSize_ms; + + /* I: Bitrate during active speech in bits/second; internally limited */ + opus_int32 bitRate; + + /* I: Uplink packet loss in percent (0-100) */ + opus_int packetLossPercentage; + + /* I: Complexity mode; 0 is lowest, 10 is highest complexity */ + opus_int complexity; + + /* I: Flag to enable in-band Forward Error Correction (FEC); 0/1 */ + opus_int useInBandFEC; + + /* I: Flag to enable discontinuous transmission (DTX); 0/1 */ + opus_int useDTX; + + /* I: Flag to use constant bitrate */ + opus_int useCBR; + + /* I: Maximum number of bits allowed for the frame */ + opus_int maxBits; + + /* I: Causes a smooth downmix to mono */ + opus_int toMono; + + /* I: Opus encoder is allowing us to switch bandwidth */ + opus_int opusCanSwitch; + + /* I: Make frames as independent as possible (but still use LPC) */ + opus_int reducedDependency; + + /* O: Internal sampling rate used, in Hertz; 8000/12000/16000 */ + opus_int32 internalSampleRate; + + /* O: Flag that bandwidth switching is allowed (because low voice activity) */ + opus_int allowBandwidthSwitch; + + /* O: Flag that SILK runs in WB mode without variable LP filter (use for switching between WB/SWB/FB) */ + opus_int inWBmodeWithoutVariableLP; + + /* O: Stereo width */ + opus_int stereoWidth_Q14; + + /* O: Tells the Opus encoder we're ready to switch */ + opus_int switchReady; + +} silk_EncControlStruct; + +/**************************************************************************/ +/* Structure for controlling decoder operation and reading decoder status */ +/**************************************************************************/ +typedef struct { + /* I: Number of channels; 1/2 */ + opus_int32 nChannelsAPI; + + /* I: Number of channels; 1/2 */ + opus_int32 nChannelsInternal; + + /* I: Output signal sampling rate in Hertz; 8000/12000/16000/24000/32000/44100/48000 */ + opus_int32 API_sampleRate; + + /* I: Internal sampling rate used, in Hertz; 8000/12000/16000 */ + opus_int32 internalSampleRate; + + /* I: Number of samples per packet in milliseconds; 10/20/40/60 */ + opus_int payloadSize_ms; + + /* O: Pitch lag of previous frame (0 if unvoiced), measured in samples at 48 kHz */ + opus_int prevPitchLag; +} silk_DecControlStruct; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/opus-1.1/silk/control_SNR.c b/src/opus-1.1/silk/control_SNR.c new file mode 100644 index 00000000..f04e69fc --- /dev/null +++ b/src/opus-1.1/silk/control_SNR.c @@ -0,0 +1,81 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main.h" +#include "tuning_parameters.h" + +/* Control SNR of redidual quantizer */ +opus_int silk_control_SNR( + silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */ + opus_int32 TargetRate_bps /* I Target max bitrate (bps) */ +) +{ + opus_int k, ret = SILK_NO_ERROR; + opus_int32 frac_Q6; + const opus_int32 *rateTable; + + /* Set bitrate/coding quality */ + TargetRate_bps = silk_LIMIT( TargetRate_bps, MIN_TARGET_RATE_BPS, MAX_TARGET_RATE_BPS ); + if( TargetRate_bps != psEncC->TargetRate_bps ) { + psEncC->TargetRate_bps = TargetRate_bps; + + /* If new TargetRate_bps, translate to SNR_dB value */ + if( psEncC->fs_kHz == 8 ) { + rateTable = silk_TargetRate_table_NB; + } else if( psEncC->fs_kHz == 12 ) { + rateTable = silk_TargetRate_table_MB; + } else { + rateTable = silk_TargetRate_table_WB; + } + + /* Reduce bitrate for 10 ms modes in these calculations */ + if( psEncC->nb_subfr == 2 ) { + TargetRate_bps -= REDUCE_BITRATE_10_MS_BPS; + } + + /* Find bitrate interval in table and interpolate */ + for( k = 1; k < TARGET_RATE_TAB_SZ; k++ ) { + if( TargetRate_bps <= rateTable[ k ] ) { + frac_Q6 = silk_DIV32( silk_LSHIFT( TargetRate_bps - rateTable[ k - 1 ], 6 ), + rateTable[ k ] - rateTable[ k - 1 ] ); + psEncC->SNR_dB_Q7 = silk_LSHIFT( silk_SNR_table_Q1[ k - 1 ], 6 ) + silk_MUL( frac_Q6, silk_SNR_table_Q1[ k ] - silk_SNR_table_Q1[ k - 1 ] ); + break; + } + } + + /* Reduce coding quality whenever LBRR is enabled, to free up some bits */ + if( psEncC->LBRR_enabled ) { + psEncC->SNR_dB_Q7 = silk_SMLABB( psEncC->SNR_dB_Q7, 12 - psEncC->LBRR_GainIncreases, SILK_FIX_CONST( -0.25, 7 ) ); + } + } + + return ret; +} diff --git a/src/opus-1.1/silk/control_audio_bandwidth.c b/src/opus-1.1/silk/control_audio_bandwidth.c new file mode 100644 index 00000000..4f9bc5cb --- /dev/null +++ b/src/opus-1.1/silk/control_audio_bandwidth.c @@ -0,0 +1,126 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main.h" +#include "tuning_parameters.h" + +/* Control internal sampling rate */ +opus_int silk_control_audio_bandwidth( + silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */ + silk_EncControlStruct *encControl /* I Control structure */ +) +{ + opus_int fs_kHz; + opus_int32 fs_Hz; + + fs_kHz = psEncC->fs_kHz; + fs_Hz = silk_SMULBB( fs_kHz, 1000 ); + if( fs_Hz == 0 ) { + /* Encoder has just been initialized */ + fs_Hz = silk_min( psEncC->desiredInternal_fs_Hz, psEncC->API_fs_Hz ); + fs_kHz = silk_DIV32_16( fs_Hz, 1000 ); + } else if( fs_Hz > psEncC->API_fs_Hz || fs_Hz > psEncC->maxInternal_fs_Hz || fs_Hz < psEncC->minInternal_fs_Hz ) { + /* Make sure internal rate is not higher than external rate or maximum allowed, or lower than minimum allowed */ + fs_Hz = psEncC->API_fs_Hz; + fs_Hz = silk_min( fs_Hz, psEncC->maxInternal_fs_Hz ); + fs_Hz = silk_max( fs_Hz, psEncC->minInternal_fs_Hz ); + fs_kHz = silk_DIV32_16( fs_Hz, 1000 ); + } else { + /* State machine for the internal sampling rate switching */ + if( psEncC->sLP.transition_frame_no >= TRANSITION_FRAMES ) { + /* Stop transition phase */ + psEncC->sLP.mode = 0; + } + if( psEncC->allow_bandwidth_switch || encControl->opusCanSwitch ) { + /* Check if we should switch down */ + if( silk_SMULBB( psEncC->fs_kHz, 1000 ) > psEncC->desiredInternal_fs_Hz ) + { + /* Switch down */ + if( psEncC->sLP.mode == 0 ) { + /* New transition */ + psEncC->sLP.transition_frame_no = TRANSITION_FRAMES; + + /* Reset transition filter state */ + silk_memset( psEncC->sLP.In_LP_State, 0, sizeof( psEncC->sLP.In_LP_State ) ); + } + if( encControl->opusCanSwitch ) { + /* Stop transition phase */ + psEncC->sLP.mode = 0; + + /* Switch to a lower sample frequency */ + fs_kHz = psEncC->fs_kHz == 16 ? 12 : 8; + } else { + if( psEncC->sLP.transition_frame_no <= 0 ) { + encControl->switchReady = 1; + /* Make room for redundancy */ + encControl->maxBits -= encControl->maxBits * 5 / ( encControl->payloadSize_ms + 5 ); + } else { + /* Direction: down (at double speed) */ + psEncC->sLP.mode = -2; + } + } + } + else + /* Check if we should switch up */ + if( silk_SMULBB( psEncC->fs_kHz, 1000 ) < psEncC->desiredInternal_fs_Hz ) + { + /* Switch up */ + if( encControl->opusCanSwitch ) { + /* Switch to a higher sample frequency */ + fs_kHz = psEncC->fs_kHz == 8 ? 12 : 16; + + /* New transition */ + psEncC->sLP.transition_frame_no = 0; + + /* Reset transition filter state */ + silk_memset( psEncC->sLP.In_LP_State, 0, sizeof( psEncC->sLP.In_LP_State ) ); + + /* Direction: up */ + psEncC->sLP.mode = 1; + } else { + if( psEncC->sLP.mode == 0 ) { + encControl->switchReady = 1; + /* Make room for redundancy */ + encControl->maxBits -= encControl->maxBits * 5 / ( encControl->payloadSize_ms + 5 ); + } else { + /* Direction: up */ + psEncC->sLP.mode = 1; + } + } + } else { + if (psEncC->sLP.mode<0) + psEncC->sLP.mode = 1; + } + } + } + + return fs_kHz; +} diff --git a/src/opus-1.1/silk/control_codec.c b/src/opus-1.1/silk/control_codec.c new file mode 100644 index 00000000..1f674bdd --- /dev/null +++ b/src/opus-1.1/silk/control_codec.c @@ -0,0 +1,422 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#ifdef FIXED_POINT +#include "main_FIX.h" +#define silk_encoder_state_Fxx silk_encoder_state_FIX +#else +#include "main_FLP.h" +#define silk_encoder_state_Fxx silk_encoder_state_FLP +#endif +#include "stack_alloc.h" +#include "tuning_parameters.h" +#include "pitch_est_defines.h" + +static opus_int silk_setup_resamplers( + silk_encoder_state_Fxx *psEnc, /* I/O */ + opus_int fs_kHz /* I */ +); + +static opus_int silk_setup_fs( + silk_encoder_state_Fxx *psEnc, /* I/O */ + opus_int fs_kHz, /* I */ + opus_int PacketSize_ms /* I */ +); + +static opus_int silk_setup_complexity( + silk_encoder_state *psEncC, /* I/O */ + opus_int Complexity /* I */ +); + +static OPUS_INLINE opus_int silk_setup_LBRR( + silk_encoder_state *psEncC, /* I/O */ + const opus_int32 TargetRate_bps /* I */ +); + + +/* Control encoder */ +opus_int silk_control_encoder( + silk_encoder_state_Fxx *psEnc, /* I/O Pointer to Silk encoder state */ + silk_EncControlStruct *encControl, /* I Control structure */ + const opus_int32 TargetRate_bps, /* I Target max bitrate (bps) */ + const opus_int allow_bw_switch, /* I Flag to allow switching audio bandwidth */ + const opus_int channelNb, /* I Channel number */ + const opus_int force_fs_kHz +) +{ + opus_int fs_kHz, ret = 0; + + psEnc->sCmn.useDTX = encControl->useDTX; + psEnc->sCmn.useCBR = encControl->useCBR; + psEnc->sCmn.API_fs_Hz = encControl->API_sampleRate; + psEnc->sCmn.maxInternal_fs_Hz = encControl->maxInternalSampleRate; + psEnc->sCmn.minInternal_fs_Hz = encControl->minInternalSampleRate; + psEnc->sCmn.desiredInternal_fs_Hz = encControl->desiredInternalSampleRate; + psEnc->sCmn.useInBandFEC = encControl->useInBandFEC; + psEnc->sCmn.nChannelsAPI = encControl->nChannelsAPI; + psEnc->sCmn.nChannelsInternal = encControl->nChannelsInternal; + psEnc->sCmn.allow_bandwidth_switch = allow_bw_switch; + psEnc->sCmn.channelNb = channelNb; + + if( psEnc->sCmn.controlled_since_last_payload != 0 && psEnc->sCmn.prefillFlag == 0 ) { + if( psEnc->sCmn.API_fs_Hz != psEnc->sCmn.prev_API_fs_Hz && psEnc->sCmn.fs_kHz > 0 ) { + /* Change in API sampling rate in the middle of encoding a packet */ + ret += silk_setup_resamplers( psEnc, psEnc->sCmn.fs_kHz ); + } + return ret; + } + + /* Beyond this point we know that there are no previously coded frames in the payload buffer */ + + /********************************************/ + /* Determine internal sampling rate */ + /********************************************/ + fs_kHz = silk_control_audio_bandwidth( &psEnc->sCmn, encControl ); + if( force_fs_kHz ) { + fs_kHz = force_fs_kHz; + } + /********************************************/ + /* Prepare resampler and buffered data */ + /********************************************/ + ret += silk_setup_resamplers( psEnc, fs_kHz ); + + /********************************************/ + /* Set internal sampling frequency */ + /********************************************/ + ret += silk_setup_fs( psEnc, fs_kHz, encControl->payloadSize_ms ); + + /********************************************/ + /* Set encoding complexity */ + /********************************************/ + ret += silk_setup_complexity( &psEnc->sCmn, encControl->complexity ); + + /********************************************/ + /* Set packet loss rate measured by farend */ + /********************************************/ + psEnc->sCmn.PacketLoss_perc = encControl->packetLossPercentage; + + /********************************************/ + /* Set LBRR usage */ + /********************************************/ + ret += silk_setup_LBRR( &psEnc->sCmn, TargetRate_bps ); + + psEnc->sCmn.controlled_since_last_payload = 1; + + return ret; +} + +static opus_int silk_setup_resamplers( + silk_encoder_state_Fxx *psEnc, /* I/O */ + opus_int fs_kHz /* I */ +) +{ + opus_int ret = SILK_NO_ERROR; + SAVE_STACK; + + if( psEnc->sCmn.fs_kHz != fs_kHz || psEnc->sCmn.prev_API_fs_Hz != psEnc->sCmn.API_fs_Hz ) + { + if( psEnc->sCmn.fs_kHz == 0 ) { + /* Initialize the resampler for enc_API.c preparing resampling from API_fs_Hz to fs_kHz */ + ret += silk_resampler_init( &psEnc->sCmn.resampler_state, psEnc->sCmn.API_fs_Hz, fs_kHz * 1000, 1 ); + } else { + VARDECL( opus_int16, x_buf_API_fs_Hz ); + VARDECL( silk_resampler_state_struct, temp_resampler_state ); +#ifdef FIXED_POINT + opus_int16 *x_bufFIX = psEnc->x_buf; +#else + VARDECL( opus_int16, x_bufFIX ); + opus_int32 new_buf_samples; +#endif + opus_int32 api_buf_samples; + opus_int32 old_buf_samples; + opus_int32 buf_length_ms; + + buf_length_ms = silk_LSHIFT( psEnc->sCmn.nb_subfr * 5, 1 ) + LA_SHAPE_MS; + old_buf_samples = buf_length_ms * psEnc->sCmn.fs_kHz; + +#ifndef FIXED_POINT + new_buf_samples = buf_length_ms * fs_kHz; + ALLOC( x_bufFIX, silk_max( old_buf_samples, new_buf_samples ), + opus_int16 ); + silk_float2short_array( x_bufFIX, psEnc->x_buf, old_buf_samples ); +#endif + + /* Initialize resampler for temporary resampling of x_buf data to API_fs_Hz */ + ALLOC( temp_resampler_state, 1, silk_resampler_state_struct ); + ret += silk_resampler_init( temp_resampler_state, silk_SMULBB( psEnc->sCmn.fs_kHz, 1000 ), psEnc->sCmn.API_fs_Hz, 0 ); + + /* Calculate number of samples to temporarily upsample */ + api_buf_samples = buf_length_ms * silk_DIV32_16( psEnc->sCmn.API_fs_Hz, 1000 ); + + /* Temporary resampling of x_buf data to API_fs_Hz */ + ALLOC( x_buf_API_fs_Hz, api_buf_samples, opus_int16 ); + ret += silk_resampler( temp_resampler_state, x_buf_API_fs_Hz, x_bufFIX, old_buf_samples ); + + /* Initialize the resampler for enc_API.c preparing resampling from API_fs_Hz to fs_kHz */ + ret += silk_resampler_init( &psEnc->sCmn.resampler_state, psEnc->sCmn.API_fs_Hz, silk_SMULBB( fs_kHz, 1000 ), 1 ); + + /* Correct resampler state by resampling buffered data from API_fs_Hz to fs_kHz */ + ret += silk_resampler( &psEnc->sCmn.resampler_state, x_bufFIX, x_buf_API_fs_Hz, api_buf_samples ); + +#ifndef FIXED_POINT + silk_short2float_array( psEnc->x_buf, x_bufFIX, new_buf_samples); +#endif + } + } + + psEnc->sCmn.prev_API_fs_Hz = psEnc->sCmn.API_fs_Hz; + + RESTORE_STACK; + return ret; +} + +static opus_int silk_setup_fs( + silk_encoder_state_Fxx *psEnc, /* I/O */ + opus_int fs_kHz, /* I */ + opus_int PacketSize_ms /* I */ +) +{ + opus_int ret = SILK_NO_ERROR; + + /* Set packet size */ + if( PacketSize_ms != psEnc->sCmn.PacketSize_ms ) { + if( ( PacketSize_ms != 10 ) && + ( PacketSize_ms != 20 ) && + ( PacketSize_ms != 40 ) && + ( PacketSize_ms != 60 ) ) { + ret = SILK_ENC_PACKET_SIZE_NOT_SUPPORTED; + } + if( PacketSize_ms <= 10 ) { + psEnc->sCmn.nFramesPerPacket = 1; + psEnc->sCmn.nb_subfr = PacketSize_ms == 10 ? 2 : 1; + psEnc->sCmn.frame_length = silk_SMULBB( PacketSize_ms, fs_kHz ); + psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS_2_SF, fs_kHz ); + if( psEnc->sCmn.fs_kHz == 8 ) { + psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_10_ms_NB_iCDF; + } else { + psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_10_ms_iCDF; + } + } else { + psEnc->sCmn.nFramesPerPacket = silk_DIV32_16( PacketSize_ms, MAX_FRAME_LENGTH_MS ); + psEnc->sCmn.nb_subfr = MAX_NB_SUBFR; + psEnc->sCmn.frame_length = silk_SMULBB( 20, fs_kHz ); + psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS, fs_kHz ); + if( psEnc->sCmn.fs_kHz == 8 ) { + psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_NB_iCDF; + } else { + psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_iCDF; + } + } + psEnc->sCmn.PacketSize_ms = PacketSize_ms; + psEnc->sCmn.TargetRate_bps = 0; /* trigger new SNR computation */ + } + + /* Set internal sampling frequency */ + silk_assert( fs_kHz == 8 || fs_kHz == 12 || fs_kHz == 16 ); + silk_assert( psEnc->sCmn.nb_subfr == 2 || psEnc->sCmn.nb_subfr == 4 ); + if( psEnc->sCmn.fs_kHz != fs_kHz ) { + /* reset part of the state */ + silk_memset( &psEnc->sShape, 0, sizeof( psEnc->sShape ) ); + silk_memset( &psEnc->sPrefilt, 0, sizeof( psEnc->sPrefilt ) ); + silk_memset( &psEnc->sCmn.sNSQ, 0, sizeof( psEnc->sCmn.sNSQ ) ); + silk_memset( psEnc->sCmn.prev_NLSFq_Q15, 0, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) ); + silk_memset( &psEnc->sCmn.sLP.In_LP_State, 0, sizeof( psEnc->sCmn.sLP.In_LP_State ) ); + psEnc->sCmn.inputBufIx = 0; + psEnc->sCmn.nFramesEncoded = 0; + psEnc->sCmn.TargetRate_bps = 0; /* trigger new SNR computation */ + + /* Initialize non-zero parameters */ + psEnc->sCmn.prevLag = 100; + psEnc->sCmn.first_frame_after_reset = 1; + psEnc->sPrefilt.lagPrev = 100; + psEnc->sShape.LastGainIndex = 10; + psEnc->sCmn.sNSQ.lagPrev = 100; + psEnc->sCmn.sNSQ.prev_gain_Q16 = 65536; + psEnc->sCmn.prevSignalType = TYPE_NO_VOICE_ACTIVITY; + + psEnc->sCmn.fs_kHz = fs_kHz; + if( psEnc->sCmn.fs_kHz == 8 ) { + if( psEnc->sCmn.nb_subfr == MAX_NB_SUBFR ) { + psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_NB_iCDF; + } else { + psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_10_ms_NB_iCDF; + } + } else { + if( psEnc->sCmn.nb_subfr == MAX_NB_SUBFR ) { + psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_iCDF; + } else { + psEnc->sCmn.pitch_contour_iCDF = silk_pitch_contour_10_ms_iCDF; + } + } + if( psEnc->sCmn.fs_kHz == 8 || psEnc->sCmn.fs_kHz == 12 ) { + psEnc->sCmn.predictLPCOrder = MIN_LPC_ORDER; + psEnc->sCmn.psNLSF_CB = &silk_NLSF_CB_NB_MB; + } else { + psEnc->sCmn.predictLPCOrder = MAX_LPC_ORDER; + psEnc->sCmn.psNLSF_CB = &silk_NLSF_CB_WB; + } + psEnc->sCmn.subfr_length = SUB_FRAME_LENGTH_MS * fs_kHz; + psEnc->sCmn.frame_length = silk_SMULBB( psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr ); + psEnc->sCmn.ltp_mem_length = silk_SMULBB( LTP_MEM_LENGTH_MS, fs_kHz ); + psEnc->sCmn.la_pitch = silk_SMULBB( LA_PITCH_MS, fs_kHz ); + psEnc->sCmn.max_pitch_lag = silk_SMULBB( 18, fs_kHz ); + if( psEnc->sCmn.nb_subfr == MAX_NB_SUBFR ) { + psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS, fs_kHz ); + } else { + psEnc->sCmn.pitch_LPC_win_length = silk_SMULBB( FIND_PITCH_LPC_WIN_MS_2_SF, fs_kHz ); + } + if( psEnc->sCmn.fs_kHz == 16 ) { + psEnc->sCmn.mu_LTP_Q9 = SILK_FIX_CONST( MU_LTP_QUANT_WB, 9 ); + psEnc->sCmn.pitch_lag_low_bits_iCDF = silk_uniform8_iCDF; + } else if( psEnc->sCmn.fs_kHz == 12 ) { + psEnc->sCmn.mu_LTP_Q9 = SILK_FIX_CONST( MU_LTP_QUANT_MB, 9 ); + psEnc->sCmn.pitch_lag_low_bits_iCDF = silk_uniform6_iCDF; + } else { + psEnc->sCmn.mu_LTP_Q9 = SILK_FIX_CONST( MU_LTP_QUANT_NB, 9 ); + psEnc->sCmn.pitch_lag_low_bits_iCDF = silk_uniform4_iCDF; + } + } + + /* Check that settings are valid */ + silk_assert( ( psEnc->sCmn.subfr_length * psEnc->sCmn.nb_subfr ) == psEnc->sCmn.frame_length ); + + return ret; +} + +static opus_int silk_setup_complexity( + silk_encoder_state *psEncC, /* I/O */ + opus_int Complexity /* I */ +) +{ + opus_int ret = 0; + + /* Set encoding complexity */ + silk_assert( Complexity >= 0 && Complexity <= 10 ); + if( Complexity < 2 ) { + psEncC->pitchEstimationComplexity = SILK_PE_MIN_COMPLEX; + psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.8, 16 ); + psEncC->pitchEstimationLPCOrder = 6; + psEncC->shapingLPCOrder = 8; + psEncC->la_shape = 3 * psEncC->fs_kHz; + psEncC->nStatesDelayedDecision = 1; + psEncC->useInterpolatedNLSFs = 0; + psEncC->LTPQuantLowComplexity = 1; + psEncC->NLSF_MSVQ_Survivors = 2; + psEncC->warping_Q16 = 0; + } else if( Complexity < 4 ) { + psEncC->pitchEstimationComplexity = SILK_PE_MID_COMPLEX; + psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.76, 16 ); + psEncC->pitchEstimationLPCOrder = 8; + psEncC->shapingLPCOrder = 10; + psEncC->la_shape = 5 * psEncC->fs_kHz; + psEncC->nStatesDelayedDecision = 1; + psEncC->useInterpolatedNLSFs = 0; + psEncC->LTPQuantLowComplexity = 0; + psEncC->NLSF_MSVQ_Survivors = 4; + psEncC->warping_Q16 = 0; + } else if( Complexity < 6 ) { + psEncC->pitchEstimationComplexity = SILK_PE_MID_COMPLEX; + psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.74, 16 ); + psEncC->pitchEstimationLPCOrder = 10; + psEncC->shapingLPCOrder = 12; + psEncC->la_shape = 5 * psEncC->fs_kHz; + psEncC->nStatesDelayedDecision = 2; + psEncC->useInterpolatedNLSFs = 1; + psEncC->LTPQuantLowComplexity = 0; + psEncC->NLSF_MSVQ_Survivors = 8; + psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 ); + } else if( Complexity < 8 ) { + psEncC->pitchEstimationComplexity = SILK_PE_MID_COMPLEX; + psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.72, 16 ); + psEncC->pitchEstimationLPCOrder = 12; + psEncC->shapingLPCOrder = 14; + psEncC->la_shape = 5 * psEncC->fs_kHz; + psEncC->nStatesDelayedDecision = 3; + psEncC->useInterpolatedNLSFs = 1; + psEncC->LTPQuantLowComplexity = 0; + psEncC->NLSF_MSVQ_Survivors = 16; + psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 ); + } else { + psEncC->pitchEstimationComplexity = SILK_PE_MAX_COMPLEX; + psEncC->pitchEstimationThreshold_Q16 = SILK_FIX_CONST( 0.7, 16 ); + psEncC->pitchEstimationLPCOrder = 16; + psEncC->shapingLPCOrder = 16; + psEncC->la_shape = 5 * psEncC->fs_kHz; + psEncC->nStatesDelayedDecision = MAX_DEL_DEC_STATES; + psEncC->useInterpolatedNLSFs = 1; + psEncC->LTPQuantLowComplexity = 0; + psEncC->NLSF_MSVQ_Survivors = 32; + psEncC->warping_Q16 = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 ); + } + + /* Do not allow higher pitch estimation LPC order than predict LPC order */ + psEncC->pitchEstimationLPCOrder = silk_min_int( psEncC->pitchEstimationLPCOrder, psEncC->predictLPCOrder ); + psEncC->shapeWinLength = SUB_FRAME_LENGTH_MS * psEncC->fs_kHz + 2 * psEncC->la_shape; + psEncC->Complexity = Complexity; + + silk_assert( psEncC->pitchEstimationLPCOrder <= MAX_FIND_PITCH_LPC_ORDER ); + silk_assert( psEncC->shapingLPCOrder <= MAX_SHAPE_LPC_ORDER ); + silk_assert( psEncC->nStatesDelayedDecision <= MAX_DEL_DEC_STATES ); + silk_assert( psEncC->warping_Q16 <= 32767 ); + silk_assert( psEncC->la_shape <= LA_SHAPE_MAX ); + silk_assert( psEncC->shapeWinLength <= SHAPE_LPC_WIN_MAX ); + silk_assert( psEncC->NLSF_MSVQ_Survivors <= NLSF_VQ_MAX_SURVIVORS ); + + return ret; +} + +static OPUS_INLINE opus_int silk_setup_LBRR( + silk_encoder_state *psEncC, /* I/O */ + const opus_int32 TargetRate_bps /* I */ +) +{ + opus_int ret = SILK_NO_ERROR; + opus_int32 LBRR_rate_thres_bps; + + psEncC->LBRR_enabled = 0; + if( psEncC->useInBandFEC && psEncC->PacketLoss_perc > 0 ) { + if( psEncC->fs_kHz == 8 ) { + LBRR_rate_thres_bps = LBRR_NB_MIN_RATE_BPS; + } else if( psEncC->fs_kHz == 12 ) { + LBRR_rate_thres_bps = LBRR_MB_MIN_RATE_BPS; + } else { + LBRR_rate_thres_bps = LBRR_WB_MIN_RATE_BPS; + } + LBRR_rate_thres_bps = silk_SMULWB( silk_MUL( LBRR_rate_thres_bps, 125 - silk_min( psEncC->PacketLoss_perc, 25 ) ), SILK_FIX_CONST( 0.01, 16 ) ); + + if( TargetRate_bps > LBRR_rate_thres_bps ) { + /* Set gain increase for coding LBRR excitation */ + psEncC->LBRR_enabled = 1; + psEncC->LBRR_GainIncreases = silk_max_int( 7 - silk_SMULWB( (opus_int32)psEncC->PacketLoss_perc, SILK_FIX_CONST( 0.4, 16 ) ), 2 ); + } + } + + return ret; +} diff --git a/src/opus-1.1/silk/debug.c b/src/opus-1.1/silk/debug.c new file mode 100644 index 00000000..9253faf7 --- /dev/null +++ b/src/opus-1.1/silk/debug.c @@ -0,0 +1,170 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "debug.h" +#include "SigProc_FIX.h" + +#if SILK_TIC_TOC + +#ifdef _WIN32 + +#if (defined(_WIN32) || defined(_WINCE)) +#include /* timer */ +#else /* Linux or Mac*/ +#include +#endif + +unsigned long silk_GetHighResolutionTime(void) /* O time in usec*/ +{ + /* Returns a time counter in microsec */ + /* the resolution is platform dependent */ + /* but is typically 1.62 us resolution */ + LARGE_INTEGER lpPerformanceCount; + LARGE_INTEGER lpFrequency; + QueryPerformanceCounter(&lpPerformanceCount); + QueryPerformanceFrequency(&lpFrequency); + return (unsigned long)((1000000*(lpPerformanceCount.QuadPart)) / lpFrequency.QuadPart); +} +#else /* Linux or Mac*/ +unsigned long GetHighResolutionTime(void) /* O time in usec*/ +{ + struct timeval tv; + gettimeofday(&tv, 0); + return((tv.tv_sec*1000000)+(tv.tv_usec)); +} +#endif + +int silk_Timer_nTimers = 0; +int silk_Timer_depth_ctr = 0; +char silk_Timer_tags[silk_NUM_TIMERS_MAX][silk_NUM_TIMERS_MAX_TAG_LEN]; +#ifdef WIN32 +LARGE_INTEGER silk_Timer_start[silk_NUM_TIMERS_MAX]; +#else +unsigned long silk_Timer_start[silk_NUM_TIMERS_MAX]; +#endif +unsigned int silk_Timer_cnt[silk_NUM_TIMERS_MAX]; +opus_int64 silk_Timer_min[silk_NUM_TIMERS_MAX]; +opus_int64 silk_Timer_sum[silk_NUM_TIMERS_MAX]; +opus_int64 silk_Timer_max[silk_NUM_TIMERS_MAX]; +opus_int64 silk_Timer_depth[silk_NUM_TIMERS_MAX]; + +#ifdef WIN32 +void silk_TimerSave(char *file_name) +{ + if( silk_Timer_nTimers > 0 ) + { + int k; + FILE *fp; + LARGE_INTEGER lpFrequency; + LARGE_INTEGER lpPerformanceCount1, lpPerformanceCount2; + int del = 0x7FFFFFFF; + double avg, sum_avg; + /* estimate overhead of calling performance counters */ + for( k = 0; k < 1000; k++ ) { + QueryPerformanceCounter(&lpPerformanceCount1); + QueryPerformanceCounter(&lpPerformanceCount2); + lpPerformanceCount2.QuadPart -= lpPerformanceCount1.QuadPart; + if( (int)lpPerformanceCount2.LowPart < del ) + del = lpPerformanceCount2.LowPart; + } + QueryPerformanceFrequency(&lpFrequency); + /* print results to file */ + sum_avg = 0.0f; + for( k = 0; k < silk_Timer_nTimers; k++ ) { + if (silk_Timer_depth[k] == 0) { + sum_avg += (1e6 * silk_Timer_sum[k] / silk_Timer_cnt[k] - del) / lpFrequency.QuadPart * silk_Timer_cnt[k]; + } + } + fp = fopen(file_name, "w"); + fprintf(fp, " min avg %% max count\n"); + for( k = 0; k < silk_Timer_nTimers; k++ ) { + if (silk_Timer_depth[k] == 0) { + fprintf(fp, "%-28s", silk_Timer_tags[k]); + } else if (silk_Timer_depth[k] == 1) { + fprintf(fp, " %-27s", silk_Timer_tags[k]); + } else if (silk_Timer_depth[k] == 2) { + fprintf(fp, " %-26s", silk_Timer_tags[k]); + } else if (silk_Timer_depth[k] == 3) { + fprintf(fp, " %-25s", silk_Timer_tags[k]); + } else { + fprintf(fp, " %-24s", silk_Timer_tags[k]); + } + avg = (1e6 * silk_Timer_sum[k] / silk_Timer_cnt[k] - del) / lpFrequency.QuadPart; + fprintf(fp, "%8.2f", (1e6 * (silk_max_64(silk_Timer_min[k] - del, 0))) / lpFrequency.QuadPart); + fprintf(fp, "%12.2f %6.2f", avg, 100.0 * avg / sum_avg * silk_Timer_cnt[k]); + fprintf(fp, "%12.2f", (1e6 * (silk_max_64(silk_Timer_max[k] - del, 0))) / lpFrequency.QuadPart); + fprintf(fp, "%10d\n", silk_Timer_cnt[k]); + } + fprintf(fp, " microseconds\n"); + fclose(fp); + } +} +#else +void silk_TimerSave(char *file_name) +{ + if( silk_Timer_nTimers > 0 ) + { + int k; + FILE *fp; + /* print results to file */ + fp = fopen(file_name, "w"); + fprintf(fp, " min avg max count\n"); + for( k = 0; k < silk_Timer_nTimers; k++ ) + { + if (silk_Timer_depth[k] == 0) { + fprintf(fp, "%-28s", silk_Timer_tags[k]); + } else if (silk_Timer_depth[k] == 1) { + fprintf(fp, " %-27s", silk_Timer_tags[k]); + } else if (silk_Timer_depth[k] == 2) { + fprintf(fp, " %-26s", silk_Timer_tags[k]); + } else if (silk_Timer_depth[k] == 3) { + fprintf(fp, " %-25s", silk_Timer_tags[k]); + } else { + fprintf(fp, " %-24s", silk_Timer_tags[k]); + } + fprintf(fp, "%d ", silk_Timer_min[k]); + fprintf(fp, "%f ", (double)silk_Timer_sum[k] / (double)silk_Timer_cnt[k]); + fprintf(fp, "%d ", silk_Timer_max[k]); + fprintf(fp, "%10d\n", silk_Timer_cnt[k]); + } + fprintf(fp, " microseconds\n"); + fclose(fp); + } +} +#endif + +#endif /* SILK_TIC_TOC */ + +#if SILK_DEBUG +FILE *silk_debug_store_fp[ silk_NUM_STORES_MAX ]; +int silk_debug_store_count = 0; +#endif /* SILK_DEBUG */ + diff --git a/src/opus-1.1/silk/debug.h b/src/opus-1.1/silk/debug.h new file mode 100644 index 00000000..efb6d3e9 --- /dev/null +++ b/src/opus-1.1/silk/debug.h @@ -0,0 +1,279 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifndef SILK_DEBUG_H +#define SILK_DEBUG_H + +#include "typedef.h" +#include /* file writing */ +#include /* strcpy, strcmp */ + +#ifdef __cplusplus +extern "C" +{ +#endif + +unsigned long GetHighResolutionTime(void); /* O time in usec*/ + +/* make SILK_DEBUG dependent on compiler's _DEBUG */ +#if defined _WIN32 + #ifdef _DEBUG + #define SILK_DEBUG 1 + #else + #define SILK_DEBUG 0 + #endif + + /* overrule the above */ + #if 0 + /* #define NO_ASSERTS*/ + #undef SILK_DEBUG + #define SILK_DEBUG 1 + #endif +#else + #define SILK_DEBUG 0 +#endif + +/* Flag for using timers */ +#define SILK_TIC_TOC 0 + + +#if SILK_TIC_TOC + +#if (defined(_WIN32) || defined(_WINCE)) +#include /* timer */ +#else /* Linux or Mac*/ +#include +#endif + +/*********************************/ +/* timer functions for profiling */ +/*********************************/ +/* example: */ +/* */ +/* TIC(LPC) */ +/* do_LPC(in_vec, order, acoef); // do LPC analysis */ +/* TOC(LPC) */ +/* */ +/* and call the following just before exiting (from main) */ +/* */ +/* silk_TimerSave("silk_TimingData.txt"); */ +/* */ +/* results are now in silk_TimingData.txt */ + +void silk_TimerSave(char *file_name); + +/* max number of timers (in different locations) */ +#define silk_NUM_TIMERS_MAX 50 +/* max length of name tags in TIC(..), TOC(..) */ +#define silk_NUM_TIMERS_MAX_TAG_LEN 30 + +extern int silk_Timer_nTimers; +extern int silk_Timer_depth_ctr; +extern char silk_Timer_tags[silk_NUM_TIMERS_MAX][silk_NUM_TIMERS_MAX_TAG_LEN]; +#ifdef _WIN32 +extern LARGE_INTEGER silk_Timer_start[silk_NUM_TIMERS_MAX]; +#else +extern unsigned long silk_Timer_start[silk_NUM_TIMERS_MAX]; +#endif +extern unsigned int silk_Timer_cnt[silk_NUM_TIMERS_MAX]; +extern opus_int64 silk_Timer_sum[silk_NUM_TIMERS_MAX]; +extern opus_int64 silk_Timer_max[silk_NUM_TIMERS_MAX]; +extern opus_int64 silk_Timer_min[silk_NUM_TIMERS_MAX]; +extern opus_int64 silk_Timer_depth[silk_NUM_TIMERS_MAX]; + +/* WARNING: TIC()/TOC can measure only up to 0.1 seconds at a time */ +#ifdef _WIN32 +#define TIC(TAG_NAME) { \ + static int init = 0; \ + static int ID = -1; \ + if( init == 0 ) \ + { \ + int k; \ + init = 1; \ + for( k = 0; k < silk_Timer_nTimers; k++ ) { \ + if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \ + ID = k; \ + break; \ + } \ + } \ + if (ID == -1) { \ + ID = silk_Timer_nTimers; \ + silk_Timer_nTimers++; \ + silk_Timer_depth[ID] = silk_Timer_depth_ctr; \ + strcpy(silk_Timer_tags[ID], #TAG_NAME); \ + silk_Timer_cnt[ID] = 0; \ + silk_Timer_sum[ID] = 0; \ + silk_Timer_min[ID] = 0xFFFFFFFF; \ + silk_Timer_max[ID] = 0; \ + } \ + } \ + silk_Timer_depth_ctr++; \ + QueryPerformanceCounter(&silk_Timer_start[ID]); \ +} +#else +#define TIC(TAG_NAME) { \ + static int init = 0; \ + static int ID = -1; \ + if( init == 0 ) \ + { \ + int k; \ + init = 1; \ + for( k = 0; k < silk_Timer_nTimers; k++ ) { \ + if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \ + ID = k; \ + break; \ + } \ + } \ + if (ID == -1) { \ + ID = silk_Timer_nTimers; \ + silk_Timer_nTimers++; \ + silk_Timer_depth[ID] = silk_Timer_depth_ctr; \ + strcpy(silk_Timer_tags[ID], #TAG_NAME); \ + silk_Timer_cnt[ID] = 0; \ + silk_Timer_sum[ID] = 0; \ + silk_Timer_min[ID] = 0xFFFFFFFF; \ + silk_Timer_max[ID] = 0; \ + } \ + } \ + silk_Timer_depth_ctr++; \ + silk_Timer_start[ID] = GetHighResolutionTime(); \ +} +#endif + +#ifdef _WIN32 +#define TOC(TAG_NAME) { \ + LARGE_INTEGER lpPerformanceCount; \ + static int init = 0; \ + static int ID = 0; \ + if( init == 0 ) \ + { \ + int k; \ + init = 1; \ + for( k = 0; k < silk_Timer_nTimers; k++ ) { \ + if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \ + ID = k; \ + break; \ + } \ + } \ + } \ + QueryPerformanceCounter(&lpPerformanceCount); \ + lpPerformanceCount.QuadPart -= silk_Timer_start[ID].QuadPart; \ + if((lpPerformanceCount.QuadPart < 100000000) && \ + (lpPerformanceCount.QuadPart >= 0)) { \ + silk_Timer_cnt[ID]++; \ + silk_Timer_sum[ID] += lpPerformanceCount.QuadPart; \ + if( lpPerformanceCount.QuadPart > silk_Timer_max[ID] ) \ + silk_Timer_max[ID] = lpPerformanceCount.QuadPart; \ + if( lpPerformanceCount.QuadPart < silk_Timer_min[ID] ) \ + silk_Timer_min[ID] = lpPerformanceCount.QuadPart; \ + } \ + silk_Timer_depth_ctr--; \ +} +#else +#define TOC(TAG_NAME) { \ + unsigned long endTime; \ + static int init = 0; \ + static int ID = 0; \ + if( init == 0 ) \ + { \ + int k; \ + init = 1; \ + for( k = 0; k < silk_Timer_nTimers; k++ ) { \ + if( strcmp(silk_Timer_tags[k], #TAG_NAME) == 0 ) { \ + ID = k; \ + break; \ + } \ + } \ + } \ + endTime = GetHighResolutionTime(); \ + endTime -= silk_Timer_start[ID]; \ + if((endTime < 100000000) && \ + (endTime >= 0)) { \ + silk_Timer_cnt[ID]++; \ + silk_Timer_sum[ID] += endTime; \ + if( endTime > silk_Timer_max[ID] ) \ + silk_Timer_max[ID] = endTime; \ + if( endTime < silk_Timer_min[ID] ) \ + silk_Timer_min[ID] = endTime; \ + } \ + silk_Timer_depth_ctr--; \ +} +#endif + +#else /* SILK_TIC_TOC */ + +/* define macros as empty strings */ +#define TIC(TAG_NAME) +#define TOC(TAG_NAME) +#define silk_TimerSave(FILE_NAME) + +#endif /* SILK_TIC_TOC */ + + +#if SILK_DEBUG +/************************************/ +/* write data to file for debugging */ +/************************************/ +/* Example: DEBUG_STORE_DATA(testfile.pcm, &RIN[0], 160*sizeof(opus_int16)); */ + +#define silk_NUM_STORES_MAX 100 +extern FILE *silk_debug_store_fp[ silk_NUM_STORES_MAX ]; +extern int silk_debug_store_count; + +/* Faster way of storing the data */ +#define DEBUG_STORE_DATA( FILE_NAME, DATA_PTR, N_BYTES ) { \ + static opus_int init = 0, cnt = 0; \ + static FILE **fp; \ + if (init == 0) { \ + init = 1; \ + cnt = silk_debug_store_count++; \ + silk_debug_store_fp[ cnt ] = fopen(#FILE_NAME, "wb"); \ + } \ + fwrite((DATA_PTR), (N_BYTES), 1, silk_debug_store_fp[ cnt ]); \ +} + +/* Call this at the end of main() */ +#define SILK_DEBUG_STORE_CLOSE_FILES { \ + opus_int i; \ + for( i = 0; i < silk_debug_store_count; i++ ) { \ + fclose( silk_debug_store_fp[ i ] ); \ + } \ +} + +#else /* SILK_DEBUG */ + +/* define macros as empty strings */ +#define DEBUG_STORE_DATA(FILE_NAME, DATA_PTR, N_BYTES) +#define SILK_DEBUG_STORE_CLOSE_FILES + +#endif /* SILK_DEBUG */ + +#ifdef __cplusplus +} +#endif + +#endif /* SILK_DEBUG_H */ diff --git a/src/opus-1.1/silk/dec_API.c b/src/opus-1.1/silk/dec_API.c new file mode 100644 index 00000000..4cbcf715 --- /dev/null +++ b/src/opus-1.1/silk/dec_API.c @@ -0,0 +1,397 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "API.h" +#include "main.h" +#include "stack_alloc.h" + +/************************/ +/* Decoder Super Struct */ +/************************/ +typedef struct { + silk_decoder_state channel_state[ DECODER_NUM_CHANNELS ]; + stereo_dec_state sStereo; + opus_int nChannelsAPI; + opus_int nChannelsInternal; + opus_int prev_decode_only_middle; +} silk_decoder; + +/*********************/ +/* Decoder functions */ +/*********************/ + +opus_int silk_Get_Decoder_Size( /* O Returns error code */ + opus_int *decSizeBytes /* O Number of bytes in SILK decoder state */ +) +{ + opus_int ret = SILK_NO_ERROR; + + *decSizeBytes = sizeof( silk_decoder ); + + return ret; +} + +/* Reset decoder state */ +opus_int silk_InitDecoder( /* O Returns error code */ + void *decState /* I/O State */ +) +{ + opus_int n, ret = SILK_NO_ERROR; + silk_decoder_state *channel_state = ((silk_decoder *)decState)->channel_state; + + for( n = 0; n < DECODER_NUM_CHANNELS; n++ ) { + ret = silk_init_decoder( &channel_state[ n ] ); + } + silk_memset(&((silk_decoder *)decState)->sStereo, 0, sizeof(((silk_decoder *)decState)->sStereo)); + /* Not strictly needed, but it's cleaner that way */ + ((silk_decoder *)decState)->prev_decode_only_middle = 0; + + return ret; +} + +/* Decode a frame */ +opus_int silk_Decode( /* O Returns error code */ + void* decState, /* I/O State */ + silk_DecControlStruct* decControl, /* I/O Control Structure */ + opus_int lostFlag, /* I 0: no loss, 1 loss, 2 decode fec */ + opus_int newPacketFlag, /* I Indicates first decoder call for this packet */ + ec_dec *psRangeDec, /* I/O Compressor data structure */ + opus_int16 *samplesOut, /* O Decoded output speech vector */ + opus_int32 *nSamplesOut /* O Number of samples decoded */ +) +{ + opus_int i, n, decode_only_middle = 0, ret = SILK_NO_ERROR; + opus_int32 nSamplesOutDec, LBRR_symbol; + opus_int16 *samplesOut1_tmp[ 2 ]; + VARDECL( opus_int16, samplesOut1_tmp_storage ); + VARDECL( opus_int16, samplesOut2_tmp ); + opus_int32 MS_pred_Q13[ 2 ] = { 0 }; + opus_int16 *resample_out_ptr; + silk_decoder *psDec = ( silk_decoder * )decState; + silk_decoder_state *channel_state = psDec->channel_state; + opus_int has_side; + opus_int stereo_to_mono; + SAVE_STACK; + + silk_assert( decControl->nChannelsInternal == 1 || decControl->nChannelsInternal == 2 ); + + /**********************************/ + /* Test if first frame in payload */ + /**********************************/ + if( newPacketFlag ) { + for( n = 0; n < decControl->nChannelsInternal; n++ ) { + channel_state[ n ].nFramesDecoded = 0; /* Used to count frames in packet */ + } + } + + /* If Mono -> Stereo transition in bitstream: init state of second channel */ + if( decControl->nChannelsInternal > psDec->nChannelsInternal ) { + ret += silk_init_decoder( &channel_state[ 1 ] ); + } + + stereo_to_mono = decControl->nChannelsInternal == 1 && psDec->nChannelsInternal == 2 && + ( decControl->internalSampleRate == 1000*channel_state[ 0 ].fs_kHz ); + + if( channel_state[ 0 ].nFramesDecoded == 0 ) { + for( n = 0; n < decControl->nChannelsInternal; n++ ) { + opus_int fs_kHz_dec; + if( decControl->payloadSize_ms == 0 ) { + /* Assuming packet loss, use 10 ms */ + channel_state[ n ].nFramesPerPacket = 1; + channel_state[ n ].nb_subfr = 2; + } else if( decControl->payloadSize_ms == 10 ) { + channel_state[ n ].nFramesPerPacket = 1; + channel_state[ n ].nb_subfr = 2; + } else if( decControl->payloadSize_ms == 20 ) { + channel_state[ n ].nFramesPerPacket = 1; + channel_state[ n ].nb_subfr = 4; + } else if( decControl->payloadSize_ms == 40 ) { + channel_state[ n ].nFramesPerPacket = 2; + channel_state[ n ].nb_subfr = 4; + } else if( decControl->payloadSize_ms == 60 ) { + channel_state[ n ].nFramesPerPacket = 3; + channel_state[ n ].nb_subfr = 4; + } else { + silk_assert( 0 ); + RESTORE_STACK; + return SILK_DEC_INVALID_FRAME_SIZE; + } + fs_kHz_dec = ( decControl->internalSampleRate >> 10 ) + 1; + if( fs_kHz_dec != 8 && fs_kHz_dec != 12 && fs_kHz_dec != 16 ) { + silk_assert( 0 ); + RESTORE_STACK; + return SILK_DEC_INVALID_SAMPLING_FREQUENCY; + } + ret += silk_decoder_set_fs( &channel_state[ n ], fs_kHz_dec, decControl->API_sampleRate ); + } + } + + if( decControl->nChannelsAPI == 2 && decControl->nChannelsInternal == 2 && ( psDec->nChannelsAPI == 1 || psDec->nChannelsInternal == 1 ) ) { + silk_memset( psDec->sStereo.pred_prev_Q13, 0, sizeof( psDec->sStereo.pred_prev_Q13 ) ); + silk_memset( psDec->sStereo.sSide, 0, sizeof( psDec->sStereo.sSide ) ); + silk_memcpy( &channel_state[ 1 ].resampler_state, &channel_state[ 0 ].resampler_state, sizeof( silk_resampler_state_struct ) ); + } + psDec->nChannelsAPI = decControl->nChannelsAPI; + psDec->nChannelsInternal = decControl->nChannelsInternal; + + if( decControl->API_sampleRate > (opus_int32)MAX_API_FS_KHZ * 1000 || decControl->API_sampleRate < 8000 ) { + ret = SILK_DEC_INVALID_SAMPLING_FREQUENCY; + RESTORE_STACK; + return( ret ); + } + + if( lostFlag != FLAG_PACKET_LOST && channel_state[ 0 ].nFramesDecoded == 0 ) { + /* First decoder call for this payload */ + /* Decode VAD flags and LBRR flag */ + for( n = 0; n < decControl->nChannelsInternal; n++ ) { + for( i = 0; i < channel_state[ n ].nFramesPerPacket; i++ ) { + channel_state[ n ].VAD_flags[ i ] = ec_dec_bit_logp(psRangeDec, 1); + } + channel_state[ n ].LBRR_flag = ec_dec_bit_logp(psRangeDec, 1); + } + /* Decode LBRR flags */ + for( n = 0; n < decControl->nChannelsInternal; n++ ) { + silk_memset( channel_state[ n ].LBRR_flags, 0, sizeof( channel_state[ n ].LBRR_flags ) ); + if( channel_state[ n ].LBRR_flag ) { + if( channel_state[ n ].nFramesPerPacket == 1 ) { + channel_state[ n ].LBRR_flags[ 0 ] = 1; + } else { + LBRR_symbol = ec_dec_icdf( psRangeDec, silk_LBRR_flags_iCDF_ptr[ channel_state[ n ].nFramesPerPacket - 2 ], 8 ) + 1; + for( i = 0; i < channel_state[ n ].nFramesPerPacket; i++ ) { + channel_state[ n ].LBRR_flags[ i ] = silk_RSHIFT( LBRR_symbol, i ) & 1; + } + } + } + } + + if( lostFlag == FLAG_DECODE_NORMAL ) { + /* Regular decoding: skip all LBRR data */ + for( i = 0; i < channel_state[ 0 ].nFramesPerPacket; i++ ) { + for( n = 0; n < decControl->nChannelsInternal; n++ ) { + if( channel_state[ n ].LBRR_flags[ i ] ) { + opus_int pulses[ MAX_FRAME_LENGTH ]; + opus_int condCoding; + + if( decControl->nChannelsInternal == 2 && n == 0 ) { + silk_stereo_decode_pred( psRangeDec, MS_pred_Q13 ); + if( channel_state[ 1 ].LBRR_flags[ i ] == 0 ) { + silk_stereo_decode_mid_only( psRangeDec, &decode_only_middle ); + } + } + /* Use conditional coding if previous frame available */ + if( i > 0 && channel_state[ n ].LBRR_flags[ i - 1 ] ) { + condCoding = CODE_CONDITIONALLY; + } else { + condCoding = CODE_INDEPENDENTLY; + } + silk_decode_indices( &channel_state[ n ], psRangeDec, i, 1, condCoding ); + silk_decode_pulses( psRangeDec, pulses, channel_state[ n ].indices.signalType, + channel_state[ n ].indices.quantOffsetType, channel_state[ n ].frame_length ); + } + } + } + } + } + + /* Get MS predictor index */ + if( decControl->nChannelsInternal == 2 ) { + if( lostFlag == FLAG_DECODE_NORMAL || + ( lostFlag == FLAG_DECODE_LBRR && channel_state[ 0 ].LBRR_flags[ channel_state[ 0 ].nFramesDecoded ] == 1 ) ) + { + silk_stereo_decode_pred( psRangeDec, MS_pred_Q13 ); + /* For LBRR data, decode mid-only flag only if side-channel's LBRR flag is false */ + if( ( lostFlag == FLAG_DECODE_NORMAL && channel_state[ 1 ].VAD_flags[ channel_state[ 0 ].nFramesDecoded ] == 0 ) || + ( lostFlag == FLAG_DECODE_LBRR && channel_state[ 1 ].LBRR_flags[ channel_state[ 0 ].nFramesDecoded ] == 0 ) ) + { + silk_stereo_decode_mid_only( psRangeDec, &decode_only_middle ); + } else { + decode_only_middle = 0; + } + } else { + for( n = 0; n < 2; n++ ) { + MS_pred_Q13[ n ] = psDec->sStereo.pred_prev_Q13[ n ]; + } + } + } + + /* Reset side channel decoder prediction memory for first frame with side coding */ + if( decControl->nChannelsInternal == 2 && decode_only_middle == 0 && psDec->prev_decode_only_middle == 1 ) { + silk_memset( psDec->channel_state[ 1 ].outBuf, 0, sizeof(psDec->channel_state[ 1 ].outBuf) ); + silk_memset( psDec->channel_state[ 1 ].sLPC_Q14_buf, 0, sizeof(psDec->channel_state[ 1 ].sLPC_Q14_buf) ); + psDec->channel_state[ 1 ].lagPrev = 100; + psDec->channel_state[ 1 ].LastGainIndex = 10; + psDec->channel_state[ 1 ].prevSignalType = TYPE_NO_VOICE_ACTIVITY; + psDec->channel_state[ 1 ].first_frame_after_reset = 1; + } + + ALLOC( samplesOut1_tmp_storage, + decControl->nChannelsInternal*( + channel_state[ 0 ].frame_length + 2 ), + opus_int16 ); + samplesOut1_tmp[ 0 ] = samplesOut1_tmp_storage; + samplesOut1_tmp[ 1 ] = samplesOut1_tmp_storage + + channel_state[ 0 ].frame_length + 2; + + if( lostFlag == FLAG_DECODE_NORMAL ) { + has_side = !decode_only_middle; + } else { + has_side = !psDec->prev_decode_only_middle + || (decControl->nChannelsInternal == 2 && lostFlag == FLAG_DECODE_LBRR && channel_state[1].LBRR_flags[ channel_state[1].nFramesDecoded ] == 1 ); + } + /* Call decoder for one frame */ + for( n = 0; n < decControl->nChannelsInternal; n++ ) { + if( n == 0 || has_side ) { + opus_int FrameIndex; + opus_int condCoding; + + FrameIndex = channel_state[ 0 ].nFramesDecoded - n; + /* Use independent coding if no previous frame available */ + if( FrameIndex <= 0 ) { + condCoding = CODE_INDEPENDENTLY; + } else if( lostFlag == FLAG_DECODE_LBRR ) { + condCoding = channel_state[ n ].LBRR_flags[ FrameIndex - 1 ] ? CODE_CONDITIONALLY : CODE_INDEPENDENTLY; + } else if( n > 0 && psDec->prev_decode_only_middle ) { + /* If we skipped a side frame in this packet, we don't + need LTP scaling; the LTP state is well-defined. */ + condCoding = CODE_INDEPENDENTLY_NO_LTP_SCALING; + } else { + condCoding = CODE_CONDITIONALLY; + } + ret += silk_decode_frame( &channel_state[ n ], psRangeDec, &samplesOut1_tmp[ n ][ 2 ], &nSamplesOutDec, lostFlag, condCoding); + } else { + silk_memset( &samplesOut1_tmp[ n ][ 2 ], 0, nSamplesOutDec * sizeof( opus_int16 ) ); + } + channel_state[ n ].nFramesDecoded++; + } + + if( decControl->nChannelsAPI == 2 && decControl->nChannelsInternal == 2 ) { + /* Convert Mid/Side to Left/Right */ + silk_stereo_MS_to_LR( &psDec->sStereo, samplesOut1_tmp[ 0 ], samplesOut1_tmp[ 1 ], MS_pred_Q13, channel_state[ 0 ].fs_kHz, nSamplesOutDec ); + } else { + /* Buffering */ + silk_memcpy( samplesOut1_tmp[ 0 ], psDec->sStereo.sMid, 2 * sizeof( opus_int16 ) ); + silk_memcpy( psDec->sStereo.sMid, &samplesOut1_tmp[ 0 ][ nSamplesOutDec ], 2 * sizeof( opus_int16 ) ); + } + + /* Number of output samples */ + *nSamplesOut = silk_DIV32( nSamplesOutDec * decControl->API_sampleRate, silk_SMULBB( channel_state[ 0 ].fs_kHz, 1000 ) ); + + /* Set up pointers to temp buffers */ + ALLOC( samplesOut2_tmp, + decControl->nChannelsAPI == 2 ? *nSamplesOut : ALLOC_NONE, opus_int16 ); + if( decControl->nChannelsAPI == 2 ) { + resample_out_ptr = samplesOut2_tmp; + } else { + resample_out_ptr = samplesOut; + } + + for( n = 0; n < silk_min( decControl->nChannelsAPI, decControl->nChannelsInternal ); n++ ) { + + /* Resample decoded signal to API_sampleRate */ + ret += silk_resampler( &channel_state[ n ].resampler_state, resample_out_ptr, &samplesOut1_tmp[ n ][ 1 ], nSamplesOutDec ); + + /* Interleave if stereo output and stereo stream */ + if( decControl->nChannelsAPI == 2 ) { + for( i = 0; i < *nSamplesOut; i++ ) { + samplesOut[ n + 2 * i ] = resample_out_ptr[ i ]; + } + } + } + + /* Create two channel output from mono stream */ + if( decControl->nChannelsAPI == 2 && decControl->nChannelsInternal == 1 ) { + if ( stereo_to_mono ){ + /* Resample right channel for newly collapsed stereo just in case + we weren't doing collapsing when switching to mono */ + ret += silk_resampler( &channel_state[ 1 ].resampler_state, resample_out_ptr, &samplesOut1_tmp[ 0 ][ 1 ], nSamplesOutDec ); + + for( i = 0; i < *nSamplesOut; i++ ) { + samplesOut[ 1 + 2 * i ] = resample_out_ptr[ i ]; + } + } else { + for( i = 0; i < *nSamplesOut; i++ ) { + samplesOut[ 1 + 2 * i ] = samplesOut[ 0 + 2 * i ]; + } + } + } + + /* Export pitch lag, measured at 48 kHz sampling rate */ + if( channel_state[ 0 ].prevSignalType == TYPE_VOICED ) { + int mult_tab[ 3 ] = { 6, 4, 3 }; + decControl->prevPitchLag = channel_state[ 0 ].lagPrev * mult_tab[ ( channel_state[ 0 ].fs_kHz - 8 ) >> 2 ]; + } else { + decControl->prevPitchLag = 0; + } + + if( lostFlag == FLAG_PACKET_LOST ) { + /* On packet loss, remove the gain clamping to prevent having the energy "bounce back" + if we lose packets when the energy is going down */ + for ( i = 0; i < psDec->nChannelsInternal; i++ ) + psDec->channel_state[ i ].LastGainIndex = 10; + } else { + psDec->prev_decode_only_middle = decode_only_middle; + } + RESTORE_STACK; + return ret; +} + +#if 0 +/* Getting table of contents for a packet */ +opus_int silk_get_TOC( + const opus_uint8 *payload, /* I Payload data */ + const opus_int nBytesIn, /* I Number of input bytes */ + const opus_int nFramesPerPayload, /* I Number of SILK frames per payload */ + silk_TOC_struct *Silk_TOC /* O Type of content */ +) +{ + opus_int i, flags, ret = SILK_NO_ERROR; + + if( nBytesIn < 1 ) { + return -1; + } + if( nFramesPerPayload < 0 || nFramesPerPayload > 3 ) { + return -1; + } + + silk_memset( Silk_TOC, 0, sizeof( *Silk_TOC ) ); + + /* For stereo, extract the flags for the mid channel */ + flags = silk_RSHIFT( payload[ 0 ], 7 - nFramesPerPayload ) & ( silk_LSHIFT( 1, nFramesPerPayload + 1 ) - 1 ); + + Silk_TOC->inbandFECFlag = flags & 1; + for( i = nFramesPerPayload - 1; i >= 0 ; i-- ) { + flags = silk_RSHIFT( flags, 1 ); + Silk_TOC->VADFlags[ i ] = flags & 1; + Silk_TOC->VADFlag |= flags & 1; + } + + return ret; +} +#endif diff --git a/src/opus-1.1/silk/decode_core.c b/src/opus-1.1/silk/decode_core.c new file mode 100644 index 00000000..a820bf11 --- /dev/null +++ b/src/opus-1.1/silk/decode_core.c @@ -0,0 +1,238 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main.h" +#include "stack_alloc.h" + +/**********************************************************/ +/* Core decoder. Performs inverse NSQ operation LTP + LPC */ +/**********************************************************/ +void silk_decode_core( + silk_decoder_state *psDec, /* I/O Decoder state */ + silk_decoder_control *psDecCtrl, /* I Decoder control */ + opus_int16 xq[], /* O Decoded speech */ + const opus_int pulses[ MAX_FRAME_LENGTH ] /* I Pulse signal */ +) +{ + opus_int i, k, lag = 0, start_idx, sLTP_buf_idx, NLSF_interpolation_flag, signalType; + opus_int16 *A_Q12, *B_Q14, *pxq, A_Q12_tmp[ MAX_LPC_ORDER ]; + VARDECL( opus_int16, sLTP ); + VARDECL( opus_int32, sLTP_Q15 ); + opus_int32 LTP_pred_Q13, LPC_pred_Q10, Gain_Q10, inv_gain_Q31, gain_adj_Q16, rand_seed, offset_Q10; + opus_int32 *pred_lag_ptr, *pexc_Q14, *pres_Q14; + VARDECL( opus_int32, res_Q14 ); + VARDECL( opus_int32, sLPC_Q14 ); + SAVE_STACK; + + silk_assert( psDec->prev_gain_Q16 != 0 ); + + ALLOC( sLTP, psDec->ltp_mem_length, opus_int16 ); + ALLOC( sLTP_Q15, psDec->ltp_mem_length + psDec->frame_length, opus_int32 ); + ALLOC( res_Q14, psDec->subfr_length, opus_int32 ); + ALLOC( sLPC_Q14, psDec->subfr_length + MAX_LPC_ORDER, opus_int32 ); + + offset_Q10 = silk_Quantization_Offsets_Q10[ psDec->indices.signalType >> 1 ][ psDec->indices.quantOffsetType ]; + + if( psDec->indices.NLSFInterpCoef_Q2 < 1 << 2 ) { + NLSF_interpolation_flag = 1; + } else { + NLSF_interpolation_flag = 0; + } + + /* Decode excitation */ + rand_seed = psDec->indices.Seed; + for( i = 0; i < psDec->frame_length; i++ ) { + rand_seed = silk_RAND( rand_seed ); + psDec->exc_Q14[ i ] = silk_LSHIFT( (opus_int32)pulses[ i ], 14 ); + if( psDec->exc_Q14[ i ] > 0 ) { + psDec->exc_Q14[ i ] -= QUANT_LEVEL_ADJUST_Q10 << 4; + } else + if( psDec->exc_Q14[ i ] < 0 ) { + psDec->exc_Q14[ i ] += QUANT_LEVEL_ADJUST_Q10 << 4; + } + psDec->exc_Q14[ i ] += offset_Q10 << 4; + if( rand_seed < 0 ) { + psDec->exc_Q14[ i ] = -psDec->exc_Q14[ i ]; + } + + rand_seed = silk_ADD32_ovflw( rand_seed, pulses[ i ] ); + } + + /* Copy LPC state */ + silk_memcpy( sLPC_Q14, psDec->sLPC_Q14_buf, MAX_LPC_ORDER * sizeof( opus_int32 ) ); + + pexc_Q14 = psDec->exc_Q14; + pxq = xq; + sLTP_buf_idx = psDec->ltp_mem_length; + /* Loop over subframes */ + for( k = 0; k < psDec->nb_subfr; k++ ) { + pres_Q14 = res_Q14; + A_Q12 = psDecCtrl->PredCoef_Q12[ k >> 1 ]; + + /* Preload LPC coeficients to array on stack. Gives small performance gain */ + silk_memcpy( A_Q12_tmp, A_Q12, psDec->LPC_order * sizeof( opus_int16 ) ); + B_Q14 = &psDecCtrl->LTPCoef_Q14[ k * LTP_ORDER ]; + signalType = psDec->indices.signalType; + + Gain_Q10 = silk_RSHIFT( psDecCtrl->Gains_Q16[ k ], 6 ); + inv_gain_Q31 = silk_INVERSE32_varQ( psDecCtrl->Gains_Q16[ k ], 47 ); + + /* Calculate gain adjustment factor */ + if( psDecCtrl->Gains_Q16[ k ] != psDec->prev_gain_Q16 ) { + gain_adj_Q16 = silk_DIV32_varQ( psDec->prev_gain_Q16, psDecCtrl->Gains_Q16[ k ], 16 ); + + /* Scale short term state */ + for( i = 0; i < MAX_LPC_ORDER; i++ ) { + sLPC_Q14[ i ] = silk_SMULWW( gain_adj_Q16, sLPC_Q14[ i ] ); + } + } else { + gain_adj_Q16 = (opus_int32)1 << 16; + } + + /* Save inv_gain */ + silk_assert( inv_gain_Q31 != 0 ); + psDec->prev_gain_Q16 = psDecCtrl->Gains_Q16[ k ]; + + /* Avoid abrupt transition from voiced PLC to unvoiced normal decoding */ + if( psDec->lossCnt && psDec->prevSignalType == TYPE_VOICED && + psDec->indices.signalType != TYPE_VOICED && k < MAX_NB_SUBFR/2 ) { + + silk_memset( B_Q14, 0, LTP_ORDER * sizeof( opus_int16 ) ); + B_Q14[ LTP_ORDER/2 ] = SILK_FIX_CONST( 0.25, 14 ); + + signalType = TYPE_VOICED; + psDecCtrl->pitchL[ k ] = psDec->lagPrev; + } + + if( signalType == TYPE_VOICED ) { + /* Voiced */ + lag = psDecCtrl->pitchL[ k ]; + + /* Re-whitening */ + if( k == 0 || ( k == 2 && NLSF_interpolation_flag ) ) { + /* Rewhiten with new A coefs */ + start_idx = psDec->ltp_mem_length - lag - psDec->LPC_order - LTP_ORDER / 2; + silk_assert( start_idx > 0 ); + + if( k == 2 ) { + silk_memcpy( &psDec->outBuf[ psDec->ltp_mem_length ], xq, 2 * psDec->subfr_length * sizeof( opus_int16 ) ); + } + + silk_LPC_analysis_filter( &sLTP[ start_idx ], &psDec->outBuf[ start_idx + k * psDec->subfr_length ], + A_Q12, psDec->ltp_mem_length - start_idx, psDec->LPC_order ); + + /* After rewhitening the LTP state is unscaled */ + if( k == 0 ) { + /* Do LTP downscaling to reduce inter-packet dependency */ + inv_gain_Q31 = silk_LSHIFT( silk_SMULWB( inv_gain_Q31, psDecCtrl->LTP_scale_Q14 ), 2 ); + } + for( i = 0; i < lag + LTP_ORDER/2; i++ ) { + sLTP_Q15[ sLTP_buf_idx - i - 1 ] = silk_SMULWB( inv_gain_Q31, sLTP[ psDec->ltp_mem_length - i - 1 ] ); + } + } else { + /* Update LTP state when Gain changes */ + if( gain_adj_Q16 != (opus_int32)1 << 16 ) { + for( i = 0; i < lag + LTP_ORDER/2; i++ ) { + sLTP_Q15[ sLTP_buf_idx - i - 1 ] = silk_SMULWW( gain_adj_Q16, sLTP_Q15[ sLTP_buf_idx - i - 1 ] ); + } + } + } + } + + /* Long-term prediction */ + if( signalType == TYPE_VOICED ) { + /* Set up pointer */ + pred_lag_ptr = &sLTP_Q15[ sLTP_buf_idx - lag + LTP_ORDER / 2 ]; + for( i = 0; i < psDec->subfr_length; i++ ) { + /* Unrolled loop */ + /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ + LTP_pred_Q13 = 2; + LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ 0 ], B_Q14[ 0 ] ); + LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -1 ], B_Q14[ 1 ] ); + LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -2 ], B_Q14[ 2 ] ); + LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -3 ], B_Q14[ 3 ] ); + LTP_pred_Q13 = silk_SMLAWB( LTP_pred_Q13, pred_lag_ptr[ -4 ], B_Q14[ 4 ] ); + pred_lag_ptr++; + + /* Generate LPC excitation */ + pres_Q14[ i ] = silk_ADD_LSHIFT32( pexc_Q14[ i ], LTP_pred_Q13, 1 ); + + /* Update states */ + sLTP_Q15[ sLTP_buf_idx ] = silk_LSHIFT( pres_Q14[ i ], 1 ); + sLTP_buf_idx++; + } + } else { + pres_Q14 = pexc_Q14; + } + + for( i = 0; i < psDec->subfr_length; i++ ) { + /* Short-term prediction */ + silk_assert( psDec->LPC_order == 10 || psDec->LPC_order == 16 ); + /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */ + LPC_pred_Q10 = silk_RSHIFT( psDec->LPC_order, 1 ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 1 ], A_Q12_tmp[ 0 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 2 ], A_Q12_tmp[ 1 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 3 ], A_Q12_tmp[ 2 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 4 ], A_Q12_tmp[ 3 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 5 ], A_Q12_tmp[ 4 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 6 ], A_Q12_tmp[ 5 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 7 ], A_Q12_tmp[ 6 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 8 ], A_Q12_tmp[ 7 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 9 ], A_Q12_tmp[ 8 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 10 ], A_Q12_tmp[ 9 ] ); + if( psDec->LPC_order == 16 ) { + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 11 ], A_Q12_tmp[ 10 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 12 ], A_Q12_tmp[ 11 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 13 ], A_Q12_tmp[ 12 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 14 ], A_Q12_tmp[ 13 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 15 ], A_Q12_tmp[ 14 ] ); + LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, sLPC_Q14[ MAX_LPC_ORDER + i - 16 ], A_Q12_tmp[ 15 ] ); + } + + /* Add prediction to LPC excitation */ + sLPC_Q14[ MAX_LPC_ORDER + i ] = silk_ADD_LSHIFT32( pres_Q14[ i ], LPC_pred_Q10, 4 ); + + /* Scale with gain */ + pxq[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( sLPC_Q14[ MAX_LPC_ORDER + i ], Gain_Q10 ), 8 ) ); + } + + /* DEBUG_STORE_DATA( dec.pcm, pxq, psDec->subfr_length * sizeof( opus_int16 ) ) */ + + /* Update LPC filter state */ + silk_memcpy( sLPC_Q14, &sLPC_Q14[ psDec->subfr_length ], MAX_LPC_ORDER * sizeof( opus_int32 ) ); + pexc_Q14 += psDec->subfr_length; + pxq += psDec->subfr_length; + } + + /* Save LPC state */ + silk_memcpy( psDec->sLPC_Q14_buf, sLPC_Q14, MAX_LPC_ORDER * sizeof( opus_int32 ) ); + RESTORE_STACK; +} diff --git a/src/opus-1.1/silk/decode_frame.c b/src/opus-1.1/silk/decode_frame.c new file mode 100644 index 00000000..abc00a3d --- /dev/null +++ b/src/opus-1.1/silk/decode_frame.c @@ -0,0 +1,128 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main.h" +#include "stack_alloc.h" +#include "PLC.h" + +/****************/ +/* Decode frame */ +/****************/ +opus_int silk_decode_frame( + silk_decoder_state *psDec, /* I/O Pointer to Silk decoder state */ + ec_dec *psRangeDec, /* I/O Compressor data structure */ + opus_int16 pOut[], /* O Pointer to output speech frame */ + opus_int32 *pN, /* O Pointer to size of output frame */ + opus_int lostFlag, /* I 0: no loss, 1 loss, 2 decode fec */ + opus_int condCoding /* I The type of conditional coding to use */ +) +{ + VARDECL( silk_decoder_control, psDecCtrl ); + opus_int L, mv_len, ret = 0; + VARDECL( opus_int, pulses ); + SAVE_STACK; + + L = psDec->frame_length; + ALLOC( psDecCtrl, 1, silk_decoder_control ); + ALLOC( pulses, (L + SHELL_CODEC_FRAME_LENGTH - 1) & + ~(SHELL_CODEC_FRAME_LENGTH - 1), opus_int ); + psDecCtrl->LTP_scale_Q14 = 0; + + /* Safety checks */ + silk_assert( L > 0 && L <= MAX_FRAME_LENGTH ); + + if( lostFlag == FLAG_DECODE_NORMAL || + ( lostFlag == FLAG_DECODE_LBRR && psDec->LBRR_flags[ psDec->nFramesDecoded ] == 1 ) ) + { + /*********************************************/ + /* Decode quantization indices of side info */ + /*********************************************/ + silk_decode_indices( psDec, psRangeDec, psDec->nFramesDecoded, lostFlag, condCoding ); + + /*********************************************/ + /* Decode quantization indices of excitation */ + /*********************************************/ + silk_decode_pulses( psRangeDec, pulses, psDec->indices.signalType, + psDec->indices.quantOffsetType, psDec->frame_length ); + + /********************************************/ + /* Decode parameters and pulse signal */ + /********************************************/ + silk_decode_parameters( psDec, psDecCtrl, condCoding ); + + /********************************************************/ + /* Run inverse NSQ */ + /********************************************************/ + silk_decode_core( psDec, psDecCtrl, pOut, pulses ); + + /********************************************************/ + /* Update PLC state */ + /********************************************************/ + silk_PLC( psDec, psDecCtrl, pOut, 0 ); + + psDec->lossCnt = 0; + psDec->prevSignalType = psDec->indices.signalType; + silk_assert( psDec->prevSignalType >= 0 && psDec->prevSignalType <= 2 ); + + /* A frame has been decoded without errors */ + psDec->first_frame_after_reset = 0; + } else { + /* Handle packet loss by extrapolation */ + silk_PLC( psDec, psDecCtrl, pOut, 1 ); + } + + /*************************/ + /* Update output buffer. */ + /*************************/ + silk_assert( psDec->ltp_mem_length >= psDec->frame_length ); + mv_len = psDec->ltp_mem_length - psDec->frame_length; + silk_memmove( psDec->outBuf, &psDec->outBuf[ psDec->frame_length ], mv_len * sizeof(opus_int16) ); + silk_memcpy( &psDec->outBuf[ mv_len ], pOut, psDec->frame_length * sizeof( opus_int16 ) ); + + /****************************************************************/ + /* Ensure smooth connection of extrapolated and good frames */ + /****************************************************************/ + silk_PLC_glue_frames( psDec, pOut, L ); + + /************************************************/ + /* Comfort noise generation / estimation */ + /************************************************/ + silk_CNG( psDec, psDecCtrl, pOut, L ); + + /* Update some decoder state variables */ + psDec->lagPrev = psDecCtrl->pitchL[ psDec->nb_subfr - 1 ]; + + /* Set output frame length */ + *pN = L; + + RESTORE_STACK; + return ret; +} diff --git a/src/opus-1.1/silk/decode_indices.c b/src/opus-1.1/silk/decode_indices.c new file mode 100644 index 00000000..7afe5c26 --- /dev/null +++ b/src/opus-1.1/silk/decode_indices.c @@ -0,0 +1,151 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main.h" + +/* Decode side-information parameters from payload */ +void silk_decode_indices( + silk_decoder_state *psDec, /* I/O State */ + ec_dec *psRangeDec, /* I/O Compressor data structure */ + opus_int FrameIndex, /* I Frame number */ + opus_int decode_LBRR, /* I Flag indicating LBRR data is being decoded */ + opus_int condCoding /* I The type of conditional coding to use */ +) +{ + opus_int i, k, Ix; + opus_int decode_absolute_lagIndex, delta_lagIndex; + opus_int16 ec_ix[ MAX_LPC_ORDER ]; + opus_uint8 pred_Q8[ MAX_LPC_ORDER ]; + + /*******************************************/ + /* Decode signal type and quantizer offset */ + /*******************************************/ + if( decode_LBRR || psDec->VAD_flags[ FrameIndex ] ) { + Ix = ec_dec_icdf( psRangeDec, silk_type_offset_VAD_iCDF, 8 ) + 2; + } else { + Ix = ec_dec_icdf( psRangeDec, silk_type_offset_no_VAD_iCDF, 8 ); + } + psDec->indices.signalType = (opus_int8)silk_RSHIFT( Ix, 1 ); + psDec->indices.quantOffsetType = (opus_int8)( Ix & 1 ); + + /****************/ + /* Decode gains */ + /****************/ + /* First subframe */ + if( condCoding == CODE_CONDITIONALLY ) { + /* Conditional coding */ + psDec->indices.GainsIndices[ 0 ] = (opus_int8)ec_dec_icdf( psRangeDec, silk_delta_gain_iCDF, 8 ); + } else { + /* Independent coding, in two stages: MSB bits followed by 3 LSBs */ + psDec->indices.GainsIndices[ 0 ] = (opus_int8)silk_LSHIFT( ec_dec_icdf( psRangeDec, silk_gain_iCDF[ psDec->indices.signalType ], 8 ), 3 ); + psDec->indices.GainsIndices[ 0 ] += (opus_int8)ec_dec_icdf( psRangeDec, silk_uniform8_iCDF, 8 ); + } + + /* Remaining subframes */ + for( i = 1; i < psDec->nb_subfr; i++ ) { + psDec->indices.GainsIndices[ i ] = (opus_int8)ec_dec_icdf( psRangeDec, silk_delta_gain_iCDF, 8 ); + } + + /**********************/ + /* Decode LSF Indices */ + /**********************/ + psDec->indices.NLSFIndices[ 0 ] = (opus_int8)ec_dec_icdf( psRangeDec, &psDec->psNLSF_CB->CB1_iCDF[ ( psDec->indices.signalType >> 1 ) * psDec->psNLSF_CB->nVectors ], 8 ); + silk_NLSF_unpack( ec_ix, pred_Q8, psDec->psNLSF_CB, psDec->indices.NLSFIndices[ 0 ] ); + silk_assert( psDec->psNLSF_CB->order == psDec->LPC_order ); + for( i = 0; i < psDec->psNLSF_CB->order; i++ ) { + Ix = ec_dec_icdf( psRangeDec, &psDec->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 ); + if( Ix == 0 ) { + Ix -= ec_dec_icdf( psRangeDec, silk_NLSF_EXT_iCDF, 8 ); + } else if( Ix == 2 * NLSF_QUANT_MAX_AMPLITUDE ) { + Ix += ec_dec_icdf( psRangeDec, silk_NLSF_EXT_iCDF, 8 ); + } + psDec->indices.NLSFIndices[ i+1 ] = (opus_int8)( Ix - NLSF_QUANT_MAX_AMPLITUDE ); + } + + /* Decode LSF interpolation factor */ + if( psDec->nb_subfr == MAX_NB_SUBFR ) { + psDec->indices.NLSFInterpCoef_Q2 = (opus_int8)ec_dec_icdf( psRangeDec, silk_NLSF_interpolation_factor_iCDF, 8 ); + } else { + psDec->indices.NLSFInterpCoef_Q2 = 4; + } + + if( psDec->indices.signalType == TYPE_VOICED ) + { + /*********************/ + /* Decode pitch lags */ + /*********************/ + /* Get lag index */ + decode_absolute_lagIndex = 1; + if( condCoding == CODE_CONDITIONALLY && psDec->ec_prevSignalType == TYPE_VOICED ) { + /* Decode Delta index */ + delta_lagIndex = (opus_int16)ec_dec_icdf( psRangeDec, silk_pitch_delta_iCDF, 8 ); + if( delta_lagIndex > 0 ) { + delta_lagIndex = delta_lagIndex - 9; + psDec->indices.lagIndex = (opus_int16)( psDec->ec_prevLagIndex + delta_lagIndex ); + decode_absolute_lagIndex = 0; + } + } + if( decode_absolute_lagIndex ) { + /* Absolute decoding */ + psDec->indices.lagIndex = (opus_int16)ec_dec_icdf( psRangeDec, silk_pitch_lag_iCDF, 8 ) * silk_RSHIFT( psDec->fs_kHz, 1 ); + psDec->indices.lagIndex += (opus_int16)ec_dec_icdf( psRangeDec, psDec->pitch_lag_low_bits_iCDF, 8 ); + } + psDec->ec_prevLagIndex = psDec->indices.lagIndex; + + /* Get countour index */ + psDec->indices.contourIndex = (opus_int8)ec_dec_icdf( psRangeDec, psDec->pitch_contour_iCDF, 8 ); + + /********************/ + /* Decode LTP gains */ + /********************/ + /* Decode PERIndex value */ + psDec->indices.PERIndex = (opus_int8)ec_dec_icdf( psRangeDec, silk_LTP_per_index_iCDF, 8 ); + + for( k = 0; k < psDec->nb_subfr; k++ ) { + psDec->indices.LTPIndex[ k ] = (opus_int8)ec_dec_icdf( psRangeDec, silk_LTP_gain_iCDF_ptrs[ psDec->indices.PERIndex ], 8 ); + } + + /**********************/ + /* Decode LTP scaling */ + /**********************/ + if( condCoding == CODE_INDEPENDENTLY ) { + psDec->indices.LTP_scaleIndex = (opus_int8)ec_dec_icdf( psRangeDec, silk_LTPscale_iCDF, 8 ); + } else { + psDec->indices.LTP_scaleIndex = 0; + } + } + psDec->ec_prevSignalType = psDec->indices.signalType; + + /***************/ + /* Decode seed */ + /***************/ + psDec->indices.Seed = (opus_int8)ec_dec_icdf( psRangeDec, silk_uniform4_iCDF, 8 ); +} diff --git a/src/opus-1.1/silk/decode_parameters.c b/src/opus-1.1/silk/decode_parameters.c new file mode 100644 index 00000000..e345b1dc --- /dev/null +++ b/src/opus-1.1/silk/decode_parameters.c @@ -0,0 +1,115 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main.h" + +/* Decode parameters from payload */ +void silk_decode_parameters( + silk_decoder_state *psDec, /* I/O State */ + silk_decoder_control *psDecCtrl, /* I/O Decoder control */ + opus_int condCoding /* I The type of conditional coding to use */ +) +{ + opus_int i, k, Ix; + opus_int16 pNLSF_Q15[ MAX_LPC_ORDER ], pNLSF0_Q15[ MAX_LPC_ORDER ]; + const opus_int8 *cbk_ptr_Q7; + + /* Dequant Gains */ + silk_gains_dequant( psDecCtrl->Gains_Q16, psDec->indices.GainsIndices, + &psDec->LastGainIndex, condCoding == CODE_CONDITIONALLY, psDec->nb_subfr ); + + /****************/ + /* Decode NLSFs */ + /****************/ + silk_NLSF_decode( pNLSF_Q15, psDec->indices.NLSFIndices, psDec->psNLSF_CB ); + + /* Convert NLSF parameters to AR prediction filter coefficients */ + silk_NLSF2A( psDecCtrl->PredCoef_Q12[ 1 ], pNLSF_Q15, psDec->LPC_order ); + + /* If just reset, e.g., because internal Fs changed, do not allow interpolation */ + /* improves the case of packet loss in the first frame after a switch */ + if( psDec->first_frame_after_reset == 1 ) { + psDec->indices.NLSFInterpCoef_Q2 = 4; + } + + if( psDec->indices.NLSFInterpCoef_Q2 < 4 ) { + /* Calculation of the interpolated NLSF0 vector from the interpolation factor, */ + /* the previous NLSF1, and the current NLSF1 */ + for( i = 0; i < psDec->LPC_order; i++ ) { + pNLSF0_Q15[ i ] = psDec->prevNLSF_Q15[ i ] + silk_RSHIFT( silk_MUL( psDec->indices.NLSFInterpCoef_Q2, + pNLSF_Q15[ i ] - psDec->prevNLSF_Q15[ i ] ), 2 ); + } + + /* Convert NLSF parameters to AR prediction filter coefficients */ + silk_NLSF2A( psDecCtrl->PredCoef_Q12[ 0 ], pNLSF0_Q15, psDec->LPC_order ); + } else { + /* Copy LPC coefficients for first half from second half */ + silk_memcpy( psDecCtrl->PredCoef_Q12[ 0 ], psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order * sizeof( opus_int16 ) ); + } + + silk_memcpy( psDec->prevNLSF_Q15, pNLSF_Q15, psDec->LPC_order * sizeof( opus_int16 ) ); + + /* After a packet loss do BWE of LPC coefs */ + if( psDec->lossCnt ) { + silk_bwexpander( psDecCtrl->PredCoef_Q12[ 0 ], psDec->LPC_order, BWE_AFTER_LOSS_Q16 ); + silk_bwexpander( psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order, BWE_AFTER_LOSS_Q16 ); + } + + if( psDec->indices.signalType == TYPE_VOICED ) { + /*********************/ + /* Decode pitch lags */ + /*********************/ + + /* Decode pitch values */ + silk_decode_pitch( psDec->indices.lagIndex, psDec->indices.contourIndex, psDecCtrl->pitchL, psDec->fs_kHz, psDec->nb_subfr ); + + /* Decode Codebook Index */ + cbk_ptr_Q7 = silk_LTP_vq_ptrs_Q7[ psDec->indices.PERIndex ]; /* set pointer to start of codebook */ + + for( k = 0; k < psDec->nb_subfr; k++ ) { + Ix = psDec->indices.LTPIndex[ k ]; + for( i = 0; i < LTP_ORDER; i++ ) { + psDecCtrl->LTPCoef_Q14[ k * LTP_ORDER + i ] = silk_LSHIFT( cbk_ptr_Q7[ Ix * LTP_ORDER + i ], 7 ); + } + } + + /**********************/ + /* Decode LTP scaling */ + /**********************/ + Ix = psDec->indices.LTP_scaleIndex; + psDecCtrl->LTP_scale_Q14 = silk_LTPScales_table_Q14[ Ix ]; + } else { + silk_memset( psDecCtrl->pitchL, 0, psDec->nb_subfr * sizeof( opus_int ) ); + silk_memset( psDecCtrl->LTPCoef_Q14, 0, LTP_ORDER * psDec->nb_subfr * sizeof( opus_int16 ) ); + psDec->indices.PERIndex = 0; + psDecCtrl->LTP_scale_Q14 = 0; + } +} diff --git a/src/opus-1.1/silk/decode_pitch.c b/src/opus-1.1/silk/decode_pitch.c new file mode 100644 index 00000000..fedbc6a5 --- /dev/null +++ b/src/opus-1.1/silk/decode_pitch.c @@ -0,0 +1,77 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/*********************************************************** +* Pitch analyser function +********************************************************** */ +#include "SigProc_FIX.h" +#include "pitch_est_defines.h" + +void silk_decode_pitch( + opus_int16 lagIndex, /* I */ + opus_int8 contourIndex, /* O */ + opus_int pitch_lags[], /* O 4 pitch values */ + const opus_int Fs_kHz, /* I sampling frequency (kHz) */ + const opus_int nb_subfr /* I number of sub frames */ +) +{ + opus_int lag, k, min_lag, max_lag, cbk_size; + const opus_int8 *Lag_CB_ptr; + + if( Fs_kHz == 8 ) { + if( nb_subfr == PE_MAX_NB_SUBFR ) { + Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ]; + cbk_size = PE_NB_CBKS_STAGE2_EXT; + } else { + silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1 ); + Lag_CB_ptr = &silk_CB_lags_stage2_10_ms[ 0 ][ 0 ]; + cbk_size = PE_NB_CBKS_STAGE2_10MS; + } + } else { + if( nb_subfr == PE_MAX_NB_SUBFR ) { + Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ]; + cbk_size = PE_NB_CBKS_STAGE3_MAX; + } else { + silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1 ); + Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ]; + cbk_size = PE_NB_CBKS_STAGE3_10MS; + } + } + + min_lag = silk_SMULBB( PE_MIN_LAG_MS, Fs_kHz ); + max_lag = silk_SMULBB( PE_MAX_LAG_MS, Fs_kHz ); + lag = min_lag + lagIndex; + + for( k = 0; k < nb_subfr; k++ ) { + pitch_lags[ k ] = lag + matrix_ptr( Lag_CB_ptr, k, contourIndex, cbk_size ); + pitch_lags[ k ] = silk_LIMIT( pitch_lags[ k ], min_lag, max_lag ); + } +} diff --git a/src/opus-1.1/silk/decode_pulses.c b/src/opus-1.1/silk/decode_pulses.c new file mode 100644 index 00000000..e8a87c2a --- /dev/null +++ b/src/opus-1.1/silk/decode_pulses.c @@ -0,0 +1,115 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main.h" + +/*********************************************/ +/* Decode quantization indices of excitation */ +/*********************************************/ +void silk_decode_pulses( + ec_dec *psRangeDec, /* I/O Compressor data structure */ + opus_int pulses[], /* O Excitation signal */ + const opus_int signalType, /* I Sigtype */ + const opus_int quantOffsetType, /* I quantOffsetType */ + const opus_int frame_length /* I Frame length */ +) +{ + opus_int i, j, k, iter, abs_q, nLS, RateLevelIndex; + opus_int sum_pulses[ MAX_NB_SHELL_BLOCKS ], nLshifts[ MAX_NB_SHELL_BLOCKS ]; + opus_int *pulses_ptr; + const opus_uint8 *cdf_ptr; + + /*********************/ + /* Decode rate level */ + /*********************/ + RateLevelIndex = ec_dec_icdf( psRangeDec, silk_rate_levels_iCDF[ signalType >> 1 ], 8 ); + + /* Calculate number of shell blocks */ + silk_assert( 1 << LOG2_SHELL_CODEC_FRAME_LENGTH == SHELL_CODEC_FRAME_LENGTH ); + iter = silk_RSHIFT( frame_length, LOG2_SHELL_CODEC_FRAME_LENGTH ); + if( iter * SHELL_CODEC_FRAME_LENGTH < frame_length ) { + silk_assert( frame_length == 12 * 10 ); /* Make sure only happens for 10 ms @ 12 kHz */ + iter++; + } + + /***************************************************/ + /* Sum-Weighted-Pulses Decoding */ + /***************************************************/ + cdf_ptr = silk_pulses_per_block_iCDF[ RateLevelIndex ]; + for( i = 0; i < iter; i++ ) { + nLshifts[ i ] = 0; + sum_pulses[ i ] = ec_dec_icdf( psRangeDec, cdf_ptr, 8 ); + + /* LSB indication */ + while( sum_pulses[ i ] == MAX_PULSES + 1 ) { + nLshifts[ i ]++; + /* When we've already got 10 LSBs, we shift the table to not allow (MAX_PULSES + 1) */ + sum_pulses[ i ] = ec_dec_icdf( psRangeDec, + silk_pulses_per_block_iCDF[ N_RATE_LEVELS - 1] + ( nLshifts[ i ] == 10 ), 8 ); + } + } + + /***************************************************/ + /* Shell decoding */ + /***************************************************/ + for( i = 0; i < iter; i++ ) { + if( sum_pulses[ i ] > 0 ) { + silk_shell_decoder( &pulses[ silk_SMULBB( i, SHELL_CODEC_FRAME_LENGTH ) ], psRangeDec, sum_pulses[ i ] ); + } else { + silk_memset( &pulses[ silk_SMULBB( i, SHELL_CODEC_FRAME_LENGTH ) ], 0, SHELL_CODEC_FRAME_LENGTH * sizeof( opus_int ) ); + } + } + + /***************************************************/ + /* LSB Decoding */ + /***************************************************/ + for( i = 0; i < iter; i++ ) { + if( nLshifts[ i ] > 0 ) { + nLS = nLshifts[ i ]; + pulses_ptr = &pulses[ silk_SMULBB( i, SHELL_CODEC_FRAME_LENGTH ) ]; + for( k = 0; k < SHELL_CODEC_FRAME_LENGTH; k++ ) { + abs_q = pulses_ptr[ k ]; + for( j = 0; j < nLS; j++ ) { + abs_q = silk_LSHIFT( abs_q, 1 ); + abs_q += ec_dec_icdf( psRangeDec, silk_lsb_iCDF, 8 ); + } + pulses_ptr[ k ] = abs_q; + } + /* Mark the number of pulses non-zero for sign decoding. */ + sum_pulses[ i ] |= nLS << 5; + } + } + + /****************************************/ + /* Decode and add signs to pulse signal */ + /****************************************/ + silk_decode_signs( psRangeDec, pulses, frame_length, signalType, quantOffsetType, sum_pulses ); +} diff --git a/src/opus-1.1/silk/decoder_set_fs.c b/src/opus-1.1/silk/decoder_set_fs.c new file mode 100644 index 00000000..eef0fd25 --- /dev/null +++ b/src/opus-1.1/silk/decoder_set_fs.c @@ -0,0 +1,108 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main.h" + +/* Set decoder sampling rate */ +opus_int silk_decoder_set_fs( + silk_decoder_state *psDec, /* I/O Decoder state pointer */ + opus_int fs_kHz, /* I Sampling frequency (kHz) */ + opus_int32 fs_API_Hz /* I API Sampling frequency (Hz) */ +) +{ + opus_int frame_length, ret = 0; + + silk_assert( fs_kHz == 8 || fs_kHz == 12 || fs_kHz == 16 ); + silk_assert( psDec->nb_subfr == MAX_NB_SUBFR || psDec->nb_subfr == MAX_NB_SUBFR/2 ); + + /* New (sub)frame length */ + psDec->subfr_length = silk_SMULBB( SUB_FRAME_LENGTH_MS, fs_kHz ); + frame_length = silk_SMULBB( psDec->nb_subfr, psDec->subfr_length ); + + /* Initialize resampler when switching internal or external sampling frequency */ + if( psDec->fs_kHz != fs_kHz || psDec->fs_API_hz != fs_API_Hz ) { + /* Initialize the resampler for dec_API.c preparing resampling from fs_kHz to API_fs_Hz */ + ret += silk_resampler_init( &psDec->resampler_state, silk_SMULBB( fs_kHz, 1000 ), fs_API_Hz, 0 ); + + psDec->fs_API_hz = fs_API_Hz; + } + + if( psDec->fs_kHz != fs_kHz || frame_length != psDec->frame_length ) { + if( fs_kHz == 8 ) { + if( psDec->nb_subfr == MAX_NB_SUBFR ) { + psDec->pitch_contour_iCDF = silk_pitch_contour_NB_iCDF; + } else { + psDec->pitch_contour_iCDF = silk_pitch_contour_10_ms_NB_iCDF; + } + } else { + if( psDec->nb_subfr == MAX_NB_SUBFR ) { + psDec->pitch_contour_iCDF = silk_pitch_contour_iCDF; + } else { + psDec->pitch_contour_iCDF = silk_pitch_contour_10_ms_iCDF; + } + } + if( psDec->fs_kHz != fs_kHz ) { + psDec->ltp_mem_length = silk_SMULBB( LTP_MEM_LENGTH_MS, fs_kHz ); + if( fs_kHz == 8 || fs_kHz == 12 ) { + psDec->LPC_order = MIN_LPC_ORDER; + psDec->psNLSF_CB = &silk_NLSF_CB_NB_MB; + } else { + psDec->LPC_order = MAX_LPC_ORDER; + psDec->psNLSF_CB = &silk_NLSF_CB_WB; + } + if( fs_kHz == 16 ) { + psDec->pitch_lag_low_bits_iCDF = silk_uniform8_iCDF; + } else if( fs_kHz == 12 ) { + psDec->pitch_lag_low_bits_iCDF = silk_uniform6_iCDF; + } else if( fs_kHz == 8 ) { + psDec->pitch_lag_low_bits_iCDF = silk_uniform4_iCDF; + } else { + /* unsupported sampling rate */ + silk_assert( 0 ); + } + psDec->first_frame_after_reset = 1; + psDec->lagPrev = 100; + psDec->LastGainIndex = 10; + psDec->prevSignalType = TYPE_NO_VOICE_ACTIVITY; + silk_memset( psDec->outBuf, 0, sizeof(psDec->outBuf)); + silk_memset( psDec->sLPC_Q14_buf, 0, sizeof(psDec->sLPC_Q14_buf) ); + } + + psDec->fs_kHz = fs_kHz; + psDec->frame_length = frame_length; + } + + /* Check that settings are valid */ + silk_assert( psDec->frame_length > 0 && psDec->frame_length <= MAX_FRAME_LENGTH ); + + return ret; +} + diff --git a/src/opus-1.1/silk/define.h b/src/opus-1.1/silk/define.h new file mode 100644 index 00000000..c47aca9f --- /dev/null +++ b/src/opus-1.1/silk/define.h @@ -0,0 +1,235 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifndef SILK_DEFINE_H +#define SILK_DEFINE_H + +#include "errors.h" +#include "typedef.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Max number of encoder channels (1/2) */ +#define ENCODER_NUM_CHANNELS 2 +/* Number of decoder channels (1/2) */ +#define DECODER_NUM_CHANNELS 2 + +#define MAX_FRAMES_PER_PACKET 3 + +/* Limits on bitrate */ +#define MIN_TARGET_RATE_BPS 5000 +#define MAX_TARGET_RATE_BPS 80000 +#define TARGET_RATE_TAB_SZ 8 + +/* LBRR thresholds */ +#define LBRR_NB_MIN_RATE_BPS 12000 +#define LBRR_MB_MIN_RATE_BPS 14000 +#define LBRR_WB_MIN_RATE_BPS 16000 + +/* DTX settings */ +#define NB_SPEECH_FRAMES_BEFORE_DTX 10 /* eq 200 ms */ +#define MAX_CONSECUTIVE_DTX 20 /* eq 400 ms */ + +/* Maximum sampling frequency */ +#define MAX_FS_KHZ 16 +#define MAX_API_FS_KHZ 48 + +/* Signal types */ +#define TYPE_NO_VOICE_ACTIVITY 0 +#define TYPE_UNVOICED 1 +#define TYPE_VOICED 2 + +/* Conditional coding types */ +#define CODE_INDEPENDENTLY 0 +#define CODE_INDEPENDENTLY_NO_LTP_SCALING 1 +#define CODE_CONDITIONALLY 2 + +/* Settings for stereo processing */ +#define STEREO_QUANT_TAB_SIZE 16 +#define STEREO_QUANT_SUB_STEPS 5 +#define STEREO_INTERP_LEN_MS 8 /* must be even */ +#define STEREO_RATIO_SMOOTH_COEF 0.01 /* smoothing coef for signal norms and stereo width */ + +/* Range of pitch lag estimates */ +#define PITCH_EST_MIN_LAG_MS 2 /* 2 ms -> 500 Hz */ +#define PITCH_EST_MAX_LAG_MS 18 /* 18 ms -> 56 Hz */ + +/* Maximum number of subframes */ +#define MAX_NB_SUBFR 4 + +/* Number of samples per frame */ +#define LTP_MEM_LENGTH_MS 20 +#define SUB_FRAME_LENGTH_MS 5 +#define MAX_SUB_FRAME_LENGTH ( SUB_FRAME_LENGTH_MS * MAX_FS_KHZ ) +#define MAX_FRAME_LENGTH_MS ( SUB_FRAME_LENGTH_MS * MAX_NB_SUBFR ) +#define MAX_FRAME_LENGTH ( MAX_FRAME_LENGTH_MS * MAX_FS_KHZ ) + +/* Milliseconds of lookahead for pitch analysis */ +#define LA_PITCH_MS 2 +#define LA_PITCH_MAX ( LA_PITCH_MS * MAX_FS_KHZ ) + +/* Order of LPC used in find pitch */ +#define MAX_FIND_PITCH_LPC_ORDER 16 + +/* Length of LPC window used in find pitch */ +#define FIND_PITCH_LPC_WIN_MS ( 20 + (LA_PITCH_MS << 1) ) +#define FIND_PITCH_LPC_WIN_MS_2_SF ( 10 + (LA_PITCH_MS << 1) ) +#define FIND_PITCH_LPC_WIN_MAX ( FIND_PITCH_LPC_WIN_MS * MAX_FS_KHZ ) + +/* Milliseconds of lookahead for noise shape analysis */ +#define LA_SHAPE_MS 5 +#define LA_SHAPE_MAX ( LA_SHAPE_MS * MAX_FS_KHZ ) + +/* Maximum length of LPC window used in noise shape analysis */ +#define SHAPE_LPC_WIN_MAX ( 15 * MAX_FS_KHZ ) + +/* dB level of lowest gain quantization level */ +#define MIN_QGAIN_DB 2 +/* dB level of highest gain quantization level */ +#define MAX_QGAIN_DB 88 +/* Number of gain quantization levels */ +#define N_LEVELS_QGAIN 64 +/* Max increase in gain quantization index */ +#define MAX_DELTA_GAIN_QUANT 36 +/* Max decrease in gain quantization index */ +#define MIN_DELTA_GAIN_QUANT -4 + +/* Quantization offsets (multiples of 4) */ +#define OFFSET_VL_Q10 32 +#define OFFSET_VH_Q10 100 +#define OFFSET_UVL_Q10 100 +#define OFFSET_UVH_Q10 240 + +#define QUANT_LEVEL_ADJUST_Q10 80 + +/* Maximum numbers of iterations used to stabilize an LPC vector */ +#define MAX_LPC_STABILIZE_ITERATIONS 16 +#define MAX_PREDICTION_POWER_GAIN 1e4f +#define MAX_PREDICTION_POWER_GAIN_AFTER_RESET 1e2f + +#define MAX_LPC_ORDER 16 +#define MIN_LPC_ORDER 10 + +/* Find Pred Coef defines */ +#define LTP_ORDER 5 + +/* LTP quantization settings */ +#define NB_LTP_CBKS 3 + +/* Flag to use harmonic noise shaping */ +#define USE_HARM_SHAPING 1 + +/* Max LPC order of noise shaping filters */ +#define MAX_SHAPE_LPC_ORDER 16 + +#define HARM_SHAPE_FIR_TAPS 3 + +/* Maximum number of delayed decision states */ +#define MAX_DEL_DEC_STATES 4 + +#define LTP_BUF_LENGTH 512 +#define LTP_MASK ( LTP_BUF_LENGTH - 1 ) + +#define DECISION_DELAY 32 +#define DECISION_DELAY_MASK ( DECISION_DELAY - 1 ) + +/* Number of subframes for excitation entropy coding */ +#define SHELL_CODEC_FRAME_LENGTH 16 +#define LOG2_SHELL_CODEC_FRAME_LENGTH 4 +#define MAX_NB_SHELL_BLOCKS ( MAX_FRAME_LENGTH / SHELL_CODEC_FRAME_LENGTH ) + +/* Number of rate levels, for entropy coding of excitation */ +#define N_RATE_LEVELS 10 + +/* Maximum sum of pulses per shell coding frame */ +#define MAX_PULSES 16 + +#define MAX_MATRIX_SIZE MAX_LPC_ORDER /* Max of LPC Order and LTP order */ + +#if( MAX_LPC_ORDER > DECISION_DELAY ) +# define NSQ_LPC_BUF_LENGTH MAX_LPC_ORDER +#else +# define NSQ_LPC_BUF_LENGTH DECISION_DELAY +#endif + +/***************************/ +/* Voice activity detector */ +/***************************/ +#define VAD_N_BANDS 4 + +#define VAD_INTERNAL_SUBFRAMES_LOG2 2 +#define VAD_INTERNAL_SUBFRAMES ( 1 << VAD_INTERNAL_SUBFRAMES_LOG2 ) + +#define VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 1024 /* Must be < 4096 */ +#define VAD_NOISE_LEVELS_BIAS 50 + +/* Sigmoid settings */ +#define VAD_NEGATIVE_OFFSET_Q5 128 /* sigmoid is 0 at -128 */ +#define VAD_SNR_FACTOR_Q16 45000 + +/* smoothing for SNR measurement */ +#define VAD_SNR_SMOOTH_COEF_Q18 4096 + +/* Size of the piecewise linear cosine approximation table for the LSFs */ +#define LSF_COS_TAB_SZ_FIX 128 + +/******************/ +/* NLSF quantizer */ +/******************/ +#define NLSF_W_Q 2 +#define NLSF_VQ_MAX_VECTORS 32 +#define NLSF_VQ_MAX_SURVIVORS 32 +#define NLSF_QUANT_MAX_AMPLITUDE 4 +#define NLSF_QUANT_MAX_AMPLITUDE_EXT 10 +#define NLSF_QUANT_LEVEL_ADJ 0.1 +#define NLSF_QUANT_DEL_DEC_STATES_LOG2 2 +#define NLSF_QUANT_DEL_DEC_STATES ( 1 << NLSF_QUANT_DEL_DEC_STATES_LOG2 ) + +/* Transition filtering for mode switching */ +#define TRANSITION_TIME_MS 5120 /* 5120 = 64 * FRAME_LENGTH_MS * ( TRANSITION_INT_NUM - 1 ) = 64*(20*4)*/ +#define TRANSITION_NB 3 /* Hardcoded in tables */ +#define TRANSITION_NA 2 /* Hardcoded in tables */ +#define TRANSITION_INT_NUM 5 /* Hardcoded in tables */ +#define TRANSITION_FRAMES ( TRANSITION_TIME_MS / MAX_FRAME_LENGTH_MS ) +#define TRANSITION_INT_STEPS ( TRANSITION_FRAMES / ( TRANSITION_INT_NUM - 1 ) ) + +/* BWE factors to apply after packet loss */ +#define BWE_AFTER_LOSS_Q16 63570 + +/* Defines for CN generation */ +#define CNG_BUF_MASK_MAX 255 /* 2^floor(log2(MAX_FRAME_LENGTH))-1 */ +#define CNG_GAIN_SMTH_Q16 4634 /* 0.25^(1/4) */ +#define CNG_NLSF_SMTH_Q16 16348 /* 0.25 */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/opus-1.1/silk/enc_API.c b/src/opus-1.1/silk/enc_API.c new file mode 100644 index 00000000..43739efc --- /dev/null +++ b/src/opus-1.1/silk/enc_API.c @@ -0,0 +1,556 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include "define.h" +#include "API.h" +#include "control.h" +#include "typedef.h" +#include "stack_alloc.h" +#include "structs.h" +#include "tuning_parameters.h" +#ifdef FIXED_POINT +#include "main_FIX.h" +#else +#include "main_FLP.h" +#endif + +/***************************************/ +/* Read control structure from encoder */ +/***************************************/ +static opus_int silk_QueryEncoder( /* O Returns error code */ + const void *encState, /* I State */ + silk_EncControlStruct *encStatus /* O Encoder Status */ +); + +/****************************************/ +/* Encoder functions */ +/****************************************/ + +opus_int silk_Get_Encoder_Size( /* O Returns error code */ + opus_int *encSizeBytes /* O Number of bytes in SILK encoder state */ +) +{ + opus_int ret = SILK_NO_ERROR; + + *encSizeBytes = sizeof( silk_encoder ); + + return ret; +} + +/*************************/ +/* Init or Reset encoder */ +/*************************/ +opus_int silk_InitEncoder( /* O Returns error code */ + void *encState, /* I/O State */ + int arch, /* I Run-time architecture */ + silk_EncControlStruct *encStatus /* O Encoder Status */ +) +{ + silk_encoder *psEnc; + opus_int n, ret = SILK_NO_ERROR; + + psEnc = (silk_encoder *)encState; + + /* Reset encoder */ + silk_memset( psEnc, 0, sizeof( silk_encoder ) ); + for( n = 0; n < ENCODER_NUM_CHANNELS; n++ ) { + if( ret += silk_init_encoder( &psEnc->state_Fxx[ n ], arch ) ) { + silk_assert( 0 ); + } + } + + psEnc->nChannelsAPI = 1; + psEnc->nChannelsInternal = 1; + + /* Read control structure */ + if( ret += silk_QueryEncoder( encState, encStatus ) ) { + silk_assert( 0 ); + } + + return ret; +} + +/***************************************/ +/* Read control structure from encoder */ +/***************************************/ +static opus_int silk_QueryEncoder( /* O Returns error code */ + const void *encState, /* I State */ + silk_EncControlStruct *encStatus /* O Encoder Status */ +) +{ + opus_int ret = SILK_NO_ERROR; + silk_encoder_state_Fxx *state_Fxx; + silk_encoder *psEnc = (silk_encoder *)encState; + + state_Fxx = psEnc->state_Fxx; + + encStatus->nChannelsAPI = psEnc->nChannelsAPI; + encStatus->nChannelsInternal = psEnc->nChannelsInternal; + encStatus->API_sampleRate = state_Fxx[ 0 ].sCmn.API_fs_Hz; + encStatus->maxInternalSampleRate = state_Fxx[ 0 ].sCmn.maxInternal_fs_Hz; + encStatus->minInternalSampleRate = state_Fxx[ 0 ].sCmn.minInternal_fs_Hz; + encStatus->desiredInternalSampleRate = state_Fxx[ 0 ].sCmn.desiredInternal_fs_Hz; + encStatus->payloadSize_ms = state_Fxx[ 0 ].sCmn.PacketSize_ms; + encStatus->bitRate = state_Fxx[ 0 ].sCmn.TargetRate_bps; + encStatus->packetLossPercentage = state_Fxx[ 0 ].sCmn.PacketLoss_perc; + encStatus->complexity = state_Fxx[ 0 ].sCmn.Complexity; + encStatus->useInBandFEC = state_Fxx[ 0 ].sCmn.useInBandFEC; + encStatus->useDTX = state_Fxx[ 0 ].sCmn.useDTX; + encStatus->useCBR = state_Fxx[ 0 ].sCmn.useCBR; + encStatus->internalSampleRate = silk_SMULBB( state_Fxx[ 0 ].sCmn.fs_kHz, 1000 ); + encStatus->allowBandwidthSwitch = state_Fxx[ 0 ].sCmn.allow_bandwidth_switch; + encStatus->inWBmodeWithoutVariableLP = state_Fxx[ 0 ].sCmn.fs_kHz == 16 && state_Fxx[ 0 ].sCmn.sLP.mode == 0; + + return ret; +} + + +/**************************/ +/* Encode frame with Silk */ +/**************************/ +/* Note: if prefillFlag is set, the input must contain 10 ms of audio, irrespective of what */ +/* encControl->payloadSize_ms is set to */ +opus_int silk_Encode( /* O Returns error code */ + void *encState, /* I/O State */ + silk_EncControlStruct *encControl, /* I Control status */ + const opus_int16 *samplesIn, /* I Speech sample input vector */ + opus_int nSamplesIn, /* I Number of samples in input vector */ + ec_enc *psRangeEnc, /* I/O Compressor data structure */ + opus_int32 *nBytesOut, /* I/O Number of bytes in payload (input: Max bytes) */ + const opus_int prefillFlag /* I Flag to indicate prefilling buffers no coding */ +) +{ + opus_int n, i, nBits, flags, tmp_payloadSize_ms = 0, tmp_complexity = 0, ret = 0; + opus_int nSamplesToBuffer, nSamplesToBufferMax, nBlocksOf10ms; + opus_int nSamplesFromInput = 0, nSamplesFromInputMax; + opus_int speech_act_thr_for_switch_Q8; + opus_int32 TargetRate_bps, MStargetRates_bps[ 2 ], channelRate_bps, LBRR_symbol, sum; + silk_encoder *psEnc = ( silk_encoder * )encState; + VARDECL( opus_int16, buf ); + opus_int transition, curr_block, tot_blocks; + SAVE_STACK; + + if (encControl->reducedDependency) + { + psEnc->state_Fxx[0].sCmn.first_frame_after_reset = 1; + psEnc->state_Fxx[1].sCmn.first_frame_after_reset = 1; + } + psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded = psEnc->state_Fxx[ 1 ].sCmn.nFramesEncoded = 0; + + /* Check values in encoder control structure */ + if( ( ret = check_control_input( encControl ) != 0 ) ) { + silk_assert( 0 ); + RESTORE_STACK; + return ret; + } + + encControl->switchReady = 0; + + if( encControl->nChannelsInternal > psEnc->nChannelsInternal ) { + /* Mono -> Stereo transition: init state of second channel and stereo state */ + ret += silk_init_encoder( &psEnc->state_Fxx[ 1 ], psEnc->state_Fxx[ 0 ].sCmn.arch ); + silk_memset( psEnc->sStereo.pred_prev_Q13, 0, sizeof( psEnc->sStereo.pred_prev_Q13 ) ); + silk_memset( psEnc->sStereo.sSide, 0, sizeof( psEnc->sStereo.sSide ) ); + psEnc->sStereo.mid_side_amp_Q0[ 0 ] = 0; + psEnc->sStereo.mid_side_amp_Q0[ 1 ] = 1; + psEnc->sStereo.mid_side_amp_Q0[ 2 ] = 0; + psEnc->sStereo.mid_side_amp_Q0[ 3 ] = 1; + psEnc->sStereo.width_prev_Q14 = 0; + psEnc->sStereo.smth_width_Q14 = SILK_FIX_CONST( 1, 14 ); + if( psEnc->nChannelsAPI == 2 ) { + silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state, &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, sizeof( silk_resampler_state_struct ) ); + silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.In_HP_State, &psEnc->state_Fxx[ 0 ].sCmn.In_HP_State, sizeof( psEnc->state_Fxx[ 1 ].sCmn.In_HP_State ) ); + } + } + + transition = (encControl->payloadSize_ms != psEnc->state_Fxx[ 0 ].sCmn.PacketSize_ms) || (psEnc->nChannelsInternal != encControl->nChannelsInternal); + + psEnc->nChannelsAPI = encControl->nChannelsAPI; + psEnc->nChannelsInternal = encControl->nChannelsInternal; + + nBlocksOf10ms = silk_DIV32( 100 * nSamplesIn, encControl->API_sampleRate ); + tot_blocks = ( nBlocksOf10ms > 1 ) ? nBlocksOf10ms >> 1 : 1; + curr_block = 0; + if( prefillFlag ) { + /* Only accept input length of 10 ms */ + if( nBlocksOf10ms != 1 ) { + silk_assert( 0 ); + RESTORE_STACK; + return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES; + } + /* Reset Encoder */ + for( n = 0; n < encControl->nChannelsInternal; n++ ) { + ret = silk_init_encoder( &psEnc->state_Fxx[ n ], psEnc->state_Fxx[ n ].sCmn.arch ); + silk_assert( !ret ); + } + tmp_payloadSize_ms = encControl->payloadSize_ms; + encControl->payloadSize_ms = 10; + tmp_complexity = encControl->complexity; + encControl->complexity = 0; + for( n = 0; n < encControl->nChannelsInternal; n++ ) { + psEnc->state_Fxx[ n ].sCmn.controlled_since_last_payload = 0; + psEnc->state_Fxx[ n ].sCmn.prefillFlag = 1; + } + } else { + /* Only accept input lengths that are a multiple of 10 ms */ + if( nBlocksOf10ms * encControl->API_sampleRate != 100 * nSamplesIn || nSamplesIn < 0 ) { + silk_assert( 0 ); + RESTORE_STACK; + return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES; + } + /* Make sure no more than one packet can be produced */ + if( 1000 * (opus_int32)nSamplesIn > encControl->payloadSize_ms * encControl->API_sampleRate ) { + silk_assert( 0 ); + RESTORE_STACK; + return SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES; + } + } + + TargetRate_bps = silk_RSHIFT32( encControl->bitRate, encControl->nChannelsInternal - 1 ); + for( n = 0; n < encControl->nChannelsInternal; n++ ) { + /* Force the side channel to the same rate as the mid */ + opus_int force_fs_kHz = (n==1) ? psEnc->state_Fxx[0].sCmn.fs_kHz : 0; + if( ( ret = silk_control_encoder( &psEnc->state_Fxx[ n ], encControl, TargetRate_bps, psEnc->allowBandwidthSwitch, n, force_fs_kHz ) ) != 0 ) { + silk_assert( 0 ); + RESTORE_STACK; + return ret; + } + if( psEnc->state_Fxx[n].sCmn.first_frame_after_reset || transition ) { + for( i = 0; i < psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket; i++ ) { + psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i ] = 0; + } + } + psEnc->state_Fxx[ n ].sCmn.inDTX = psEnc->state_Fxx[ n ].sCmn.useDTX; + } + silk_assert( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 0 ].sCmn.fs_kHz == psEnc->state_Fxx[ 1 ].sCmn.fs_kHz ); + + /* Input buffering/resampling and encoding */ + nSamplesToBufferMax = + 10 * nBlocksOf10ms * psEnc->state_Fxx[ 0 ].sCmn.fs_kHz; + nSamplesFromInputMax = + silk_DIV32_16( nSamplesToBufferMax * + psEnc->state_Fxx[ 0 ].sCmn.API_fs_Hz, + psEnc->state_Fxx[ 0 ].sCmn.fs_kHz * 1000 ); + ALLOC( buf, nSamplesFromInputMax, opus_int16 ); + while( 1 ) { + nSamplesToBuffer = psEnc->state_Fxx[ 0 ].sCmn.frame_length - psEnc->state_Fxx[ 0 ].sCmn.inputBufIx; + nSamplesToBuffer = silk_min( nSamplesToBuffer, nSamplesToBufferMax ); + nSamplesFromInput = silk_DIV32_16( nSamplesToBuffer * psEnc->state_Fxx[ 0 ].sCmn.API_fs_Hz, psEnc->state_Fxx[ 0 ].sCmn.fs_kHz * 1000 ); + /* Resample and write to buffer */ + if( encControl->nChannelsAPI == 2 && encControl->nChannelsInternal == 2 ) { + opus_int id = psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded; + for( n = 0; n < nSamplesFromInput; n++ ) { + buf[ n ] = samplesIn[ 2 * n ]; + } + /* Making sure to start both resamplers from the same state when switching from mono to stereo */ + if( psEnc->nPrevChannelsInternal == 1 && id==0 ) { + silk_memcpy( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state, &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, sizeof(psEnc->state_Fxx[ 1 ].sCmn.resampler_state)); + } + + ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, + &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput ); + psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer; + + nSamplesToBuffer = psEnc->state_Fxx[ 1 ].sCmn.frame_length - psEnc->state_Fxx[ 1 ].sCmn.inputBufIx; + nSamplesToBuffer = silk_min( nSamplesToBuffer, 10 * nBlocksOf10ms * psEnc->state_Fxx[ 1 ].sCmn.fs_kHz ); + for( n = 0; n < nSamplesFromInput; n++ ) { + buf[ n ] = samplesIn[ 2 * n + 1 ]; + } + ret += silk_resampler( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state, + &psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput ); + + psEnc->state_Fxx[ 1 ].sCmn.inputBufIx += nSamplesToBuffer; + } else if( encControl->nChannelsAPI == 2 && encControl->nChannelsInternal == 1 ) { + /* Combine left and right channels before resampling */ + for( n = 0; n < nSamplesFromInput; n++ ) { + sum = samplesIn[ 2 * n ] + samplesIn[ 2 * n + 1 ]; + buf[ n ] = (opus_int16)silk_RSHIFT_ROUND( sum, 1 ); + } + ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, + &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput ); + /* On the first mono frame, average the results for the two resampler states */ + if( psEnc->nPrevChannelsInternal == 2 && psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == 0 ) { + ret += silk_resampler( &psEnc->state_Fxx[ 1 ].sCmn.resampler_state, + &psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput ); + for( n = 0; n < psEnc->state_Fxx[ 0 ].sCmn.frame_length; n++ ) { + psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx+n+2 ] = + silk_RSHIFT(psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx+n+2 ] + + psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ psEnc->state_Fxx[ 1 ].sCmn.inputBufIx+n+2 ], 1); + } + } + psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer; + } else { + silk_assert( encControl->nChannelsAPI == 1 && encControl->nChannelsInternal == 1 ); + silk_memcpy(buf, samplesIn, nSamplesFromInput*sizeof(opus_int16)); + ret += silk_resampler( &psEnc->state_Fxx[ 0 ].sCmn.resampler_state, + &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.inputBufIx + 2 ], buf, nSamplesFromInput ); + psEnc->state_Fxx[ 0 ].sCmn.inputBufIx += nSamplesToBuffer; + } + + samplesIn += nSamplesFromInput * encControl->nChannelsAPI; + nSamplesIn -= nSamplesFromInput; + + /* Default */ + psEnc->allowBandwidthSwitch = 0; + + /* Silk encoder */ + if( psEnc->state_Fxx[ 0 ].sCmn.inputBufIx >= psEnc->state_Fxx[ 0 ].sCmn.frame_length ) { + /* Enough data in input buffer, so encode */ + silk_assert( psEnc->state_Fxx[ 0 ].sCmn.inputBufIx == psEnc->state_Fxx[ 0 ].sCmn.frame_length ); + silk_assert( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 1 ].sCmn.inputBufIx == psEnc->state_Fxx[ 1 ].sCmn.frame_length ); + + /* Deal with LBRR data */ + if( psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == 0 && !prefillFlag ) { + /* Create space at start of payload for VAD and FEC flags */ + opus_uint8 iCDF[ 2 ] = { 0, 0 }; + iCDF[ 0 ] = 256 - silk_RSHIFT( 256, ( psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket + 1 ) * encControl->nChannelsInternal ); + ec_enc_icdf( psRangeEnc, 0, iCDF, 8 ); + + /* Encode any LBRR data from previous packet */ + /* Encode LBRR flags */ + for( n = 0; n < encControl->nChannelsInternal; n++ ) { + LBRR_symbol = 0; + for( i = 0; i < psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket; i++ ) { + LBRR_symbol |= silk_LSHIFT( psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i ], i ); + } + psEnc->state_Fxx[ n ].sCmn.LBRR_flag = LBRR_symbol > 0 ? 1 : 0; + if( LBRR_symbol && psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket > 1 ) { + ec_enc_icdf( psRangeEnc, LBRR_symbol - 1, silk_LBRR_flags_iCDF_ptr[ psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket - 2 ], 8 ); + } + } + + /* Code LBRR indices and excitation signals */ + for( i = 0; i < psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket; i++ ) { + for( n = 0; n < encControl->nChannelsInternal; n++ ) { + if( psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i ] ) { + opus_int condCoding; + + if( encControl->nChannelsInternal == 2 && n == 0 ) { + silk_stereo_encode_pred( psRangeEnc, psEnc->sStereo.predIx[ i ] ); + /* For LBRR data there's no need to code the mid-only flag if the side-channel LBRR flag is set */ + if( psEnc->state_Fxx[ 1 ].sCmn.LBRR_flags[ i ] == 0 ) { + silk_stereo_encode_mid_only( psRangeEnc, psEnc->sStereo.mid_only_flags[ i ] ); + } + } + /* Use conditional coding if previous frame available */ + if( i > 0 && psEnc->state_Fxx[ n ].sCmn.LBRR_flags[ i - 1 ] ) { + condCoding = CODE_CONDITIONALLY; + } else { + condCoding = CODE_INDEPENDENTLY; + } + silk_encode_indices( &psEnc->state_Fxx[ n ].sCmn, psRangeEnc, i, 1, condCoding ); + silk_encode_pulses( psRangeEnc, psEnc->state_Fxx[ n ].sCmn.indices_LBRR[i].signalType, psEnc->state_Fxx[ n ].sCmn.indices_LBRR[i].quantOffsetType, + psEnc->state_Fxx[ n ].sCmn.pulses_LBRR[ i ], psEnc->state_Fxx[ n ].sCmn.frame_length ); + } + } + } + + /* Reset LBRR flags */ + for( n = 0; n < encControl->nChannelsInternal; n++ ) { + silk_memset( psEnc->state_Fxx[ n ].sCmn.LBRR_flags, 0, sizeof( psEnc->state_Fxx[ n ].sCmn.LBRR_flags ) ); + } + } + + silk_HP_variable_cutoff( psEnc->state_Fxx ); + + /* Total target bits for packet */ + nBits = silk_DIV32_16( silk_MUL( encControl->bitRate, encControl->payloadSize_ms ), 1000 ); + /* Subtract half of the bits already used */ + if( !prefillFlag ) { + nBits -= ec_tell( psRangeEnc ) >> 1; + } + /* Divide by number of uncoded frames left in packet */ + nBits = silk_DIV32_16( nBits, psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket - psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ); + /* Convert to bits/second */ + if( encControl->payloadSize_ms == 10 ) { + TargetRate_bps = silk_SMULBB( nBits, 100 ); + } else { + TargetRate_bps = silk_SMULBB( nBits, 50 ); + } + /* Subtract fraction of bits in excess of target in previous packets */ + TargetRate_bps -= silk_DIV32_16( silk_MUL( psEnc->nBitsExceeded, 1000 ), BITRESERVOIR_DECAY_TIME_MS ); + /* Never exceed input bitrate */ + TargetRate_bps = silk_LIMIT( TargetRate_bps, encControl->bitRate, 5000 ); + + /* Convert Left/Right to Mid/Side */ + if( encControl->nChannelsInternal == 2 ) { + silk_stereo_LR_to_MS( &psEnc->sStereo, &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ 2 ], &psEnc->state_Fxx[ 1 ].sCmn.inputBuf[ 2 ], + psEnc->sStereo.predIx[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ], &psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ], + MStargetRates_bps, TargetRate_bps, psEnc->state_Fxx[ 0 ].sCmn.speech_activity_Q8, encControl->toMono, + psEnc->state_Fxx[ 0 ].sCmn.fs_kHz, psEnc->state_Fxx[ 0 ].sCmn.frame_length ); + if( psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] == 0 ) { + /* Reset side channel encoder memory for first frame with side coding */ + if( psEnc->prev_decode_only_middle == 1 ) { + silk_memset( &psEnc->state_Fxx[ 1 ].sShape, 0, sizeof( psEnc->state_Fxx[ 1 ].sShape ) ); + silk_memset( &psEnc->state_Fxx[ 1 ].sPrefilt, 0, sizeof( psEnc->state_Fxx[ 1 ].sPrefilt ) ); + silk_memset( &psEnc->state_Fxx[ 1 ].sCmn.sNSQ, 0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.sNSQ ) ); + silk_memset( psEnc->state_Fxx[ 1 ].sCmn.prev_NLSFq_Q15, 0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.prev_NLSFq_Q15 ) ); + silk_memset( &psEnc->state_Fxx[ 1 ].sCmn.sLP.In_LP_State, 0, sizeof( psEnc->state_Fxx[ 1 ].sCmn.sLP.In_LP_State ) ); + psEnc->state_Fxx[ 1 ].sCmn.prevLag = 100; + psEnc->state_Fxx[ 1 ].sCmn.sNSQ.lagPrev = 100; + psEnc->state_Fxx[ 1 ].sShape.LastGainIndex = 10; + psEnc->state_Fxx[ 1 ].sCmn.prevSignalType = TYPE_NO_VOICE_ACTIVITY; + psEnc->state_Fxx[ 1 ].sCmn.sNSQ.prev_gain_Q16 = 65536; + psEnc->state_Fxx[ 1 ].sCmn.first_frame_after_reset = 1; + } + silk_encode_do_VAD_Fxx( &psEnc->state_Fxx[ 1 ] ); + } else { + psEnc->state_Fxx[ 1 ].sCmn.VAD_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] = 0; + } + if( !prefillFlag ) { + silk_stereo_encode_pred( psRangeEnc, psEnc->sStereo.predIx[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] ); + if( psEnc->state_Fxx[ 1 ].sCmn.VAD_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] == 0 ) { + silk_stereo_encode_mid_only( psRangeEnc, psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded ] ); + } + } + } else { + /* Buffering */ + silk_memcpy( psEnc->state_Fxx[ 0 ].sCmn.inputBuf, psEnc->sStereo.sMid, 2 * sizeof( opus_int16 ) ); + silk_memcpy( psEnc->sStereo.sMid, &psEnc->state_Fxx[ 0 ].sCmn.inputBuf[ psEnc->state_Fxx[ 0 ].sCmn.frame_length ], 2 * sizeof( opus_int16 ) ); + } + silk_encode_do_VAD_Fxx( &psEnc->state_Fxx[ 0 ] ); + + /* Encode */ + for( n = 0; n < encControl->nChannelsInternal; n++ ) { + opus_int maxBits, useCBR; + + /* Handling rate constraints */ + maxBits = encControl->maxBits; + if( tot_blocks == 2 && curr_block == 0 ) { + maxBits = maxBits * 3 / 5; + } else if( tot_blocks == 3 ) { + if( curr_block == 0 ) { + maxBits = maxBits * 2 / 5; + } else if( curr_block == 1 ) { + maxBits = maxBits * 3 / 4; + } + } + useCBR = encControl->useCBR && curr_block == tot_blocks - 1; + + if( encControl->nChannelsInternal == 1 ) { + channelRate_bps = TargetRate_bps; + } else { + channelRate_bps = MStargetRates_bps[ n ]; + if( n == 0 && MStargetRates_bps[ 1 ] > 0 ) { + useCBR = 0; + /* Give mid up to 1/2 of the max bits for that frame */ + maxBits -= encControl->maxBits / ( tot_blocks * 2 ); + } + } + + if( channelRate_bps > 0 ) { + opus_int condCoding; + + silk_control_SNR( &psEnc->state_Fxx[ n ].sCmn, channelRate_bps ); + + /* Use independent coding if no previous frame available */ + if( psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded - n <= 0 ) { + condCoding = CODE_INDEPENDENTLY; + } else if( n > 0 && psEnc->prev_decode_only_middle ) { + /* If we skipped a side frame in this packet, we don't + need LTP scaling; the LTP state is well-defined. */ + condCoding = CODE_INDEPENDENTLY_NO_LTP_SCALING; + } else { + condCoding = CODE_CONDITIONALLY; + } + if( ( ret = silk_encode_frame_Fxx( &psEnc->state_Fxx[ n ], nBytesOut, psRangeEnc, condCoding, maxBits, useCBR ) ) != 0 ) { + silk_assert( 0 ); + } + } + psEnc->state_Fxx[ n ].sCmn.controlled_since_last_payload = 0; + psEnc->state_Fxx[ n ].sCmn.inputBufIx = 0; + psEnc->state_Fxx[ n ].sCmn.nFramesEncoded++; + } + psEnc->prev_decode_only_middle = psEnc->sStereo.mid_only_flags[ psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded - 1 ]; + + /* Insert VAD and FEC flags at beginning of bitstream */ + if( *nBytesOut > 0 && psEnc->state_Fxx[ 0 ].sCmn.nFramesEncoded == psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket) { + flags = 0; + for( n = 0; n < encControl->nChannelsInternal; n++ ) { + for( i = 0; i < psEnc->state_Fxx[ n ].sCmn.nFramesPerPacket; i++ ) { + flags = silk_LSHIFT( flags, 1 ); + flags |= psEnc->state_Fxx[ n ].sCmn.VAD_flags[ i ]; + } + flags = silk_LSHIFT( flags, 1 ); + flags |= psEnc->state_Fxx[ n ].sCmn.LBRR_flag; + } + if( !prefillFlag ) { + ec_enc_patch_initial_bits( psRangeEnc, flags, ( psEnc->state_Fxx[ 0 ].sCmn.nFramesPerPacket + 1 ) * encControl->nChannelsInternal ); + } + + /* Return zero bytes if all channels DTXed */ + if( psEnc->state_Fxx[ 0 ].sCmn.inDTX && ( encControl->nChannelsInternal == 1 || psEnc->state_Fxx[ 1 ].sCmn.inDTX ) ) { + *nBytesOut = 0; + } + + psEnc->nBitsExceeded += *nBytesOut * 8; + psEnc->nBitsExceeded -= silk_DIV32_16( silk_MUL( encControl->bitRate, encControl->payloadSize_ms ), 1000 ); + psEnc->nBitsExceeded = silk_LIMIT( psEnc->nBitsExceeded, 0, 10000 ); + + /* Update flag indicating if bandwidth switching is allowed */ + speech_act_thr_for_switch_Q8 = silk_SMLAWB( SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ), + SILK_FIX_CONST( ( 1 - SPEECH_ACTIVITY_DTX_THRES ) / MAX_BANDWIDTH_SWITCH_DELAY_MS, 16 + 8 ), psEnc->timeSinceSwitchAllowed_ms ); + if( psEnc->state_Fxx[ 0 ].sCmn.speech_activity_Q8 < speech_act_thr_for_switch_Q8 ) { + psEnc->allowBandwidthSwitch = 1; + psEnc->timeSinceSwitchAllowed_ms = 0; + } else { + psEnc->allowBandwidthSwitch = 0; + psEnc->timeSinceSwitchAllowed_ms += encControl->payloadSize_ms; + } + } + + if( nSamplesIn == 0 ) { + break; + } + } else { + break; + } + curr_block++; + } + + psEnc->nPrevChannelsInternal = encControl->nChannelsInternal; + + encControl->allowBandwidthSwitch = psEnc->allowBandwidthSwitch; + encControl->inWBmodeWithoutVariableLP = psEnc->state_Fxx[ 0 ].sCmn.fs_kHz == 16 && psEnc->state_Fxx[ 0 ].sCmn.sLP.mode == 0; + encControl->internalSampleRate = silk_SMULBB( psEnc->state_Fxx[ 0 ].sCmn.fs_kHz, 1000 ); + encControl->stereoWidth_Q14 = encControl->toMono ? 0 : psEnc->sStereo.smth_width_Q14; + if( prefillFlag ) { + encControl->payloadSize_ms = tmp_payloadSize_ms; + encControl->complexity = tmp_complexity; + for( n = 0; n < encControl->nChannelsInternal; n++ ) { + psEnc->state_Fxx[ n ].sCmn.controlled_since_last_payload = 0; + psEnc->state_Fxx[ n ].sCmn.prefillFlag = 0; + } + } + + RESTORE_STACK; + return ret; +} + diff --git a/src/opus-1.1/silk/encode_indices.c b/src/opus-1.1/silk/encode_indices.c new file mode 100644 index 00000000..666c8c0b --- /dev/null +++ b/src/opus-1.1/silk/encode_indices.c @@ -0,0 +1,181 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main.h" + +/* Encode side-information parameters to payload */ +void silk_encode_indices( + silk_encoder_state *psEncC, /* I/O Encoder state */ + ec_enc *psRangeEnc, /* I/O Compressor data structure */ + opus_int FrameIndex, /* I Frame number */ + opus_int encode_LBRR, /* I Flag indicating LBRR data is being encoded */ + opus_int condCoding /* I The type of conditional coding to use */ +) +{ + opus_int i, k, typeOffset; + opus_int encode_absolute_lagIndex, delta_lagIndex; + opus_int16 ec_ix[ MAX_LPC_ORDER ]; + opus_uint8 pred_Q8[ MAX_LPC_ORDER ]; + const SideInfoIndices *psIndices; + + if( encode_LBRR ) { + psIndices = &psEncC->indices_LBRR[ FrameIndex ]; + } else { + psIndices = &psEncC->indices; + } + + /*******************************************/ + /* Encode signal type and quantizer offset */ + /*******************************************/ + typeOffset = 2 * psIndices->signalType + psIndices->quantOffsetType; + silk_assert( typeOffset >= 0 && typeOffset < 6 ); + silk_assert( encode_LBRR == 0 || typeOffset >= 2 ); + if( encode_LBRR || typeOffset >= 2 ) { + ec_enc_icdf( psRangeEnc, typeOffset - 2, silk_type_offset_VAD_iCDF, 8 ); + } else { + ec_enc_icdf( psRangeEnc, typeOffset, silk_type_offset_no_VAD_iCDF, 8 ); + } + + /****************/ + /* Encode gains */ + /****************/ + /* first subframe */ + if( condCoding == CODE_CONDITIONALLY ) { + /* conditional coding */ + silk_assert( psIndices->GainsIndices[ 0 ] >= 0 && psIndices->GainsIndices[ 0 ] < MAX_DELTA_GAIN_QUANT - MIN_DELTA_GAIN_QUANT + 1 ); + ec_enc_icdf( psRangeEnc, psIndices->GainsIndices[ 0 ], silk_delta_gain_iCDF, 8 ); + } else { + /* independent coding, in two stages: MSB bits followed by 3 LSBs */ + silk_assert( psIndices->GainsIndices[ 0 ] >= 0 && psIndices->GainsIndices[ 0 ] < N_LEVELS_QGAIN ); + ec_enc_icdf( psRangeEnc, silk_RSHIFT( psIndices->GainsIndices[ 0 ], 3 ), silk_gain_iCDF[ psIndices->signalType ], 8 ); + ec_enc_icdf( psRangeEnc, psIndices->GainsIndices[ 0 ] & 7, silk_uniform8_iCDF, 8 ); + } + + /* remaining subframes */ + for( i = 1; i < psEncC->nb_subfr; i++ ) { + silk_assert( psIndices->GainsIndices[ i ] >= 0 && psIndices->GainsIndices[ i ] < MAX_DELTA_GAIN_QUANT - MIN_DELTA_GAIN_QUANT + 1 ); + ec_enc_icdf( psRangeEnc, psIndices->GainsIndices[ i ], silk_delta_gain_iCDF, 8 ); + } + + /****************/ + /* Encode NLSFs */ + /****************/ + ec_enc_icdf( psRangeEnc, psIndices->NLSFIndices[ 0 ], &psEncC->psNLSF_CB->CB1_iCDF[ ( psIndices->signalType >> 1 ) * psEncC->psNLSF_CB->nVectors ], 8 ); + silk_NLSF_unpack( ec_ix, pred_Q8, psEncC->psNLSF_CB, psIndices->NLSFIndices[ 0 ] ); + silk_assert( psEncC->psNLSF_CB->order == psEncC->predictLPCOrder ); + for( i = 0; i < psEncC->psNLSF_CB->order; i++ ) { + if( psIndices->NLSFIndices[ i+1 ] >= NLSF_QUANT_MAX_AMPLITUDE ) { + ec_enc_icdf( psRangeEnc, 2 * NLSF_QUANT_MAX_AMPLITUDE, &psEncC->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 ); + ec_enc_icdf( psRangeEnc, psIndices->NLSFIndices[ i+1 ] - NLSF_QUANT_MAX_AMPLITUDE, silk_NLSF_EXT_iCDF, 8 ); + } else if( psIndices->NLSFIndices[ i+1 ] <= -NLSF_QUANT_MAX_AMPLITUDE ) { + ec_enc_icdf( psRangeEnc, 0, &psEncC->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 ); + ec_enc_icdf( psRangeEnc, -psIndices->NLSFIndices[ i+1 ] - NLSF_QUANT_MAX_AMPLITUDE, silk_NLSF_EXT_iCDF, 8 ); + } else { + ec_enc_icdf( psRangeEnc, psIndices->NLSFIndices[ i+1 ] + NLSF_QUANT_MAX_AMPLITUDE, &psEncC->psNLSF_CB->ec_iCDF[ ec_ix[ i ] ], 8 ); + } + } + + /* Encode NLSF interpolation factor */ + if( psEncC->nb_subfr == MAX_NB_SUBFR ) { + silk_assert( psIndices->NLSFInterpCoef_Q2 >= 0 && psIndices->NLSFInterpCoef_Q2 < 5 ); + ec_enc_icdf( psRangeEnc, psIndices->NLSFInterpCoef_Q2, silk_NLSF_interpolation_factor_iCDF, 8 ); + } + + if( psIndices->signalType == TYPE_VOICED ) + { + /*********************/ + /* Encode pitch lags */ + /*********************/ + /* lag index */ + encode_absolute_lagIndex = 1; + if( condCoding == CODE_CONDITIONALLY && psEncC->ec_prevSignalType == TYPE_VOICED ) { + /* Delta Encoding */ + delta_lagIndex = psIndices->lagIndex - psEncC->ec_prevLagIndex; + if( delta_lagIndex < -8 || delta_lagIndex > 11 ) { + delta_lagIndex = 0; + } else { + delta_lagIndex = delta_lagIndex + 9; + encode_absolute_lagIndex = 0; /* Only use delta */ + } + silk_assert( delta_lagIndex >= 0 && delta_lagIndex < 21 ); + ec_enc_icdf( psRangeEnc, delta_lagIndex, silk_pitch_delta_iCDF, 8 ); + } + if( encode_absolute_lagIndex ) { + /* Absolute encoding */ + opus_int32 pitch_high_bits, pitch_low_bits; + pitch_high_bits = silk_DIV32_16( psIndices->lagIndex, silk_RSHIFT( psEncC->fs_kHz, 1 ) ); + pitch_low_bits = psIndices->lagIndex - silk_SMULBB( pitch_high_bits, silk_RSHIFT( psEncC->fs_kHz, 1 ) ); + silk_assert( pitch_low_bits < psEncC->fs_kHz / 2 ); + silk_assert( pitch_high_bits < 32 ); + ec_enc_icdf( psRangeEnc, pitch_high_bits, silk_pitch_lag_iCDF, 8 ); + ec_enc_icdf( psRangeEnc, pitch_low_bits, psEncC->pitch_lag_low_bits_iCDF, 8 ); + } + psEncC->ec_prevLagIndex = psIndices->lagIndex; + + /* Countour index */ + silk_assert( psIndices->contourIndex >= 0 ); + silk_assert( ( psIndices->contourIndex < 34 && psEncC->fs_kHz > 8 && psEncC->nb_subfr == 4 ) || + ( psIndices->contourIndex < 11 && psEncC->fs_kHz == 8 && psEncC->nb_subfr == 4 ) || + ( psIndices->contourIndex < 12 && psEncC->fs_kHz > 8 && psEncC->nb_subfr == 2 ) || + ( psIndices->contourIndex < 3 && psEncC->fs_kHz == 8 && psEncC->nb_subfr == 2 ) ); + ec_enc_icdf( psRangeEnc, psIndices->contourIndex, psEncC->pitch_contour_iCDF, 8 ); + + /********************/ + /* Encode LTP gains */ + /********************/ + /* PERIndex value */ + silk_assert( psIndices->PERIndex >= 0 && psIndices->PERIndex < 3 ); + ec_enc_icdf( psRangeEnc, psIndices->PERIndex, silk_LTP_per_index_iCDF, 8 ); + + /* Codebook Indices */ + for( k = 0; k < psEncC->nb_subfr; k++ ) { + silk_assert( psIndices->LTPIndex[ k ] >= 0 && psIndices->LTPIndex[ k ] < ( 8 << psIndices->PERIndex ) ); + ec_enc_icdf( psRangeEnc, psIndices->LTPIndex[ k ], silk_LTP_gain_iCDF_ptrs[ psIndices->PERIndex ], 8 ); + } + + /**********************/ + /* Encode LTP scaling */ + /**********************/ + if( condCoding == CODE_INDEPENDENTLY ) { + silk_assert( psIndices->LTP_scaleIndex >= 0 && psIndices->LTP_scaleIndex < 3 ); + ec_enc_icdf( psRangeEnc, psIndices->LTP_scaleIndex, silk_LTPscale_iCDF, 8 ); + } + silk_assert( !condCoding || psIndices->LTP_scaleIndex == 0 ); + } + + psEncC->ec_prevSignalType = psIndices->signalType; + + /***************/ + /* Encode seed */ + /***************/ + silk_assert( psIndices->Seed >= 0 && psIndices->Seed < 4 ); + ec_enc_icdf( psRangeEnc, psIndices->Seed, silk_uniform4_iCDF, 8 ); +} diff --git a/src/opus-1.1/silk/encode_pulses.c b/src/opus-1.1/silk/encode_pulses.c new file mode 100644 index 00000000..a4501438 --- /dev/null +++ b/src/opus-1.1/silk/encode_pulses.c @@ -0,0 +1,206 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main.h" +#include "stack_alloc.h" + +/*********************************************/ +/* Encode quantization indices of excitation */ +/*********************************************/ + +static OPUS_INLINE opus_int combine_and_check( /* return ok */ + opus_int *pulses_comb, /* O */ + const opus_int *pulses_in, /* I */ + opus_int max_pulses, /* I max value for sum of pulses */ + opus_int len /* I number of output values */ +) +{ + opus_int k, sum; + + for( k = 0; k < len; k++ ) { + sum = pulses_in[ 2 * k ] + pulses_in[ 2 * k + 1 ]; + if( sum > max_pulses ) { + return 1; + } + pulses_comb[ k ] = sum; + } + + return 0; +} + +/* Encode quantization indices of excitation */ +void silk_encode_pulses( + ec_enc *psRangeEnc, /* I/O compressor data structure */ + const opus_int signalType, /* I Signal type */ + const opus_int quantOffsetType, /* I quantOffsetType */ + opus_int8 pulses[], /* I quantization indices */ + const opus_int frame_length /* I Frame length */ +) +{ + opus_int i, k, j, iter, bit, nLS, scale_down, RateLevelIndex = 0; + opus_int32 abs_q, minSumBits_Q5, sumBits_Q5; + VARDECL( opus_int, abs_pulses ); + VARDECL( opus_int, sum_pulses ); + VARDECL( opus_int, nRshifts ); + opus_int pulses_comb[ 8 ]; + opus_int *abs_pulses_ptr; + const opus_int8 *pulses_ptr; + const opus_uint8 *cdf_ptr; + const opus_uint8 *nBits_ptr; + SAVE_STACK; + + silk_memset( pulses_comb, 0, 8 * sizeof( opus_int ) ); /* Fixing Valgrind reported problem*/ + + /****************************/ + /* Prepare for shell coding */ + /****************************/ + /* Calculate number of shell blocks */ + silk_assert( 1 << LOG2_SHELL_CODEC_FRAME_LENGTH == SHELL_CODEC_FRAME_LENGTH ); + iter = silk_RSHIFT( frame_length, LOG2_SHELL_CODEC_FRAME_LENGTH ); + if( iter * SHELL_CODEC_FRAME_LENGTH < frame_length ) { + silk_assert( frame_length == 12 * 10 ); /* Make sure only happens for 10 ms @ 12 kHz */ + iter++; + silk_memset( &pulses[ frame_length ], 0, SHELL_CODEC_FRAME_LENGTH * sizeof(opus_int8)); + } + + /* Take the absolute value of the pulses */ + ALLOC( abs_pulses, iter * SHELL_CODEC_FRAME_LENGTH, opus_int ); + silk_assert( !( SHELL_CODEC_FRAME_LENGTH & 3 ) ); + for( i = 0; i < iter * SHELL_CODEC_FRAME_LENGTH; i+=4 ) { + abs_pulses[i+0] = ( opus_int )silk_abs( pulses[ i + 0 ] ); + abs_pulses[i+1] = ( opus_int )silk_abs( pulses[ i + 1 ] ); + abs_pulses[i+2] = ( opus_int )silk_abs( pulses[ i + 2 ] ); + abs_pulses[i+3] = ( opus_int )silk_abs( pulses[ i + 3 ] ); + } + + /* Calc sum pulses per shell code frame */ + ALLOC( sum_pulses, iter, opus_int ); + ALLOC( nRshifts, iter, opus_int ); + abs_pulses_ptr = abs_pulses; + for( i = 0; i < iter; i++ ) { + nRshifts[ i ] = 0; + + while( 1 ) { + /* 1+1 -> 2 */ + scale_down = combine_and_check( pulses_comb, abs_pulses_ptr, silk_max_pulses_table[ 0 ], 8 ); + /* 2+2 -> 4 */ + scale_down += combine_and_check( pulses_comb, pulses_comb, silk_max_pulses_table[ 1 ], 4 ); + /* 4+4 -> 8 */ + scale_down += combine_and_check( pulses_comb, pulses_comb, silk_max_pulses_table[ 2 ], 2 ); + /* 8+8 -> 16 */ + scale_down += combine_and_check( &sum_pulses[ i ], pulses_comb, silk_max_pulses_table[ 3 ], 1 ); + + if( scale_down ) { + /* We need to downscale the quantization signal */ + nRshifts[ i ]++; + for( k = 0; k < SHELL_CODEC_FRAME_LENGTH; k++ ) { + abs_pulses_ptr[ k ] = silk_RSHIFT( abs_pulses_ptr[ k ], 1 ); + } + } else { + /* Jump out of while(1) loop and go to next shell coding frame */ + break; + } + } + abs_pulses_ptr += SHELL_CODEC_FRAME_LENGTH; + } + + /**************/ + /* Rate level */ + /**************/ + /* find rate level that leads to fewest bits for coding of pulses per block info */ + minSumBits_Q5 = silk_int32_MAX; + for( k = 0; k < N_RATE_LEVELS - 1; k++ ) { + nBits_ptr = silk_pulses_per_block_BITS_Q5[ k ]; + sumBits_Q5 = silk_rate_levels_BITS_Q5[ signalType >> 1 ][ k ]; + for( i = 0; i < iter; i++ ) { + if( nRshifts[ i ] > 0 ) { + sumBits_Q5 += nBits_ptr[ MAX_PULSES + 1 ]; + } else { + sumBits_Q5 += nBits_ptr[ sum_pulses[ i ] ]; + } + } + if( sumBits_Q5 < minSumBits_Q5 ) { + minSumBits_Q5 = sumBits_Q5; + RateLevelIndex = k; + } + } + ec_enc_icdf( psRangeEnc, RateLevelIndex, silk_rate_levels_iCDF[ signalType >> 1 ], 8 ); + + /***************************************************/ + /* Sum-Weighted-Pulses Encoding */ + /***************************************************/ + cdf_ptr = silk_pulses_per_block_iCDF[ RateLevelIndex ]; + for( i = 0; i < iter; i++ ) { + if( nRshifts[ i ] == 0 ) { + ec_enc_icdf( psRangeEnc, sum_pulses[ i ], cdf_ptr, 8 ); + } else { + ec_enc_icdf( psRangeEnc, MAX_PULSES + 1, cdf_ptr, 8 ); + for( k = 0; k < nRshifts[ i ] - 1; k++ ) { + ec_enc_icdf( psRangeEnc, MAX_PULSES + 1, silk_pulses_per_block_iCDF[ N_RATE_LEVELS - 1 ], 8 ); + } + ec_enc_icdf( psRangeEnc, sum_pulses[ i ], silk_pulses_per_block_iCDF[ N_RATE_LEVELS - 1 ], 8 ); + } + } + + /******************/ + /* Shell Encoding */ + /******************/ + for( i = 0; i < iter; i++ ) { + if( sum_pulses[ i ] > 0 ) { + silk_shell_encoder( psRangeEnc, &abs_pulses[ i * SHELL_CODEC_FRAME_LENGTH ] ); + } + } + + /****************/ + /* LSB Encoding */ + /****************/ + for( i = 0; i < iter; i++ ) { + if( nRshifts[ i ] > 0 ) { + pulses_ptr = &pulses[ i * SHELL_CODEC_FRAME_LENGTH ]; + nLS = nRshifts[ i ] - 1; + for( k = 0; k < SHELL_CODEC_FRAME_LENGTH; k++ ) { + abs_q = (opus_int8)silk_abs( pulses_ptr[ k ] ); + for( j = nLS; j > 0; j-- ) { + bit = silk_RSHIFT( abs_q, j ) & 1; + ec_enc_icdf( psRangeEnc, bit, silk_lsb_iCDF, 8 ); + } + bit = abs_q & 1; + ec_enc_icdf( psRangeEnc, bit, silk_lsb_iCDF, 8 ); + } + } + } + + /****************/ + /* Encode signs */ + /****************/ + silk_encode_signs( psRangeEnc, pulses, frame_length, signalType, quantOffsetType, sum_pulses ); + RESTORE_STACK; +} diff --git a/src/opus-1.1/silk/errors.h b/src/opus-1.1/silk/errors.h new file mode 100644 index 00000000..45070800 --- /dev/null +++ b/src/opus-1.1/silk/errors.h @@ -0,0 +1,98 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifndef SILK_ERRORS_H +#define SILK_ERRORS_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************/ +/* Error messages */ +/******************/ +#define SILK_NO_ERROR 0 + +/**************************/ +/* Encoder error messages */ +/**************************/ + +/* Input length is not a multiple of 10 ms, or length is longer than the packet length */ +#define SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES -101 + +/* Sampling frequency not 8000, 12000 or 16000 Hertz */ +#define SILK_ENC_FS_NOT_SUPPORTED -102 + +/* Packet size not 10, 20, 40, or 60 ms */ +#define SILK_ENC_PACKET_SIZE_NOT_SUPPORTED -103 + +/* Allocated payload buffer too short */ +#define SILK_ENC_PAYLOAD_BUF_TOO_SHORT -104 + +/* Loss rate not between 0 and 100 percent */ +#define SILK_ENC_INVALID_LOSS_RATE -105 + +/* Complexity setting not valid, use 0...10 */ +#define SILK_ENC_INVALID_COMPLEXITY_SETTING -106 + +/* Inband FEC setting not valid, use 0 or 1 */ +#define SILK_ENC_INVALID_INBAND_FEC_SETTING -107 + +/* DTX setting not valid, use 0 or 1 */ +#define SILK_ENC_INVALID_DTX_SETTING -108 + +/* CBR setting not valid, use 0 or 1 */ +#define SILK_ENC_INVALID_CBR_SETTING -109 + +/* Internal encoder error */ +#define SILK_ENC_INTERNAL_ERROR -110 + +/* Internal encoder error */ +#define SILK_ENC_INVALID_NUMBER_OF_CHANNELS_ERROR -111 + +/**************************/ +/* Decoder error messages */ +/**************************/ + +/* Output sampling frequency lower than internal decoded sampling frequency */ +#define SILK_DEC_INVALID_SAMPLING_FREQUENCY -200 + +/* Payload size exceeded the maximum allowed 1024 bytes */ +#define SILK_DEC_PAYLOAD_TOO_LARGE -201 + +/* Payload has bit errors */ +#define SILK_DEC_PAYLOAD_ERROR -202 + +/* Payload has bit errors */ +#define SILK_DEC_INVALID_FRAME_SIZE -203 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/opus-1.1/silk/fixed/LTP_analysis_filter_FIX.c b/src/opus-1.1/silk/fixed/LTP_analysis_filter_FIX.c new file mode 100644 index 00000000..a9419080 --- /dev/null +++ b/src/opus-1.1/silk/fixed/LTP_analysis_filter_FIX.c @@ -0,0 +1,85 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main_FIX.h" + +void silk_LTP_analysis_filter_FIX( + opus_int16 *LTP_res, /* O LTP residual signal of length MAX_NB_SUBFR * ( pre_length + subfr_length ) */ + const opus_int16 *x, /* I Pointer to input signal with at least max( pitchL ) preceding samples */ + const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],/* I LTP_ORDER LTP coefficients for each MAX_NB_SUBFR subframe */ + const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag, one for each subframe */ + const opus_int32 invGains_Q16[ MAX_NB_SUBFR ], /* I Inverse quantization gains, one for each subframe */ + const opus_int subfr_length, /* I Length of each subframe */ + const opus_int nb_subfr, /* I Number of subframes */ + const opus_int pre_length /* I Length of the preceding samples starting at &x[0] for each subframe */ +) +{ + const opus_int16 *x_ptr, *x_lag_ptr; + opus_int16 Btmp_Q14[ LTP_ORDER ]; + opus_int16 *LTP_res_ptr; + opus_int k, i, j; + opus_int32 LTP_est; + + x_ptr = x; + LTP_res_ptr = LTP_res; + for( k = 0; k < nb_subfr; k++ ) { + + x_lag_ptr = x_ptr - pitchL[ k ]; + for( i = 0; i < LTP_ORDER; i++ ) { + Btmp_Q14[ i ] = LTPCoef_Q14[ k * LTP_ORDER + i ]; + } + + /* LTP analysis FIR filter */ + for( i = 0; i < subfr_length + pre_length; i++ ) { + LTP_res_ptr[ i ] = x_ptr[ i ]; + + /* Long-term prediction */ + LTP_est = silk_SMULBB( x_lag_ptr[ LTP_ORDER / 2 ], Btmp_Q14[ 0 ] ); + for( j = 1; j < LTP_ORDER; j++ ) { + LTP_est = silk_SMLABB_ovflw( LTP_est, x_lag_ptr[ LTP_ORDER / 2 - j ], Btmp_Q14[ j ] ); + } + LTP_est = silk_RSHIFT_ROUND( LTP_est, 14 ); /* round and -> Q0*/ + + /* Subtract long-term prediction */ + LTP_res_ptr[ i ] = (opus_int16)silk_SAT16( (opus_int32)x_ptr[ i ] - LTP_est ); + + /* Scale residual */ + LTP_res_ptr[ i ] = silk_SMULWB( invGains_Q16[ k ], LTP_res_ptr[ i ] ); + + x_lag_ptr++; + } + + /* Update pointers */ + LTP_res_ptr += subfr_length + pre_length; + x_ptr += subfr_length; + } +} + diff --git a/src/opus-1.1/silk/fixed/LTP_scale_ctrl_FIX.c b/src/opus-1.1/silk/fixed/LTP_scale_ctrl_FIX.c new file mode 100644 index 00000000..3dcedef8 --- /dev/null +++ b/src/opus-1.1/silk/fixed/LTP_scale_ctrl_FIX.c @@ -0,0 +1,53 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main_FIX.h" + +/* Calculation of LTP state scaling */ +void silk_LTP_scale_ctrl_FIX( + silk_encoder_state_FIX *psEnc, /* I/O encoder state */ + silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */ + opus_int condCoding /* I The type of conditional coding to use */ +) +{ + opus_int round_loss; + + if( condCoding == CODE_INDEPENDENTLY ) { + /* Only scale if first frame in packet */ + round_loss = psEnc->sCmn.PacketLoss_perc + psEnc->sCmn.nFramesPerPacket; + psEnc->sCmn.indices.LTP_scaleIndex = (opus_int8)silk_LIMIT( + silk_SMULWB( silk_SMULBB( round_loss, psEncCtrl->LTPredCodGain_Q7 ), SILK_FIX_CONST( 0.1, 9 ) ), 0, 2 ); + } else { + /* Default is minimum scaling */ + psEnc->sCmn.indices.LTP_scaleIndex = 0; + } + psEncCtrl->LTP_scale_Q14 = silk_LTPScales_table_Q14[ psEnc->sCmn.indices.LTP_scaleIndex ]; +} diff --git a/src/opus-1.1/silk/fixed/apply_sine_window_FIX.c b/src/opus-1.1/silk/fixed/apply_sine_window_FIX.c new file mode 100644 index 00000000..4502b713 --- /dev/null +++ b/src/opus-1.1/silk/fixed/apply_sine_window_FIX.c @@ -0,0 +1,101 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SigProc_FIX.h" + +/* Apply sine window to signal vector. */ +/* Window types: */ +/* 1 -> sine window from 0 to pi/2 */ +/* 2 -> sine window from pi/2 to pi */ +/* Every other sample is linearly interpolated, for speed. */ +/* Window length must be between 16 and 120 (incl) and a multiple of 4. */ + +/* Matlab code for table: + for k=16:9*4:16+2*9*4, fprintf(' %7.d,', -round(65536*pi ./ (k:4:k+8*4))); fprintf('\n'); end +*/ +static const opus_int16 freq_table_Q16[ 27 ] = { + 12111, 9804, 8235, 7100, 6239, 5565, 5022, 4575, 4202, + 3885, 3612, 3375, 3167, 2984, 2820, 2674, 2542, 2422, + 2313, 2214, 2123, 2038, 1961, 1889, 1822, 1760, 1702, +}; + +void silk_apply_sine_window( + opus_int16 px_win[], /* O Pointer to windowed signal */ + const opus_int16 px[], /* I Pointer to input signal */ + const opus_int win_type, /* I Selects a window type */ + const opus_int length /* I Window length, multiple of 4 */ +) +{ + opus_int k, f_Q16, c_Q16; + opus_int32 S0_Q16, S1_Q16; + + silk_assert( win_type == 1 || win_type == 2 ); + + /* Length must be in a range from 16 to 120 and a multiple of 4 */ + silk_assert( length >= 16 && length <= 120 ); + silk_assert( ( length & 3 ) == 0 ); + + /* Frequency */ + k = ( length >> 2 ) - 4; + silk_assert( k >= 0 && k <= 26 ); + f_Q16 = (opus_int)freq_table_Q16[ k ]; + + /* Factor used for cosine approximation */ + c_Q16 = silk_SMULWB( (opus_int32)f_Q16, -f_Q16 ); + silk_assert( c_Q16 >= -32768 ); + + /* initialize state */ + if( win_type == 1 ) { + /* start from 0 */ + S0_Q16 = 0; + /* approximation of sin(f) */ + S1_Q16 = f_Q16 + silk_RSHIFT( length, 3 ); + } else { + /* start from 1 */ + S0_Q16 = ( (opus_int32)1 << 16 ); + /* approximation of cos(f) */ + S1_Q16 = ( (opus_int32)1 << 16 ) + silk_RSHIFT( c_Q16, 1 ) + silk_RSHIFT( length, 4 ); + } + + /* Uses the recursive equation: sin(n*f) = 2 * cos(f) * sin((n-1)*f) - sin((n-2)*f) */ + /* 4 samples at a time */ + for( k = 0; k < length; k += 4 ) { + px_win[ k ] = (opus_int16)silk_SMULWB( silk_RSHIFT( S0_Q16 + S1_Q16, 1 ), px[ k ] ); + px_win[ k + 1 ] = (opus_int16)silk_SMULWB( S1_Q16, px[ k + 1] ); + S0_Q16 = silk_SMULWB( S1_Q16, c_Q16 ) + silk_LSHIFT( S1_Q16, 1 ) - S0_Q16 + 1; + S0_Q16 = silk_min( S0_Q16, ( (opus_int32)1 << 16 ) ); + + px_win[ k + 2 ] = (opus_int16)silk_SMULWB( silk_RSHIFT( S0_Q16 + S1_Q16, 1 ), px[ k + 2] ); + px_win[ k + 3 ] = (opus_int16)silk_SMULWB( S0_Q16, px[ k + 3 ] ); + S1_Q16 = silk_SMULWB( S0_Q16, c_Q16 ) + silk_LSHIFT( S0_Q16, 1 ) - S1_Q16; + S1_Q16 = silk_min( S1_Q16, ( (opus_int32)1 << 16 ) ); + } +} diff --git a/src/opus-1.1/silk/fixed/autocorr_FIX.c b/src/opus-1.1/silk/fixed/autocorr_FIX.c new file mode 100644 index 00000000..de95c986 --- /dev/null +++ b/src/opus-1.1/silk/fixed/autocorr_FIX.c @@ -0,0 +1,48 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SigProc_FIX.h" +#include "celt_lpc.h" + +/* Compute autocorrelation */ +void silk_autocorr( + opus_int32 *results, /* O Result (length correlationCount) */ + opus_int *scale, /* O Scaling of the correlation vector */ + const opus_int16 *inputData, /* I Input data to correlate */ + const opus_int inputDataSize, /* I Length of input */ + const opus_int correlationCount, /* I Number of correlation taps to compute */ + int arch /* I Run-time architecture */ +) +{ + opus_int corrCount; + corrCount = silk_min_int( inputDataSize, correlationCount ); + *scale = _celt_autocorr(inputData, results, NULL, 0, corrCount-1, inputDataSize, arch); +} diff --git a/src/opus-1.1/silk/fixed/burg_modified_FIX.c b/src/opus-1.1/silk/fixed/burg_modified_FIX.c new file mode 100644 index 00000000..db348295 --- /dev/null +++ b/src/opus-1.1/silk/fixed/burg_modified_FIX.c @@ -0,0 +1,279 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SigProc_FIX.h" +#include "define.h" +#include "tuning_parameters.h" +#include "pitch.h" + +#define MAX_FRAME_SIZE 384 /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384 */ + +#define QA 25 +#define N_BITS_HEAD_ROOM 2 +#define MIN_RSHIFTS -16 +#define MAX_RSHIFTS (32 - QA) + +/* Compute reflection coefficients from input signal */ +void silk_burg_modified( + opus_int32 *res_nrg, /* O Residual energy */ + opus_int *res_nrg_Q, /* O Residual energy Q value */ + opus_int32 A_Q16[], /* O Prediction coefficients (length order) */ + const opus_int16 x[], /* I Input signal, length: nb_subfr * ( D + subfr_length ) */ + const opus_int32 minInvGain_Q30, /* I Inverse of max prediction gain */ + const opus_int subfr_length, /* I Input signal subframe length (incl. D preceding samples) */ + const opus_int nb_subfr, /* I Number of subframes stacked in x */ + const opus_int D, /* I Order */ + int arch /* I Run-time architecture */ +) +{ + opus_int k, n, s, lz, rshifts, rshifts_extra, reached_max_gain; + opus_int32 C0, num, nrg, rc_Q31, invGain_Q30, Atmp_QA, Atmp1, tmp1, tmp2, x1, x2; + const opus_int16 *x_ptr; + opus_int32 C_first_row[ SILK_MAX_ORDER_LPC ]; + opus_int32 C_last_row[ SILK_MAX_ORDER_LPC ]; + opus_int32 Af_QA[ SILK_MAX_ORDER_LPC ]; + opus_int32 CAf[ SILK_MAX_ORDER_LPC + 1 ]; + opus_int32 CAb[ SILK_MAX_ORDER_LPC + 1 ]; + opus_int32 xcorr[ SILK_MAX_ORDER_LPC ]; + + silk_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE ); + + /* Compute autocorrelations, added over subframes */ + silk_sum_sqr_shift( &C0, &rshifts, x, nb_subfr * subfr_length ); + if( rshifts > MAX_RSHIFTS ) { + C0 = silk_LSHIFT32( C0, rshifts - MAX_RSHIFTS ); + silk_assert( C0 > 0 ); + rshifts = MAX_RSHIFTS; + } else { + lz = silk_CLZ32( C0 ) - 1; + rshifts_extra = N_BITS_HEAD_ROOM - lz; + if( rshifts_extra > 0 ) { + rshifts_extra = silk_min( rshifts_extra, MAX_RSHIFTS - rshifts ); + C0 = silk_RSHIFT32( C0, rshifts_extra ); + } else { + rshifts_extra = silk_max( rshifts_extra, MIN_RSHIFTS - rshifts ); + C0 = silk_LSHIFT32( C0, -rshifts_extra ); + } + rshifts += rshifts_extra; + } + CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1; /* Q(-rshifts) */ + silk_memset( C_first_row, 0, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) ); + if( rshifts > 0 ) { + for( s = 0; s < nb_subfr; s++ ) { + x_ptr = x + s * subfr_length; + for( n = 1; n < D + 1; n++ ) { + C_first_row[ n - 1 ] += (opus_int32)silk_RSHIFT64( + silk_inner_prod16_aligned_64( x_ptr, x_ptr + n, subfr_length - n ), rshifts ); + } + } + } else { + for( s = 0; s < nb_subfr; s++ ) { + int i; + opus_int32 d; + x_ptr = x + s * subfr_length; + celt_pitch_xcorr(x_ptr, x_ptr + 1, xcorr, subfr_length - D, D, arch ); + for( n = 1; n < D + 1; n++ ) { + for ( i = n + subfr_length - D, d = 0; i < subfr_length; i++ ) + d = MAC16_16( d, x_ptr[ i ], x_ptr[ i - n ] ); + xcorr[ n - 1 ] += d; + } + for( n = 1; n < D + 1; n++ ) { + C_first_row[ n - 1 ] += silk_LSHIFT32( xcorr[ n - 1 ], -rshifts ); + } + } + } + silk_memcpy( C_last_row, C_first_row, SILK_MAX_ORDER_LPC * sizeof( opus_int32 ) ); + + /* Initialize */ + CAb[ 0 ] = CAf[ 0 ] = C0 + silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ) + 1; /* Q(-rshifts) */ + + invGain_Q30 = (opus_int32)1 << 30; + reached_max_gain = 0; + for( n = 0; n < D; n++ ) { + /* Update first row of correlation matrix (without first element) */ + /* Update last row of correlation matrix (without last element, stored in reversed order) */ + /* Update C * Af */ + /* Update C * flipud(Af) (stored in reversed order) */ + if( rshifts > -2 ) { + for( s = 0; s < nb_subfr; s++ ) { + x_ptr = x + s * subfr_length; + x1 = -silk_LSHIFT32( (opus_int32)x_ptr[ n ], 16 - rshifts ); /* Q(16-rshifts) */ + x2 = -silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], 16 - rshifts ); /* Q(16-rshifts) */ + tmp1 = silk_LSHIFT32( (opus_int32)x_ptr[ n ], QA - 16 ); /* Q(QA-16) */ + tmp2 = silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], QA - 16 ); /* Q(QA-16) */ + for( k = 0; k < n; k++ ) { + C_first_row[ k ] = silk_SMLAWB( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts ) */ + C_last_row[ k ] = silk_SMLAWB( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts ) */ + Atmp_QA = Af_QA[ k ]; + tmp1 = silk_SMLAWB( tmp1, Atmp_QA, x_ptr[ n - k - 1 ] ); /* Q(QA-16) */ + tmp2 = silk_SMLAWB( tmp2, Atmp_QA, x_ptr[ subfr_length - n + k ] ); /* Q(QA-16) */ + } + tmp1 = silk_LSHIFT32( -tmp1, 32 - QA - rshifts ); /* Q(16-rshifts) */ + tmp2 = silk_LSHIFT32( -tmp2, 32 - QA - rshifts ); /* Q(16-rshifts) */ + for( k = 0; k <= n; k++ ) { + CAf[ k ] = silk_SMLAWB( CAf[ k ], tmp1, x_ptr[ n - k ] ); /* Q( -rshift ) */ + CAb[ k ] = silk_SMLAWB( CAb[ k ], tmp2, x_ptr[ subfr_length - n + k - 1 ] ); /* Q( -rshift ) */ + } + } + } else { + for( s = 0; s < nb_subfr; s++ ) { + x_ptr = x + s * subfr_length; + x1 = -silk_LSHIFT32( (opus_int32)x_ptr[ n ], -rshifts ); /* Q( -rshifts ) */ + x2 = -silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], -rshifts ); /* Q( -rshifts ) */ + tmp1 = silk_LSHIFT32( (opus_int32)x_ptr[ n ], 17 ); /* Q17 */ + tmp2 = silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n - 1 ], 17 ); /* Q17 */ + for( k = 0; k < n; k++ ) { + C_first_row[ k ] = silk_MLA( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts ) */ + C_last_row[ k ] = silk_MLA( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts ) */ + Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 17 ); /* Q17 */ + tmp1 = silk_MLA( tmp1, x_ptr[ n - k - 1 ], Atmp1 ); /* Q17 */ + tmp2 = silk_MLA( tmp2, x_ptr[ subfr_length - n + k ], Atmp1 ); /* Q17 */ + } + tmp1 = -tmp1; /* Q17 */ + tmp2 = -tmp2; /* Q17 */ + for( k = 0; k <= n; k++ ) { + CAf[ k ] = silk_SMLAWW( CAf[ k ], tmp1, + silk_LSHIFT32( (opus_int32)x_ptr[ n - k ], -rshifts - 1 ) ); /* Q( -rshift ) */ + CAb[ k ] = silk_SMLAWW( CAb[ k ], tmp2, + silk_LSHIFT32( (opus_int32)x_ptr[ subfr_length - n + k - 1 ], -rshifts - 1 ) ); /* Q( -rshift ) */ + } + } + } + + /* Calculate nominator and denominator for the next order reflection (parcor) coefficient */ + tmp1 = C_first_row[ n ]; /* Q( -rshifts ) */ + tmp2 = C_last_row[ n ]; /* Q( -rshifts ) */ + num = 0; /* Q( -rshifts ) */ + nrg = silk_ADD32( CAb[ 0 ], CAf[ 0 ] ); /* Q( 1-rshifts ) */ + for( k = 0; k < n; k++ ) { + Atmp_QA = Af_QA[ k ]; + lz = silk_CLZ32( silk_abs( Atmp_QA ) ) - 1; + lz = silk_min( 32 - QA, lz ); + Atmp1 = silk_LSHIFT32( Atmp_QA, lz ); /* Q( QA + lz ) */ + + tmp1 = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( C_last_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */ + tmp2 = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( C_first_row[ n - k - 1 ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */ + num = silk_ADD_LSHIFT32( num, silk_SMMUL( CAb[ n - k ], Atmp1 ), 32 - QA - lz ); /* Q( -rshifts ) */ + nrg = silk_ADD_LSHIFT32( nrg, silk_SMMUL( silk_ADD32( CAb[ k + 1 ], CAf[ k + 1 ] ), + Atmp1 ), 32 - QA - lz ); /* Q( 1-rshifts ) */ + } + CAf[ n + 1 ] = tmp1; /* Q( -rshifts ) */ + CAb[ n + 1 ] = tmp2; /* Q( -rshifts ) */ + num = silk_ADD32( num, tmp2 ); /* Q( -rshifts ) */ + num = silk_LSHIFT32( -num, 1 ); /* Q( 1-rshifts ) */ + + /* Calculate the next order reflection (parcor) coefficient */ + if( silk_abs( num ) < nrg ) { + rc_Q31 = silk_DIV32_varQ( num, nrg, 31 ); + } else { + rc_Q31 = ( num > 0 ) ? silk_int32_MAX : silk_int32_MIN; + } + + /* Update inverse prediction gain */ + tmp1 = ( (opus_int32)1 << 30 ) - silk_SMMUL( rc_Q31, rc_Q31 ); + tmp1 = silk_LSHIFT( silk_SMMUL( invGain_Q30, tmp1 ), 2 ); + if( tmp1 <= minInvGain_Q30 ) { + /* Max prediction gain exceeded; set reflection coefficient such that max prediction gain is exactly hit */ + tmp2 = ( (opus_int32)1 << 30 ) - silk_DIV32_varQ( minInvGain_Q30, invGain_Q30, 30 ); /* Q30 */ + rc_Q31 = silk_SQRT_APPROX( tmp2 ); /* Q15 */ + /* Newton-Raphson iteration */ + rc_Q31 = silk_RSHIFT32( rc_Q31 + silk_DIV32( tmp2, rc_Q31 ), 1 ); /* Q15 */ + rc_Q31 = silk_LSHIFT32( rc_Q31, 16 ); /* Q31 */ + if( num < 0 ) { + /* Ensure adjusted reflection coefficients has the original sign */ + rc_Q31 = -rc_Q31; + } + invGain_Q30 = minInvGain_Q30; + reached_max_gain = 1; + } else { + invGain_Q30 = tmp1; + } + + /* Update the AR coefficients */ + for( k = 0; k < (n + 1) >> 1; k++ ) { + tmp1 = Af_QA[ k ]; /* QA */ + tmp2 = Af_QA[ n - k - 1 ]; /* QA */ + Af_QA[ k ] = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( tmp2, rc_Q31 ), 1 ); /* QA */ + Af_QA[ n - k - 1 ] = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( tmp1, rc_Q31 ), 1 ); /* QA */ + } + Af_QA[ n ] = silk_RSHIFT32( rc_Q31, 31 - QA ); /* QA */ + + if( reached_max_gain ) { + /* Reached max prediction gain; set remaining coefficients to zero and exit loop */ + for( k = n + 1; k < D; k++ ) { + Af_QA[ k ] = 0; + } + break; + } + + /* Update C * Af and C * Ab */ + for( k = 0; k <= n + 1; k++ ) { + tmp1 = CAf[ k ]; /* Q( -rshifts ) */ + tmp2 = CAb[ n - k + 1 ]; /* Q( -rshifts ) */ + CAf[ k ] = silk_ADD_LSHIFT32( tmp1, silk_SMMUL( tmp2, rc_Q31 ), 1 ); /* Q( -rshifts ) */ + CAb[ n - k + 1 ] = silk_ADD_LSHIFT32( tmp2, silk_SMMUL( tmp1, rc_Q31 ), 1 ); /* Q( -rshifts ) */ + } + } + + if( reached_max_gain ) { + for( k = 0; k < D; k++ ) { + /* Scale coefficients */ + A_Q16[ k ] = -silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 ); + } + /* Subtract energy of preceding samples from C0 */ + if( rshifts > 0 ) { + for( s = 0; s < nb_subfr; s++ ) { + x_ptr = x + s * subfr_length; + C0 -= (opus_int32)silk_RSHIFT64( silk_inner_prod16_aligned_64( x_ptr, x_ptr, D ), rshifts ); + } + } else { + for( s = 0; s < nb_subfr; s++ ) { + x_ptr = x + s * subfr_length; + C0 -= silk_LSHIFT32( silk_inner_prod_aligned( x_ptr, x_ptr, D ), -rshifts ); + } + } + /* Approximate residual energy */ + *res_nrg = silk_LSHIFT( silk_SMMUL( invGain_Q30, C0 ), 2 ); + *res_nrg_Q = -rshifts; + } else { + /* Return residual energy */ + nrg = CAf[ 0 ]; /* Q( -rshifts ) */ + tmp1 = (opus_int32)1 << 16; /* Q16 */ + for( k = 0; k < D; k++ ) { + Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 16 ); /* Q16 */ + nrg = silk_SMLAWW( nrg, CAf[ k + 1 ], Atmp1 ); /* Q( -rshifts ) */ + tmp1 = silk_SMLAWW( tmp1, Atmp1, Atmp1 ); /* Q16 */ + A_Q16[ k ] = -Atmp1; + } + *res_nrg = silk_SMLAWW( nrg, silk_SMMUL( SILK_FIX_CONST( FIND_LPC_COND_FAC, 32 ), C0 ), -tmp1 );/* Q( -rshifts ) */ + *res_nrg_Q = -rshifts; + } +} diff --git a/src/opus-1.1/silk/fixed/corrMatrix_FIX.c b/src/opus-1.1/silk/fixed/corrMatrix_FIX.c new file mode 100644 index 00000000..c6172705 --- /dev/null +++ b/src/opus-1.1/silk/fixed/corrMatrix_FIX.c @@ -0,0 +1,156 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/********************************************************************** + * Correlation Matrix Computations for LS estimate. + **********************************************************************/ + +#include "main_FIX.h" + +/* Calculates correlation vector X'*t */ +void silk_corrVector_FIX( + const opus_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */ + const opus_int16 *t, /* I Target vector [L] */ + const opus_int L, /* I Length of vectors */ + const opus_int order, /* I Max lag for correlation */ + opus_int32 *Xt, /* O Pointer to X'*t correlation vector [order] */ + const opus_int rshifts /* I Right shifts of correlations */ +) +{ + opus_int lag, i; + const opus_int16 *ptr1, *ptr2; + opus_int32 inner_prod; + + ptr1 = &x[ order - 1 ]; /* Points to first sample of column 0 of X: X[:,0] */ + ptr2 = t; + /* Calculate X'*t */ + if( rshifts > 0 ) { + /* Right shifting used */ + for( lag = 0; lag < order; lag++ ) { + inner_prod = 0; + for( i = 0; i < L; i++ ) { + inner_prod += silk_RSHIFT32( silk_SMULBB( ptr1[ i ], ptr2[i] ), rshifts ); + } + Xt[ lag ] = inner_prod; /* X[:,lag]'*t */ + ptr1--; /* Go to next column of X */ + } + } else { + silk_assert( rshifts == 0 ); + for( lag = 0; lag < order; lag++ ) { + Xt[ lag ] = silk_inner_prod_aligned( ptr1, ptr2, L ); /* X[:,lag]'*t */ + ptr1--; /* Go to next column of X */ + } + } +} + +/* Calculates correlation matrix X'*X */ +void silk_corrMatrix_FIX( + const opus_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */ + const opus_int L, /* I Length of vectors */ + const opus_int order, /* I Max lag for correlation */ + const opus_int head_room, /* I Desired headroom */ + opus_int32 *XX, /* O Pointer to X'*X correlation matrix [ order x order ] */ + opus_int *rshifts /* I/O Right shifts of correlations */ +) +{ + opus_int i, j, lag, rshifts_local, head_room_rshifts; + opus_int32 energy; + const opus_int16 *ptr1, *ptr2; + + /* Calculate energy to find shift used to fit in 32 bits */ + silk_sum_sqr_shift( &energy, &rshifts_local, x, L + order - 1 ); + /* Add shifts to get the desired head room */ + head_room_rshifts = silk_max( head_room - silk_CLZ32( energy ), 0 ); + + energy = silk_RSHIFT32( energy, head_room_rshifts ); + rshifts_local += head_room_rshifts; + + /* Calculate energy of first column (0) of X: X[:,0]'*X[:,0] */ + /* Remove contribution of first order - 1 samples */ + for( i = 0; i < order - 1; i++ ) { + energy -= silk_RSHIFT32( silk_SMULBB( x[ i ], x[ i ] ), rshifts_local ); + } + if( rshifts_local < *rshifts ) { + /* Adjust energy */ + energy = silk_RSHIFT32( energy, *rshifts - rshifts_local ); + rshifts_local = *rshifts; + } + + /* Calculate energy of remaining columns of X: X[:,j]'*X[:,j] */ + /* Fill out the diagonal of the correlation matrix */ + matrix_ptr( XX, 0, 0, order ) = energy; + ptr1 = &x[ order - 1 ]; /* First sample of column 0 of X */ + for( j = 1; j < order; j++ ) { + energy = silk_SUB32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ L - j ], ptr1[ L - j ] ), rshifts_local ) ); + energy = silk_ADD32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ -j ], ptr1[ -j ] ), rshifts_local ) ); + matrix_ptr( XX, j, j, order ) = energy; + } + + ptr2 = &x[ order - 2 ]; /* First sample of column 1 of X */ + /* Calculate the remaining elements of the correlation matrix */ + if( rshifts_local > 0 ) { + /* Right shifting used */ + for( lag = 1; lag < order; lag++ ) { + /* Inner product of column 0 and column lag: X[:,0]'*X[:,lag] */ + energy = 0; + for( i = 0; i < L; i++ ) { + energy += silk_RSHIFT32( silk_SMULBB( ptr1[ i ], ptr2[i] ), rshifts_local ); + } + /* Calculate remaining off diagonal: X[:,j]'*X[:,j + lag] */ + matrix_ptr( XX, lag, 0, order ) = energy; + matrix_ptr( XX, 0, lag, order ) = energy; + for( j = 1; j < ( order - lag ); j++ ) { + energy = silk_SUB32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ), rshifts_local ) ); + energy = silk_ADD32( energy, silk_RSHIFT32( silk_SMULBB( ptr1[ -j ], ptr2[ -j ] ), rshifts_local ) ); + matrix_ptr( XX, lag + j, j, order ) = energy; + matrix_ptr( XX, j, lag + j, order ) = energy; + } + ptr2--; /* Update pointer to first sample of next column (lag) in X */ + } + } else { + for( lag = 1; lag < order; lag++ ) { + /* Inner product of column 0 and column lag: X[:,0]'*X[:,lag] */ + energy = silk_inner_prod_aligned( ptr1, ptr2, L ); + matrix_ptr( XX, lag, 0, order ) = energy; + matrix_ptr( XX, 0, lag, order ) = energy; + /* Calculate remaining off diagonal: X[:,j]'*X[:,j + lag] */ + for( j = 1; j < ( order - lag ); j++ ) { + energy = silk_SUB32( energy, silk_SMULBB( ptr1[ L - j ], ptr2[ L - j ] ) ); + energy = silk_SMLABB( energy, ptr1[ -j ], ptr2[ -j ] ); + matrix_ptr( XX, lag + j, j, order ) = energy; + matrix_ptr( XX, j, lag + j, order ) = energy; + } + ptr2--;/* Update pointer to first sample of next column (lag) in X */ + } + } + *rshifts = rshifts_local; +} + diff --git a/src/opus-1.1/silk/fixed/encode_frame_FIX.c b/src/opus-1.1/silk/fixed/encode_frame_FIX.c new file mode 100644 index 00000000..b490986b --- /dev/null +++ b/src/opus-1.1/silk/fixed/encode_frame_FIX.c @@ -0,0 +1,385 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main_FIX.h" +#include "stack_alloc.h" +#include "tuning_parameters.h" + +/* Low Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode with lower bitrate */ +static OPUS_INLINE void silk_LBRR_encode_FIX( + silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ + silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk FIX encoder control struct */ + const opus_int32 xfw_Q3[], /* I Input signal */ + opus_int condCoding /* I The type of conditional coding used so far for this frame */ +); + +void silk_encode_do_VAD_FIX( + silk_encoder_state_FIX *psEnc /* I/O Pointer to Silk FIX encoder state */ +) +{ + /****************************/ + /* Voice Activity Detection */ + /****************************/ + silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf + 1 ); + + /**************************************************/ + /* Convert speech activity into VAD and DTX flags */ + /**************************************************/ + if( psEnc->sCmn.speech_activity_Q8 < SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ) ) { + psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY; + psEnc->sCmn.noSpeechCounter++; + if( psEnc->sCmn.noSpeechCounter < NB_SPEECH_FRAMES_BEFORE_DTX ) { + psEnc->sCmn.inDTX = 0; + } else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) { + psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX; + psEnc->sCmn.inDTX = 0; + } + psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 0; + } else { + psEnc->sCmn.noSpeechCounter = 0; + psEnc->sCmn.inDTX = 0; + psEnc->sCmn.indices.signalType = TYPE_UNVOICED; + psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 1; + } +} + +/****************/ +/* Encode frame */ +/****************/ +opus_int silk_encode_frame_FIX( + silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ + opus_int32 *pnBytesOut, /* O Pointer to number of payload bytes; */ + ec_enc *psRangeEnc, /* I/O compressor data structure */ + opus_int condCoding, /* I The type of conditional coding to use */ + opus_int maxBits, /* I If > 0: maximum number of output bits */ + opus_int useCBR /* I Flag to force constant-bitrate operation */ +) +{ + silk_encoder_control_FIX sEncCtrl; + opus_int i, iter, maxIter, found_upper, found_lower, ret = 0; + opus_int16 *x_frame; + ec_enc sRangeEnc_copy, sRangeEnc_copy2; + silk_nsq_state sNSQ_copy, sNSQ_copy2; + opus_int32 seed_copy, nBits, nBits_lower, nBits_upper, gainMult_lower, gainMult_upper; + opus_int32 gainsID, gainsID_lower, gainsID_upper; + opus_int16 gainMult_Q8; + opus_int16 ec_prevLagIndex_copy; + opus_int ec_prevSignalType_copy; + opus_int8 LastGainIndex_copy2; + SAVE_STACK; + + /* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */ + LastGainIndex_copy2 = nBits_lower = nBits_upper = gainMult_lower = gainMult_upper = 0; + + psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3; + + /**************************************************************/ + /* Set up Input Pointers, and insert frame in input buffer */ + /*************************************************************/ + /* start of frame to encode */ + x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length; + + /***************************************/ + /* Ensure smooth bandwidth transitions */ + /***************************************/ + silk_LP_variable_cutoff( &psEnc->sCmn.sLP, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length ); + + /*******************************************/ + /* Copy new frame to front of input buffer */ + /*******************************************/ + silk_memcpy( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length * sizeof( opus_int16 ) ); + + if( !psEnc->sCmn.prefillFlag ) { + VARDECL( opus_int32, xfw_Q3 ); + VARDECL( opus_int16, res_pitch ); + VARDECL( opus_uint8, ec_buf_copy ); + opus_int16 *res_pitch_frame; + + ALLOC( res_pitch, + psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + + psEnc->sCmn.ltp_mem_length, opus_int16 ); + /* start of pitch LPC residual frame */ + res_pitch_frame = res_pitch + psEnc->sCmn.ltp_mem_length; + + /*****************************************/ + /* Find pitch lags, initial LPC analysis */ + /*****************************************/ + silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame, psEnc->sCmn.arch ); + + /************************/ + /* Noise shape analysis */ + /************************/ + silk_noise_shape_analysis_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame, psEnc->sCmn.arch ); + + /***************************************************/ + /* Find linear prediction coefficients (LPC + LTP) */ + /***************************************************/ + silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch, x_frame, condCoding ); + + /****************************************/ + /* Process gains */ + /****************************************/ + silk_process_gains_FIX( psEnc, &sEncCtrl, condCoding ); + + /*****************************************/ + /* Prefiltering for noise shaper */ + /*****************************************/ + ALLOC( xfw_Q3, psEnc->sCmn.frame_length, opus_int32 ); + silk_prefilter_FIX( psEnc, &sEncCtrl, xfw_Q3, x_frame ); + + /****************************************/ + /* Low Bitrate Redundant Encoding */ + /****************************************/ + silk_LBRR_encode_FIX( psEnc, &sEncCtrl, xfw_Q3, condCoding ); + + /* Loop over quantizer and entropy coding to control bitrate */ + maxIter = 6; + gainMult_Q8 = SILK_FIX_CONST( 1, 8 ); + found_lower = 0; + found_upper = 0; + gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr ); + gainsID_lower = -1; + gainsID_upper = -1; + /* Copy part of the input state */ + silk_memcpy( &sRangeEnc_copy, psRangeEnc, sizeof( ec_enc ) ); + silk_memcpy( &sNSQ_copy, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); + seed_copy = psEnc->sCmn.indices.Seed; + ec_prevLagIndex_copy = psEnc->sCmn.ec_prevLagIndex; + ec_prevSignalType_copy = psEnc->sCmn.ec_prevSignalType; + ALLOC( ec_buf_copy, 1275, opus_uint8 ); + for( iter = 0; ; iter++ ) { + if( gainsID == gainsID_lower ) { + nBits = nBits_lower; + } else if( gainsID == gainsID_upper ) { + nBits = nBits_upper; + } else { + /* Restore part of the input state */ + if( iter > 0 ) { + silk_memcpy( psRangeEnc, &sRangeEnc_copy, sizeof( ec_enc ) ); + silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy, sizeof( silk_nsq_state ) ); + psEnc->sCmn.indices.Seed = seed_copy; + psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy; + psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy; + } + + /*****************************************/ + /* Noise shaping quantization */ + /*****************************************/ + if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) { + silk_NSQ_del_dec( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw_Q3, psEnc->sCmn.pulses, + sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14, + sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14 ); + } else { + silk_NSQ( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw_Q3, psEnc->sCmn.pulses, + sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14, + sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14 ); + } + + /****************************************/ + /* Encode Parameters */ + /****************************************/ + silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding ); + + /****************************************/ + /* Encode Excitation Signal */ + /****************************************/ + silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType, + psEnc->sCmn.pulses, psEnc->sCmn.frame_length ); + + nBits = ec_tell( psRangeEnc ); + + if( useCBR == 0 && iter == 0 && nBits <= maxBits ) { + break; + } + } + + if( iter == maxIter ) { + if( found_lower && ( gainsID == gainsID_lower || nBits > maxBits ) ) { + /* Restore output state from earlier iteration that did meet the bitrate budget */ + silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) ); + silk_assert( sRangeEnc_copy2.offs <= 1275 ); + silk_memcpy( psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs ); + silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy2, sizeof( silk_nsq_state ) ); + psEnc->sShape.LastGainIndex = LastGainIndex_copy2; + } + break; + } + + if( nBits > maxBits ) { + if( found_lower == 0 && iter >= 2 ) { + /* Adjust the quantizer's rate/distortion tradeoff and discard previous "upper" results */ + sEncCtrl.Lambda_Q10 = silk_ADD_RSHIFT32( sEncCtrl.Lambda_Q10, sEncCtrl.Lambda_Q10, 1 ); + found_upper = 0; + gainsID_upper = -1; + } else { + found_upper = 1; + nBits_upper = nBits; + gainMult_upper = gainMult_Q8; + gainsID_upper = gainsID; + } + } else if( nBits < maxBits - 5 ) { + found_lower = 1; + nBits_lower = nBits; + gainMult_lower = gainMult_Q8; + if( gainsID != gainsID_lower ) { + gainsID_lower = gainsID; + /* Copy part of the output state */ + silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) ); + silk_assert( psRangeEnc->offs <= 1275 ); + silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs ); + silk_memcpy( &sNSQ_copy2, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); + LastGainIndex_copy2 = psEnc->sShape.LastGainIndex; + } + } else { + /* Within 5 bits of budget: close enough */ + break; + } + + if( ( found_lower & found_upper ) == 0 ) { + /* Adjust gain according to high-rate rate/distortion curve */ + opus_int32 gain_factor_Q16; + gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) ); + gain_factor_Q16 = silk_min_32( gain_factor_Q16, SILK_FIX_CONST( 2, 16 ) ); + if( nBits > maxBits ) { + gain_factor_Q16 = silk_max_32( gain_factor_Q16, SILK_FIX_CONST( 1.3, 16 ) ); + } + gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 ); + } else { + /* Adjust gain by interpolating */ + gainMult_Q8 = gainMult_lower + silk_DIV32_16( silk_MUL( gainMult_upper - gainMult_lower, maxBits - nBits_lower ), nBits_upper - nBits_lower ); + /* New gain multplier must be between 25% and 75% of old range (note that gainMult_upper < gainMult_lower) */ + if( gainMult_Q8 > silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ) ) { + gainMult_Q8 = silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ); + } else + if( gainMult_Q8 < silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ) ) { + gainMult_Q8 = silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ); + } + } + + for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { + sEncCtrl.Gains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], gainMult_Q8 ), 8 ); + } + + /* Quantize gains */ + psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev; + silk_gains_quant( psEnc->sCmn.indices.GainsIndices, sEncCtrl.Gains_Q16, + &psEnc->sShape.LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); + + /* Unique identifier of gains vector */ + gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr ); + } + } + + /* Update input buffer */ + silk_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ], + ( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( opus_int16 ) ); + + /* Exit without entropy coding */ + if( psEnc->sCmn.prefillFlag ) { + /* No payload */ + *pnBytesOut = 0; + RESTORE_STACK; + return ret; + } + + /* Parameters needed for next frame */ + psEnc->sCmn.prevLag = sEncCtrl.pitchL[ psEnc->sCmn.nb_subfr - 1 ]; + psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType; + + /****************************************/ + /* Finalize payload */ + /****************************************/ + psEnc->sCmn.first_frame_after_reset = 0; + /* Payload size */ + *pnBytesOut = silk_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 ); + + RESTORE_STACK; + return ret; +} + +/* Low-Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode excitation at lower bitrate */ +static OPUS_INLINE void silk_LBRR_encode_FIX( + silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ + silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk FIX encoder control struct */ + const opus_int32 xfw_Q3[], /* I Input signal */ + opus_int condCoding /* I The type of conditional coding used so far for this frame */ +) +{ + opus_int32 TempGains_Q16[ MAX_NB_SUBFR ]; + SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesEncoded ]; + silk_nsq_state sNSQ_LBRR; + + /*******************************************/ + /* Control use of inband LBRR */ + /*******************************************/ + if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SILK_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) { + psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded ] = 1; + + /* Copy noise shaping quantizer state and quantization indices from regular encoding */ + silk_memcpy( &sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); + silk_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) ); + + /* Save original gains */ + silk_memcpy( TempGains_Q16, psEncCtrl->Gains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) ); + + if( psEnc->sCmn.nFramesEncoded == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded - 1 ] == 0 ) { + /* First frame in packet or previous frame not LBRR coded */ + psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex; + + /* Increase Gains to get target LBRR rate */ + psIndices_LBRR->GainsIndices[ 0 ] = psIndices_LBRR->GainsIndices[ 0 ] + psEnc->sCmn.LBRR_GainIncreases; + psIndices_LBRR->GainsIndices[ 0 ] = silk_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 ); + } + + /* Decode to get gains in sync with decoder */ + /* Overwrite unquantized gains with quantized gains */ + silk_gains_dequant( psEncCtrl->Gains_Q16, psIndices_LBRR->GainsIndices, + &psEnc->sCmn.LBRRprevLastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); + + /*****************************************/ + /* Noise shaping quantization */ + /*****************************************/ + if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) { + silk_NSQ_del_dec( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, xfw_Q3, + psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14, + psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14, + psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 ); + } else { + silk_NSQ( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, xfw_Q3, + psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14, + psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14, + psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 ); + } + + /* Restore original gains */ + silk_memcpy( psEncCtrl->Gains_Q16, TempGains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) ); + } +} diff --git a/src/opus-1.1/silk/fixed/find_LPC_FIX.c b/src/opus-1.1/silk/fixed/find_LPC_FIX.c new file mode 100644 index 00000000..783d32e2 --- /dev/null +++ b/src/opus-1.1/silk/fixed/find_LPC_FIX.c @@ -0,0 +1,151 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main_FIX.h" +#include "stack_alloc.h" +#include "tuning_parameters.h" + +/* Finds LPC vector from correlations, and converts to NLSF */ +void silk_find_LPC_FIX( + silk_encoder_state *psEncC, /* I/O Encoder state */ + opus_int16 NLSF_Q15[], /* O NLSFs */ + const opus_int16 x[], /* I Input signal */ + const opus_int32 minInvGain_Q30 /* I Inverse of max prediction gain */ +) +{ + opus_int k, subfr_length; + opus_int32 a_Q16[ MAX_LPC_ORDER ]; + opus_int isInterpLower, shift; + opus_int32 res_nrg0, res_nrg1; + opus_int rshift0, rshift1; + + /* Used only for LSF interpolation */ + opus_int32 a_tmp_Q16[ MAX_LPC_ORDER ], res_nrg_interp, res_nrg, res_tmp_nrg; + opus_int res_nrg_interp_Q, res_nrg_Q, res_tmp_nrg_Q; + opus_int16 a_tmp_Q12[ MAX_LPC_ORDER ]; + opus_int16 NLSF0_Q15[ MAX_LPC_ORDER ]; + SAVE_STACK; + + subfr_length = psEncC->subfr_length + psEncC->predictLPCOrder; + + /* Default: no interpolation */ + psEncC->indices.NLSFInterpCoef_Q2 = 4; + + /* Burg AR analysis for the full frame */ + silk_burg_modified( &res_nrg, &res_nrg_Q, a_Q16, x, minInvGain_Q30, subfr_length, psEncC->nb_subfr, psEncC->predictLPCOrder, psEncC->arch ); + + if( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) { + VARDECL( opus_int16, LPC_res ); + + /* Optimal solution for last 10 ms */ + silk_burg_modified( &res_tmp_nrg, &res_tmp_nrg_Q, a_tmp_Q16, x + 2 * subfr_length, minInvGain_Q30, subfr_length, 2, psEncC->predictLPCOrder, psEncC->arch ); + + /* subtract residual energy here, as that's easier than adding it to the */ + /* residual energy of the first 10 ms in each iteration of the search below */ + shift = res_tmp_nrg_Q - res_nrg_Q; + if( shift >= 0 ) { + if( shift < 32 ) { + res_nrg = res_nrg - silk_RSHIFT( res_tmp_nrg, shift ); + } + } else { + silk_assert( shift > -32 ); + res_nrg = silk_RSHIFT( res_nrg, -shift ) - res_tmp_nrg; + res_nrg_Q = res_tmp_nrg_Q; + } + + /* Convert to NLSFs */ + silk_A2NLSF( NLSF_Q15, a_tmp_Q16, psEncC->predictLPCOrder ); + + ALLOC( LPC_res, 2 * subfr_length, opus_int16 ); + + /* Search over interpolation indices to find the one with lowest residual energy */ + for( k = 3; k >= 0; k-- ) { + /* Interpolate NLSFs for first half */ + silk_interpolate( NLSF0_Q15, psEncC->prev_NLSFq_Q15, NLSF_Q15, k, psEncC->predictLPCOrder ); + + /* Convert to LPC for residual energy evaluation */ + silk_NLSF2A( a_tmp_Q12, NLSF0_Q15, psEncC->predictLPCOrder ); + + /* Calculate residual energy with NLSF interpolation */ + silk_LPC_analysis_filter( LPC_res, x, a_tmp_Q12, 2 * subfr_length, psEncC->predictLPCOrder ); + + silk_sum_sqr_shift( &res_nrg0, &rshift0, LPC_res + psEncC->predictLPCOrder, subfr_length - psEncC->predictLPCOrder ); + silk_sum_sqr_shift( &res_nrg1, &rshift1, LPC_res + psEncC->predictLPCOrder + subfr_length, subfr_length - psEncC->predictLPCOrder ); + + /* Add subframe energies from first half frame */ + shift = rshift0 - rshift1; + if( shift >= 0 ) { + res_nrg1 = silk_RSHIFT( res_nrg1, shift ); + res_nrg_interp_Q = -rshift0; + } else { + res_nrg0 = silk_RSHIFT( res_nrg0, -shift ); + res_nrg_interp_Q = -rshift1; + } + res_nrg_interp = silk_ADD32( res_nrg0, res_nrg1 ); + + /* Compare with first half energy without NLSF interpolation, or best interpolated value so far */ + shift = res_nrg_interp_Q - res_nrg_Q; + if( shift >= 0 ) { + if( silk_RSHIFT( res_nrg_interp, shift ) < res_nrg ) { + isInterpLower = silk_TRUE; + } else { + isInterpLower = silk_FALSE; + } + } else { + if( -shift < 32 ) { + if( res_nrg_interp < silk_RSHIFT( res_nrg, -shift ) ) { + isInterpLower = silk_TRUE; + } else { + isInterpLower = silk_FALSE; + } + } else { + isInterpLower = silk_FALSE; + } + } + + /* Determine whether current interpolated NLSFs are best so far */ + if( isInterpLower == silk_TRUE ) { + /* Interpolation has lower residual energy */ + res_nrg = res_nrg_interp; + res_nrg_Q = res_nrg_interp_Q; + psEncC->indices.NLSFInterpCoef_Q2 = (opus_int8)k; + } + } + } + + if( psEncC->indices.NLSFInterpCoef_Q2 == 4 ) { + /* NLSF interpolation is currently inactive, calculate NLSFs from full frame AR coefficients */ + silk_A2NLSF( NLSF_Q15, a_Q16, psEncC->predictLPCOrder ); + } + + silk_assert( psEncC->indices.NLSFInterpCoef_Q2 == 4 || ( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) ); + RESTORE_STACK; +} diff --git a/src/opus-1.1/silk/fixed/find_LTP_FIX.c b/src/opus-1.1/silk/fixed/find_LTP_FIX.c new file mode 100644 index 00000000..8c4d7037 --- /dev/null +++ b/src/opus-1.1/silk/fixed/find_LTP_FIX.c @@ -0,0 +1,244 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main_FIX.h" +#include "tuning_parameters.h" + +/* Head room for correlations */ +#define LTP_CORRS_HEAD_ROOM 2 + +void silk_fit_LTP( + opus_int32 LTP_coefs_Q16[ LTP_ORDER ], + opus_int16 LTP_coefs_Q14[ LTP_ORDER ] +); + +void silk_find_LTP_FIX( + opus_int16 b_Q14[ MAX_NB_SUBFR * LTP_ORDER ], /* O LTP coefs */ + opus_int32 WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */ + opus_int *LTPredCodGain_Q7, /* O LTP coding gain */ + const opus_int16 r_lpc[], /* I residual signal after LPC signal + state for first 10 ms */ + const opus_int lag[ MAX_NB_SUBFR ], /* I LTP lags */ + const opus_int32 Wght_Q15[ MAX_NB_SUBFR ], /* I weights */ + const opus_int subfr_length, /* I subframe length */ + const opus_int nb_subfr, /* I number of subframes */ + const opus_int mem_offset, /* I number of samples in LTP memory */ + opus_int corr_rshifts[ MAX_NB_SUBFR ] /* O right shifts applied to correlations */ +) +{ + opus_int i, k, lshift; + const opus_int16 *r_ptr, *lag_ptr; + opus_int16 *b_Q14_ptr; + + opus_int32 regu; + opus_int32 *WLTP_ptr; + opus_int32 b_Q16[ LTP_ORDER ], delta_b_Q14[ LTP_ORDER ], d_Q14[ MAX_NB_SUBFR ], nrg[ MAX_NB_SUBFR ], g_Q26; + opus_int32 w[ MAX_NB_SUBFR ], WLTP_max, max_abs_d_Q14, max_w_bits; + + opus_int32 temp32, denom32; + opus_int extra_shifts; + opus_int rr_shifts, maxRshifts, maxRshifts_wxtra, LZs; + opus_int32 LPC_res_nrg, LPC_LTP_res_nrg, div_Q16; + opus_int32 Rr[ LTP_ORDER ], rr[ MAX_NB_SUBFR ]; + opus_int32 wd, m_Q12; + + b_Q14_ptr = b_Q14; + WLTP_ptr = WLTP; + r_ptr = &r_lpc[ mem_offset ]; + for( k = 0; k < nb_subfr; k++ ) { + lag_ptr = r_ptr - ( lag[ k ] + LTP_ORDER / 2 ); + + silk_sum_sqr_shift( &rr[ k ], &rr_shifts, r_ptr, subfr_length ); /* rr[ k ] in Q( -rr_shifts ) */ + + /* Assure headroom */ + LZs = silk_CLZ32( rr[k] ); + if( LZs < LTP_CORRS_HEAD_ROOM ) { + rr[ k ] = silk_RSHIFT_ROUND( rr[ k ], LTP_CORRS_HEAD_ROOM - LZs ); + rr_shifts += ( LTP_CORRS_HEAD_ROOM - LZs ); + } + corr_rshifts[ k ] = rr_shifts; + silk_corrMatrix_FIX( lag_ptr, subfr_length, LTP_ORDER, LTP_CORRS_HEAD_ROOM, WLTP_ptr, &corr_rshifts[ k ] ); /* WLTP_fix_ptr in Q( -corr_rshifts[ k ] ) */ + + /* The correlation vector always has lower max abs value than rr and/or RR so head room is assured */ + silk_corrVector_FIX( lag_ptr, r_ptr, subfr_length, LTP_ORDER, Rr, corr_rshifts[ k ] ); /* Rr_fix_ptr in Q( -corr_rshifts[ k ] ) */ + if( corr_rshifts[ k ] > rr_shifts ) { + rr[ k ] = silk_RSHIFT( rr[ k ], corr_rshifts[ k ] - rr_shifts ); /* rr[ k ] in Q( -corr_rshifts[ k ] ) */ + } + silk_assert( rr[ k ] >= 0 ); + + regu = 1; + regu = silk_SMLAWB( regu, rr[ k ], SILK_FIX_CONST( LTP_DAMPING/3, 16 ) ); + regu = silk_SMLAWB( regu, matrix_ptr( WLTP_ptr, 0, 0, LTP_ORDER ), SILK_FIX_CONST( LTP_DAMPING/3, 16 ) ); + regu = silk_SMLAWB( regu, matrix_ptr( WLTP_ptr, LTP_ORDER-1, LTP_ORDER-1, LTP_ORDER ), SILK_FIX_CONST( LTP_DAMPING/3, 16 ) ); + silk_regularize_correlations_FIX( WLTP_ptr, &rr[k], regu, LTP_ORDER ); + + silk_solve_LDL_FIX( WLTP_ptr, LTP_ORDER, Rr, b_Q16 ); /* WLTP_fix_ptr and Rr_fix_ptr both in Q(-corr_rshifts[k]) */ + + /* Limit and store in Q14 */ + silk_fit_LTP( b_Q16, b_Q14_ptr ); + + /* Calculate residual energy */ + nrg[ k ] = silk_residual_energy16_covar_FIX( b_Q14_ptr, WLTP_ptr, Rr, rr[ k ], LTP_ORDER, 14 ); /* nrg_fix in Q( -corr_rshifts[ k ] ) */ + + /* temp = Wght[ k ] / ( nrg[ k ] * Wght[ k ] + 0.01f * subfr_length ); */ + extra_shifts = silk_min_int( corr_rshifts[ k ], LTP_CORRS_HEAD_ROOM ); + denom32 = silk_LSHIFT_SAT32( silk_SMULWB( nrg[ k ], Wght_Q15[ k ] ), 1 + extra_shifts ) + /* Q( -corr_rshifts[ k ] + extra_shifts ) */ + silk_RSHIFT( silk_SMULWB( (opus_int32)subfr_length, 655 ), corr_rshifts[ k ] - extra_shifts ); /* Q( -corr_rshifts[ k ] + extra_shifts ) */ + denom32 = silk_max( denom32, 1 ); + silk_assert( ((opus_int64)Wght_Q15[ k ] << 16 ) < silk_int32_MAX ); /* Wght always < 0.5 in Q0 */ + temp32 = silk_DIV32( silk_LSHIFT( (opus_int32)Wght_Q15[ k ], 16 ), denom32 ); /* Q( 15 + 16 + corr_rshifts[k] - extra_shifts ) */ + temp32 = silk_RSHIFT( temp32, 31 + corr_rshifts[ k ] - extra_shifts - 26 ); /* Q26 */ + + /* Limit temp such that the below scaling never wraps around */ + WLTP_max = 0; + for( i = 0; i < LTP_ORDER * LTP_ORDER; i++ ) { + WLTP_max = silk_max( WLTP_ptr[ i ], WLTP_max ); + } + lshift = silk_CLZ32( WLTP_max ) - 1 - 3; /* keep 3 bits free for vq_nearest_neighbor_fix */ + silk_assert( 26 - 18 + lshift >= 0 ); + if( 26 - 18 + lshift < 31 ) { + temp32 = silk_min_32( temp32, silk_LSHIFT( (opus_int32)1, 26 - 18 + lshift ) ); + } + + silk_scale_vector32_Q26_lshift_18( WLTP_ptr, temp32, LTP_ORDER * LTP_ORDER ); /* WLTP_ptr in Q( 18 - corr_rshifts[ k ] ) */ + + w[ k ] = matrix_ptr( WLTP_ptr, LTP_ORDER/2, LTP_ORDER/2, LTP_ORDER ); /* w in Q( 18 - corr_rshifts[ k ] ) */ + silk_assert( w[k] >= 0 ); + + r_ptr += subfr_length; + b_Q14_ptr += LTP_ORDER; + WLTP_ptr += LTP_ORDER * LTP_ORDER; + } + + maxRshifts = 0; + for( k = 0; k < nb_subfr; k++ ) { + maxRshifts = silk_max_int( corr_rshifts[ k ], maxRshifts ); + } + + /* Compute LTP coding gain */ + if( LTPredCodGain_Q7 != NULL ) { + LPC_LTP_res_nrg = 0; + LPC_res_nrg = 0; + silk_assert( LTP_CORRS_HEAD_ROOM >= 2 ); /* Check that no overflow will happen when adding */ + for( k = 0; k < nb_subfr; k++ ) { + LPC_res_nrg = silk_ADD32( LPC_res_nrg, silk_RSHIFT( silk_ADD32( silk_SMULWB( rr[ k ], Wght_Q15[ k ] ), 1 ), 1 + ( maxRshifts - corr_rshifts[ k ] ) ) ); /* Q( -maxRshifts ) */ + LPC_LTP_res_nrg = silk_ADD32( LPC_LTP_res_nrg, silk_RSHIFT( silk_ADD32( silk_SMULWB( nrg[ k ], Wght_Q15[ k ] ), 1 ), 1 + ( maxRshifts - corr_rshifts[ k ] ) ) ); /* Q( -maxRshifts ) */ + } + LPC_LTP_res_nrg = silk_max( LPC_LTP_res_nrg, 1 ); /* avoid division by zero */ + + div_Q16 = silk_DIV32_varQ( LPC_res_nrg, LPC_LTP_res_nrg, 16 ); + *LTPredCodGain_Q7 = ( opus_int )silk_SMULBB( 3, silk_lin2log( div_Q16 ) - ( 16 << 7 ) ); + + silk_assert( *LTPredCodGain_Q7 == ( opus_int )silk_SAT16( silk_MUL( 3, silk_lin2log( div_Q16 ) - ( 16 << 7 ) ) ) ); + } + + /* smoothing */ + /* d = sum( B, 1 ); */ + b_Q14_ptr = b_Q14; + for( k = 0; k < nb_subfr; k++ ) { + d_Q14[ k ] = 0; + for( i = 0; i < LTP_ORDER; i++ ) { + d_Q14[ k ] += b_Q14_ptr[ i ]; + } + b_Q14_ptr += LTP_ORDER; + } + + /* m = ( w * d' ) / ( sum( w ) + 1e-3 ); */ + + /* Find maximum absolute value of d_Q14 and the bits used by w in Q0 */ + max_abs_d_Q14 = 0; + max_w_bits = 0; + for( k = 0; k < nb_subfr; k++ ) { + max_abs_d_Q14 = silk_max_32( max_abs_d_Q14, silk_abs( d_Q14[ k ] ) ); + /* w[ k ] is in Q( 18 - corr_rshifts[ k ] ) */ + /* Find bits needed in Q( 18 - maxRshifts ) */ + max_w_bits = silk_max_32( max_w_bits, 32 - silk_CLZ32( w[ k ] ) + corr_rshifts[ k ] - maxRshifts ); + } + + /* max_abs_d_Q14 = (5 << 15); worst case, i.e. LTP_ORDER * -silk_int16_MIN */ + silk_assert( max_abs_d_Q14 <= ( 5 << 15 ) ); + + /* How many bits is needed for w*d' in Q( 18 - maxRshifts ) in the worst case, of all d_Q14's being equal to max_abs_d_Q14 */ + extra_shifts = max_w_bits + 32 - silk_CLZ32( max_abs_d_Q14 ) - 14; + + /* Subtract what we got available; bits in output var plus maxRshifts */ + extra_shifts -= ( 32 - 1 - 2 + maxRshifts ); /* Keep sign bit free as well as 2 bits for accumulation */ + extra_shifts = silk_max_int( extra_shifts, 0 ); + + maxRshifts_wxtra = maxRshifts + extra_shifts; + + temp32 = silk_RSHIFT( 262, maxRshifts + extra_shifts ) + 1; /* 1e-3f in Q( 18 - (maxRshifts + extra_shifts) ) */ + wd = 0; + for( k = 0; k < nb_subfr; k++ ) { + /* w has at least 2 bits of headroom so no overflow should happen */ + temp32 = silk_ADD32( temp32, silk_RSHIFT( w[ k ], maxRshifts_wxtra - corr_rshifts[ k ] ) ); /* Q( 18 - maxRshifts_wxtra ) */ + wd = silk_ADD32( wd, silk_LSHIFT( silk_SMULWW( silk_RSHIFT( w[ k ], maxRshifts_wxtra - corr_rshifts[ k ] ), d_Q14[ k ] ), 2 ) ); /* Q( 18 - maxRshifts_wxtra ) */ + } + m_Q12 = silk_DIV32_varQ( wd, temp32, 12 ); + + b_Q14_ptr = b_Q14; + for( k = 0; k < nb_subfr; k++ ) { + /* w_fix[ k ] from Q( 18 - corr_rshifts[ k ] ) to Q( 16 ) */ + if( 2 - corr_rshifts[k] > 0 ) { + temp32 = silk_RSHIFT( w[ k ], 2 - corr_rshifts[ k ] ); + } else { + temp32 = silk_LSHIFT_SAT32( w[ k ], corr_rshifts[ k ] - 2 ); + } + + g_Q26 = silk_MUL( + silk_DIV32( + SILK_FIX_CONST( LTP_SMOOTHING, 26 ), + silk_RSHIFT( SILK_FIX_CONST( LTP_SMOOTHING, 26 ), 10 ) + temp32 ), /* Q10 */ + silk_LSHIFT_SAT32( silk_SUB_SAT32( (opus_int32)m_Q12, silk_RSHIFT( d_Q14[ k ], 2 ) ), 4 ) ); /* Q16 */ + + temp32 = 0; + for( i = 0; i < LTP_ORDER; i++ ) { + delta_b_Q14[ i ] = silk_max_16( b_Q14_ptr[ i ], 1638 ); /* 1638_Q14 = 0.1_Q0 */ + temp32 += delta_b_Q14[ i ]; /* Q14 */ + } + temp32 = silk_DIV32( g_Q26, temp32 ); /* Q14 -> Q12 */ + for( i = 0; i < LTP_ORDER; i++ ) { + b_Q14_ptr[ i ] = silk_LIMIT_32( (opus_int32)b_Q14_ptr[ i ] + silk_SMULWB( silk_LSHIFT_SAT32( temp32, 4 ), delta_b_Q14[ i ] ), -16000, 28000 ); + } + b_Q14_ptr += LTP_ORDER; + } +} + +void silk_fit_LTP( + opus_int32 LTP_coefs_Q16[ LTP_ORDER ], + opus_int16 LTP_coefs_Q14[ LTP_ORDER ] +) +{ + opus_int i; + + for( i = 0; i < LTP_ORDER; i++ ) { + LTP_coefs_Q14[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( LTP_coefs_Q16[ i ], 2 ) ); + } +} diff --git a/src/opus-1.1/silk/fixed/find_pitch_lags_FIX.c b/src/opus-1.1/silk/fixed/find_pitch_lags_FIX.c new file mode 100644 index 00000000..620f8dcd --- /dev/null +++ b/src/opus-1.1/silk/fixed/find_pitch_lags_FIX.c @@ -0,0 +1,145 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main_FIX.h" +#include "stack_alloc.h" +#include "tuning_parameters.h" + +/* Find pitch lags */ +void silk_find_pitch_lags_FIX( + silk_encoder_state_FIX *psEnc, /* I/O encoder state */ + silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */ + opus_int16 res[], /* O residual */ + const opus_int16 x[], /* I Speech signal */ + int arch /* I Run-time architecture */ +) +{ + opus_int buf_len, i, scale; + opus_int32 thrhld_Q13, res_nrg; + const opus_int16 *x_buf, *x_buf_ptr; + VARDECL( opus_int16, Wsig ); + opus_int16 *Wsig_ptr; + opus_int32 auto_corr[ MAX_FIND_PITCH_LPC_ORDER + 1 ]; + opus_int16 rc_Q15[ MAX_FIND_PITCH_LPC_ORDER ]; + opus_int32 A_Q24[ MAX_FIND_PITCH_LPC_ORDER ]; + opus_int16 A_Q12[ MAX_FIND_PITCH_LPC_ORDER ]; + SAVE_STACK; + + /******************************************/ + /* Set up buffer lengths etc based on Fs */ + /******************************************/ + buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length; + + /* Safety check */ + silk_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length ); + + x_buf = x - psEnc->sCmn.ltp_mem_length; + + /*************************************/ + /* Estimate LPC AR coefficients */ + /*************************************/ + + /* Calculate windowed signal */ + + ALLOC( Wsig, psEnc->sCmn.pitch_LPC_win_length, opus_int16 ); + + /* First LA_LTP samples */ + x_buf_ptr = x_buf + buf_len - psEnc->sCmn.pitch_LPC_win_length; + Wsig_ptr = Wsig; + silk_apply_sine_window( Wsig_ptr, x_buf_ptr, 1, psEnc->sCmn.la_pitch ); + + /* Middle un - windowed samples */ + Wsig_ptr += psEnc->sCmn.la_pitch; + x_buf_ptr += psEnc->sCmn.la_pitch; + silk_memcpy( Wsig_ptr, x_buf_ptr, ( psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 ) ) * sizeof( opus_int16 ) ); + + /* Last LA_LTP samples */ + Wsig_ptr += psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 ); + x_buf_ptr += psEnc->sCmn.pitch_LPC_win_length - silk_LSHIFT( psEnc->sCmn.la_pitch, 1 ); + silk_apply_sine_window( Wsig_ptr, x_buf_ptr, 2, psEnc->sCmn.la_pitch ); + + /* Calculate autocorrelation sequence */ + silk_autocorr( auto_corr, &scale, Wsig, psEnc->sCmn.pitch_LPC_win_length, psEnc->sCmn.pitchEstimationLPCOrder + 1, arch ); + + /* Add white noise, as fraction of energy */ + auto_corr[ 0 ] = silk_SMLAWB( auto_corr[ 0 ], auto_corr[ 0 ], SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) ) + 1; + + /* Calculate the reflection coefficients using schur */ + res_nrg = silk_schur( rc_Q15, auto_corr, psEnc->sCmn.pitchEstimationLPCOrder ); + + /* Prediction gain */ + psEncCtrl->predGain_Q16 = silk_DIV32_varQ( auto_corr[ 0 ], silk_max_int( res_nrg, 1 ), 16 ); + + /* Convert reflection coefficients to prediction coefficients */ + silk_k2a( A_Q24, rc_Q15, psEnc->sCmn.pitchEstimationLPCOrder ); + + /* Convert From 32 bit Q24 to 16 bit Q12 coefs */ + for( i = 0; i < psEnc->sCmn.pitchEstimationLPCOrder; i++ ) { + A_Q12[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT( A_Q24[ i ], 12 ) ); + } + + /* Do BWE */ + silk_bwexpander( A_Q12, psEnc->sCmn.pitchEstimationLPCOrder, SILK_FIX_CONST( FIND_PITCH_BANDWIDTH_EXPANSION, 16 ) ); + + /*****************************************/ + /* LPC analysis filtering */ + /*****************************************/ + silk_LPC_analysis_filter( res, x_buf, A_Q12, buf_len, psEnc->sCmn.pitchEstimationLPCOrder ); + + if( psEnc->sCmn.indices.signalType != TYPE_NO_VOICE_ACTIVITY && psEnc->sCmn.first_frame_after_reset == 0 ) { + /* Threshold for pitch estimator */ + thrhld_Q13 = SILK_FIX_CONST( 0.6, 13 ); + thrhld_Q13 = silk_SMLABB( thrhld_Q13, SILK_FIX_CONST( -0.004, 13 ), psEnc->sCmn.pitchEstimationLPCOrder ); + thrhld_Q13 = silk_SMLAWB( thrhld_Q13, SILK_FIX_CONST( -0.1, 21 ), psEnc->sCmn.speech_activity_Q8 ); + thrhld_Q13 = silk_SMLABB( thrhld_Q13, SILK_FIX_CONST( -0.15, 13 ), silk_RSHIFT( psEnc->sCmn.prevSignalType, 1 ) ); + thrhld_Q13 = silk_SMLAWB( thrhld_Q13, SILK_FIX_CONST( -0.1, 14 ), psEnc->sCmn.input_tilt_Q15 ); + thrhld_Q13 = silk_SAT16( thrhld_Q13 ); + + /*****************************************/ + /* Call pitch estimator */ + /*****************************************/ + if( silk_pitch_analysis_core( res, psEncCtrl->pitchL, &psEnc->sCmn.indices.lagIndex, &psEnc->sCmn.indices.contourIndex, + &psEnc->LTPCorr_Q15, psEnc->sCmn.prevLag, psEnc->sCmn.pitchEstimationThreshold_Q16, + (opus_int)thrhld_Q13, psEnc->sCmn.fs_kHz, psEnc->sCmn.pitchEstimationComplexity, psEnc->sCmn.nb_subfr, + psEnc->sCmn.arch) == 0 ) + { + psEnc->sCmn.indices.signalType = TYPE_VOICED; + } else { + psEnc->sCmn.indices.signalType = TYPE_UNVOICED; + } + } else { + silk_memset( psEncCtrl->pitchL, 0, sizeof( psEncCtrl->pitchL ) ); + psEnc->sCmn.indices.lagIndex = 0; + psEnc->sCmn.indices.contourIndex = 0; + psEnc->LTPCorr_Q15 = 0; + } + RESTORE_STACK; +} diff --git a/src/opus-1.1/silk/fixed/find_pred_coefs_FIX.c b/src/opus-1.1/silk/fixed/find_pred_coefs_FIX.c new file mode 100644 index 00000000..5c22f828 --- /dev/null +++ b/src/opus-1.1/silk/fixed/find_pred_coefs_FIX.c @@ -0,0 +1,147 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main_FIX.h" +#include "stack_alloc.h" + +void silk_find_pred_coefs_FIX( + silk_encoder_state_FIX *psEnc, /* I/O encoder state */ + silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */ + const opus_int16 res_pitch[], /* I Residual from pitch analysis */ + const opus_int16 x[], /* I Speech signal */ + opus_int condCoding /* I The type of conditional coding to use */ +) +{ + opus_int i; + opus_int32 invGains_Q16[ MAX_NB_SUBFR ], local_gains[ MAX_NB_SUBFR ], Wght_Q15[ MAX_NB_SUBFR ]; + opus_int16 NLSF_Q15[ MAX_LPC_ORDER ]; + const opus_int16 *x_ptr; + opus_int16 *x_pre_ptr; + VARDECL( opus_int16, LPC_in_pre ); + opus_int32 tmp, min_gain_Q16, minInvGain_Q30; + opus_int LTP_corrs_rshift[ MAX_NB_SUBFR ]; + SAVE_STACK; + + /* weighting for weighted least squares */ + min_gain_Q16 = silk_int32_MAX >> 6; + for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { + min_gain_Q16 = silk_min( min_gain_Q16, psEncCtrl->Gains_Q16[ i ] ); + } + for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { + /* Divide to Q16 */ + silk_assert( psEncCtrl->Gains_Q16[ i ] > 0 ); + /* Invert and normalize gains, and ensure that maximum invGains_Q16 is within range of a 16 bit int */ + invGains_Q16[ i ] = silk_DIV32_varQ( min_gain_Q16, psEncCtrl->Gains_Q16[ i ], 16 - 2 ); + + /* Ensure Wght_Q15 a minimum value 1 */ + invGains_Q16[ i ] = silk_max( invGains_Q16[ i ], 363 ); + + /* Square the inverted gains */ + silk_assert( invGains_Q16[ i ] == silk_SAT16( invGains_Q16[ i ] ) ); + tmp = silk_SMULWB( invGains_Q16[ i ], invGains_Q16[ i ] ); + Wght_Q15[ i ] = silk_RSHIFT( tmp, 1 ); + + /* Invert the inverted and normalized gains */ + local_gains[ i ] = silk_DIV32( ( (opus_int32)1 << 16 ), invGains_Q16[ i ] ); + } + + ALLOC( LPC_in_pre, + psEnc->sCmn.nb_subfr * psEnc->sCmn.predictLPCOrder + + psEnc->sCmn.frame_length, opus_int16 ); + if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { + VARDECL( opus_int32, WLTP ); + + /**********/ + /* VOICED */ + /**********/ + silk_assert( psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->pitchL[ 0 ] + LTP_ORDER / 2 ); + + ALLOC( WLTP, psEnc->sCmn.nb_subfr * LTP_ORDER * LTP_ORDER, opus_int32 ); + + /* LTP analysis */ + silk_find_LTP_FIX( psEncCtrl->LTPCoef_Q14, WLTP, &psEncCtrl->LTPredCodGain_Q7, + res_pitch, psEncCtrl->pitchL, Wght_Q15, psEnc->sCmn.subfr_length, + psEnc->sCmn.nb_subfr, psEnc->sCmn.ltp_mem_length, LTP_corrs_rshift ); + + /* Quantize LTP gain parameters */ + silk_quant_LTP_gains( psEncCtrl->LTPCoef_Q14, psEnc->sCmn.indices.LTPIndex, &psEnc->sCmn.indices.PERIndex, + &psEnc->sCmn.sum_log_gain_Q7, WLTP, psEnc->sCmn.mu_LTP_Q9, psEnc->sCmn.LTPQuantLowComplexity, psEnc->sCmn.nb_subfr); + + /* Control LTP scaling */ + silk_LTP_scale_ctrl_FIX( psEnc, psEncCtrl, condCoding ); + + /* Create LTP residual */ + silk_LTP_analysis_filter_FIX( LPC_in_pre, x - psEnc->sCmn.predictLPCOrder, psEncCtrl->LTPCoef_Q14, + psEncCtrl->pitchL, invGains_Q16, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder ); + + } else { + /************/ + /* UNVOICED */ + /************/ + /* Create signal with prepended subframes, scaled by inverse gains */ + x_ptr = x - psEnc->sCmn.predictLPCOrder; + x_pre_ptr = LPC_in_pre; + for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { + silk_scale_copy_vector16( x_pre_ptr, x_ptr, invGains_Q16[ i ], + psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder ); + x_pre_ptr += psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder; + x_ptr += psEnc->sCmn.subfr_length; + } + + silk_memset( psEncCtrl->LTPCoef_Q14, 0, psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( opus_int16 ) ); + psEncCtrl->LTPredCodGain_Q7 = 0; + psEnc->sCmn.sum_log_gain_Q7 = 0; + } + + /* Limit on total predictive coding gain */ + if( psEnc->sCmn.first_frame_after_reset ) { + minInvGain_Q30 = SILK_FIX_CONST( 1.0f / MAX_PREDICTION_POWER_GAIN_AFTER_RESET, 30 ); + } else { + minInvGain_Q30 = silk_log2lin( silk_SMLAWB( 16 << 7, (opus_int32)psEncCtrl->LTPredCodGain_Q7, SILK_FIX_CONST( 1.0 / 3, 16 ) ) ); /* Q16 */ + minInvGain_Q30 = silk_DIV32_varQ( minInvGain_Q30, + silk_SMULWW( SILK_FIX_CONST( MAX_PREDICTION_POWER_GAIN, 0 ), + silk_SMLAWB( SILK_FIX_CONST( 0.25, 18 ), SILK_FIX_CONST( 0.75, 18 ), psEncCtrl->coding_quality_Q14 ) ), 14 ); + } + + /* LPC_in_pre contains the LTP-filtered input for voiced, and the unfiltered input for unvoiced */ + silk_find_LPC_FIX( &psEnc->sCmn, NLSF_Q15, LPC_in_pre, minInvGain_Q30 ); + + /* Quantize LSFs */ + silk_process_NLSFs( &psEnc->sCmn, psEncCtrl->PredCoef_Q12, NLSF_Q15, psEnc->sCmn.prev_NLSFq_Q15 ); + + /* Calculate residual energy using quantized LPC coefficients */ + silk_residual_energy_FIX( psEncCtrl->ResNrg, psEncCtrl->ResNrgQ, LPC_in_pre, psEncCtrl->PredCoef_Q12, local_gains, + psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder ); + + /* Copy to prediction struct for use in next frame for interpolation */ + silk_memcpy( psEnc->sCmn.prev_NLSFq_Q15, NLSF_Q15, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) ); + RESTORE_STACK; +} diff --git a/src/opus-1.1/silk/fixed/k2a_FIX.c b/src/opus-1.1/silk/fixed/k2a_FIX.c new file mode 100644 index 00000000..5fee599b --- /dev/null +++ b/src/opus-1.1/silk/fixed/k2a_FIX.c @@ -0,0 +1,53 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SigProc_FIX.h" + +/* Step up function, converts reflection coefficients to prediction coefficients */ +void silk_k2a( + opus_int32 *A_Q24, /* O Prediction coefficients [order] Q24 */ + const opus_int16 *rc_Q15, /* I Reflection coefficients [order] Q15 */ + const opus_int32 order /* I Prediction order */ +) +{ + opus_int k, n; + opus_int32 Atmp[ SILK_MAX_ORDER_LPC ]; + + for( k = 0; k < order; k++ ) { + for( n = 0; n < k; n++ ) { + Atmp[ n ] = A_Q24[ n ]; + } + for( n = 0; n < k; n++ ) { + A_Q24[ n ] = silk_SMLAWB( A_Q24[ n ], silk_LSHIFT( Atmp[ k - n - 1 ], 1 ), rc_Q15[ k ] ); + } + A_Q24[ k ] = -silk_LSHIFT( (opus_int32)rc_Q15[ k ], 9 ); + } +} diff --git a/src/opus-1.1/silk/fixed/k2a_Q16_FIX.c b/src/opus-1.1/silk/fixed/k2a_Q16_FIX.c new file mode 100644 index 00000000..3b039875 --- /dev/null +++ b/src/opus-1.1/silk/fixed/k2a_Q16_FIX.c @@ -0,0 +1,53 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SigProc_FIX.h" + +/* Step up function, converts reflection coefficients to prediction coefficients */ +void silk_k2a_Q16( + opus_int32 *A_Q24, /* O Prediction coefficients [order] Q24 */ + const opus_int32 *rc_Q16, /* I Reflection coefficients [order] Q16 */ + const opus_int32 order /* I Prediction order */ +) +{ + opus_int k, n; + opus_int32 Atmp[ SILK_MAX_ORDER_LPC ]; + + for( k = 0; k < order; k++ ) { + for( n = 0; n < k; n++ ) { + Atmp[ n ] = A_Q24[ n ]; + } + for( n = 0; n < k; n++ ) { + A_Q24[ n ] = silk_SMLAWW( A_Q24[ n ], Atmp[ k - n - 1 ], rc_Q16[ k ] ); + } + A_Q24[ k ] = -silk_LSHIFT( rc_Q16[ k ], 8 ); + } +} diff --git a/src/opus-1.1/silk/fixed/main_FIX.h b/src/opus-1.1/silk/fixed/main_FIX.h new file mode 100644 index 00000000..a56ca07a --- /dev/null +++ b/src/opus-1.1/silk/fixed/main_FIX.h @@ -0,0 +1,257 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifndef SILK_MAIN_FIX_H +#define SILK_MAIN_FIX_H + +#include "SigProc_FIX.h" +#include "structs_FIX.h" +#include "control.h" +#include "main.h" +#include "PLC.h" +#include "debug.h" +#include "entenc.h" + +#ifndef FORCE_CPP_BUILD +#ifdef __cplusplus +extern "C" +{ +#endif +#endif + +#define silk_encoder_state_Fxx silk_encoder_state_FIX +#define silk_encode_do_VAD_Fxx silk_encode_do_VAD_FIX +#define silk_encode_frame_Fxx silk_encode_frame_FIX + +/*********************/ +/* Encoder Functions */ +/*********************/ + +/* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */ +void silk_HP_variable_cutoff( + silk_encoder_state_Fxx state_Fxx[] /* I/O Encoder states */ +); + +/* Encoder main function */ +void silk_encode_do_VAD_FIX( + silk_encoder_state_FIX *psEnc /* I/O Pointer to Silk FIX encoder state */ +); + +/* Encoder main function */ +opus_int silk_encode_frame_FIX( + silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ + opus_int32 *pnBytesOut, /* O Pointer to number of payload bytes; */ + ec_enc *psRangeEnc, /* I/O compressor data structure */ + opus_int condCoding, /* I The type of conditional coding to use */ + opus_int maxBits, /* I If > 0: maximum number of output bits */ + opus_int useCBR /* I Flag to force constant-bitrate operation */ +); + +/* Initializes the Silk encoder state */ +opus_int silk_init_encoder( + silk_encoder_state_Fxx *psEnc, /* I/O Pointer to Silk FIX encoder state */ + int arch /* I Run-time architecture */ +); + +/* Control the Silk encoder */ +opus_int silk_control_encoder( + silk_encoder_state_Fxx *psEnc, /* I/O Pointer to Silk encoder state */ + silk_EncControlStruct *encControl, /* I Control structure */ + const opus_int32 TargetRate_bps, /* I Target max bitrate (bps) */ + const opus_int allow_bw_switch, /* I Flag to allow switching audio bandwidth */ + const opus_int channelNb, /* I Channel number */ + const opus_int force_fs_kHz +); + +/****************/ +/* Prefiltering */ +/****************/ +void silk_prefilter_FIX( + silk_encoder_state_FIX *psEnc, /* I/O Encoder state */ + const silk_encoder_control_FIX *psEncCtrl, /* I Encoder control */ + opus_int32 xw_Q10[], /* O Weighted signal */ + const opus_int16 x[] /* I Speech signal */ +); + +/**************************/ +/* Noise shaping analysis */ +/**************************/ +/* Compute noise shaping coefficients and initial gain values */ +void silk_noise_shape_analysis_FIX( + silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */ + silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control FIX */ + const opus_int16 *pitch_res, /* I LPC residual from pitch analysis */ + const opus_int16 *x, /* I Input signal [ frame_length + la_shape ] */ + int arch /* I Run-time architecture */ +); + +/* Autocorrelations for a warped frequency axis */ +void silk_warped_autocorrelation_FIX( + opus_int32 *corr, /* O Result [order + 1] */ + opus_int *scale, /* O Scaling of the correlation vector */ + const opus_int16 *input, /* I Input data to correlate */ + const opus_int warping_Q16, /* I Warping coefficient */ + const opus_int length, /* I Length of input */ + const opus_int order /* I Correlation order (even) */ +); + +/* Calculation of LTP state scaling */ +void silk_LTP_scale_ctrl_FIX( + silk_encoder_state_FIX *psEnc, /* I/O encoder state */ + silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */ + opus_int condCoding /* I The type of conditional coding to use */ +); + +/**********************************************/ +/* Prediction Analysis */ +/**********************************************/ +/* Find pitch lags */ +void silk_find_pitch_lags_FIX( + silk_encoder_state_FIX *psEnc, /* I/O encoder state */ + silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */ + opus_int16 res[], /* O residual */ + const opus_int16 x[], /* I Speech signal */ + int arch /* I Run-time architecture */ +); + +/* Find LPC and LTP coefficients */ +void silk_find_pred_coefs_FIX( + silk_encoder_state_FIX *psEnc, /* I/O encoder state */ + silk_encoder_control_FIX *psEncCtrl, /* I/O encoder control */ + const opus_int16 res_pitch[], /* I Residual from pitch analysis */ + const opus_int16 x[], /* I Speech signal */ + opus_int condCoding /* I The type of conditional coding to use */ +); + +/* LPC analysis */ +void silk_find_LPC_FIX( + silk_encoder_state *psEncC, /* I/O Encoder state */ + opus_int16 NLSF_Q15[], /* O NLSFs */ + const opus_int16 x[], /* I Input signal */ + const opus_int32 minInvGain_Q30 /* I Inverse of max prediction gain */ +); + +/* LTP analysis */ +void silk_find_LTP_FIX( + opus_int16 b_Q14[ MAX_NB_SUBFR * LTP_ORDER ], /* O LTP coefs */ + opus_int32 WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */ + opus_int *LTPredCodGain_Q7, /* O LTP coding gain */ + const opus_int16 r_lpc[], /* I residual signal after LPC signal + state for first 10 ms */ + const opus_int lag[ MAX_NB_SUBFR ], /* I LTP lags */ + const opus_int32 Wght_Q15[ MAX_NB_SUBFR ], /* I weights */ + const opus_int subfr_length, /* I subframe length */ + const opus_int nb_subfr, /* I number of subframes */ + const opus_int mem_offset, /* I number of samples in LTP memory */ + opus_int corr_rshifts[ MAX_NB_SUBFR ] /* O right shifts applied to correlations */ +); + +void silk_LTP_analysis_filter_FIX( + opus_int16 *LTP_res, /* O LTP residual signal of length MAX_NB_SUBFR * ( pre_length + subfr_length ) */ + const opus_int16 *x, /* I Pointer to input signal with at least max( pitchL ) preceding samples */ + const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ],/* I LTP_ORDER LTP coefficients for each MAX_NB_SUBFR subframe */ + const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lag, one for each subframe */ + const opus_int32 invGains_Q16[ MAX_NB_SUBFR ], /* I Inverse quantization gains, one for each subframe */ + const opus_int subfr_length, /* I Length of each subframe */ + const opus_int nb_subfr, /* I Number of subframes */ + const opus_int pre_length /* I Length of the preceding samples starting at &x[0] for each subframe */ +); + +/* Calculates residual energies of input subframes where all subframes have LPC_order */ +/* of preceding samples */ +void silk_residual_energy_FIX( + opus_int32 nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */ + opus_int nrgsQ[ MAX_NB_SUBFR ], /* O Q value per subframe */ + const opus_int16 x[], /* I Input signal */ + opus_int16 a_Q12[ 2 ][ MAX_LPC_ORDER ], /* I AR coefs for each frame half */ + const opus_int32 gains[ MAX_NB_SUBFR ], /* I Quantization gains */ + const opus_int subfr_length, /* I Subframe length */ + const opus_int nb_subfr, /* I Number of subframes */ + const opus_int LPC_order /* I LPC order */ +); + +/* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */ +opus_int32 silk_residual_energy16_covar_FIX( + const opus_int16 *c, /* I Prediction vector */ + const opus_int32 *wXX, /* I Correlation matrix */ + const opus_int32 *wXx, /* I Correlation vector */ + opus_int32 wxx, /* I Signal energy */ + opus_int D, /* I Dimension */ + opus_int cQ /* I Q value for c vector 0 - 15 */ +); + +/* Processing of gains */ +void silk_process_gains_FIX( + silk_encoder_state_FIX *psEnc, /* I/O Encoder state */ + silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control */ + opus_int condCoding /* I The type of conditional coding to use */ +); + +/******************/ +/* Linear Algebra */ +/******************/ +/* Calculates correlation matrix X'*X */ +void silk_corrMatrix_FIX( + const opus_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */ + const opus_int L, /* I Length of vectors */ + const opus_int order, /* I Max lag for correlation */ + const opus_int head_room, /* I Desired headroom */ + opus_int32 *XX, /* O Pointer to X'*X correlation matrix [ order x order ] */ + opus_int *rshifts /* I/O Right shifts of correlations */ +); + +/* Calculates correlation vector X'*t */ +void silk_corrVector_FIX( + const opus_int16 *x, /* I x vector [L + order - 1] used to form data matrix X */ + const opus_int16 *t, /* I Target vector [L] */ + const opus_int L, /* I Length of vectors */ + const opus_int order, /* I Max lag for correlation */ + opus_int32 *Xt, /* O Pointer to X'*t correlation vector [order] */ + const opus_int rshifts /* I Right shifts of correlations */ +); + +/* Add noise to matrix diagonal */ +void silk_regularize_correlations_FIX( + opus_int32 *XX, /* I/O Correlation matrices */ + opus_int32 *xx, /* I/O Correlation values */ + opus_int32 noise, /* I Noise to add */ + opus_int D /* I Dimension of XX */ +); + +/* Solves Ax = b, assuming A is symmetric */ +void silk_solve_LDL_FIX( + opus_int32 *A, /* I Pointer to symetric square matrix A */ + opus_int M, /* I Size of matrix */ + const opus_int32 *b, /* I Pointer to b vector */ + opus_int32 *x_Q16 /* O Pointer to x solution vector */ +); + +#ifndef FORCE_CPP_BUILD +#ifdef __cplusplus +} +#endif /* __cplusplus */ +#endif /* FORCE_CPP_BUILD */ +#endif /* SILK_MAIN_FIX_H */ diff --git a/src/opus-1.1/silk/fixed/noise_shape_analysis_FIX.c b/src/opus-1.1/silk/fixed/noise_shape_analysis_FIX.c new file mode 100644 index 00000000..e24d2e9d --- /dev/null +++ b/src/opus-1.1/silk/fixed/noise_shape_analysis_FIX.c @@ -0,0 +1,445 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main_FIX.h" +#include "stack_alloc.h" +#include "tuning_parameters.h" + +/* Compute gain to make warped filter coefficients have a zero mean log frequency response on a */ +/* non-warped frequency scale. (So that it can be implemented with a minimum-phase monic filter.) */ +/* Note: A monic filter is one with the first coefficient equal to 1.0. In Silk we omit the first */ +/* coefficient in an array of coefficients, for monic filters. */ +static OPUS_INLINE opus_int32 warped_gain( /* gain in Q16*/ + const opus_int32 *coefs_Q24, + opus_int lambda_Q16, + opus_int order +) { + opus_int i; + opus_int32 gain_Q24; + + lambda_Q16 = -lambda_Q16; + gain_Q24 = coefs_Q24[ order - 1 ]; + for( i = order - 2; i >= 0; i-- ) { + gain_Q24 = silk_SMLAWB( coefs_Q24[ i ], gain_Q24, lambda_Q16 ); + } + gain_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), gain_Q24, -lambda_Q16 ); + return silk_INVERSE32_varQ( gain_Q24, 40 ); +} + +/* Convert warped filter coefficients to monic pseudo-warped coefficients and limit maximum */ +/* amplitude of monic warped coefficients by using bandwidth expansion on the true coefficients */ +static OPUS_INLINE void limit_warped_coefs( + opus_int32 *coefs_syn_Q24, + opus_int32 *coefs_ana_Q24, + opus_int lambda_Q16, + opus_int32 limit_Q24, + opus_int order +) { + opus_int i, iter, ind = 0; + opus_int32 tmp, maxabs_Q24, chirp_Q16, gain_syn_Q16, gain_ana_Q16; + opus_int32 nom_Q16, den_Q24; + + /* Convert to monic coefficients */ + lambda_Q16 = -lambda_Q16; + for( i = order - 1; i > 0; i-- ) { + coefs_syn_Q24[ i - 1 ] = silk_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 ); + coefs_ana_Q24[ i - 1 ] = silk_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 ); + } + lambda_Q16 = -lambda_Q16; + nom_Q16 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -(opus_int32)lambda_Q16, lambda_Q16 ); + den_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_syn_Q24[ 0 ], lambda_Q16 ); + gain_syn_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 ); + den_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_ana_Q24[ 0 ], lambda_Q16 ); + gain_ana_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 ); + for( i = 0; i < order; i++ ) { + coefs_syn_Q24[ i ] = silk_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] ); + coefs_ana_Q24[ i ] = silk_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] ); + } + + for( iter = 0; iter < 10; iter++ ) { + /* Find maximum absolute value */ + maxabs_Q24 = -1; + for( i = 0; i < order; i++ ) { + tmp = silk_max( silk_abs_int32( coefs_syn_Q24[ i ] ), silk_abs_int32( coefs_ana_Q24[ i ] ) ); + if( tmp > maxabs_Q24 ) { + maxabs_Q24 = tmp; + ind = i; + } + } + if( maxabs_Q24 <= limit_Q24 ) { + /* Coefficients are within range - done */ + return; + } + + /* Convert back to true warped coefficients */ + for( i = 1; i < order; i++ ) { + coefs_syn_Q24[ i - 1 ] = silk_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 ); + coefs_ana_Q24[ i - 1 ] = silk_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 ); + } + gain_syn_Q16 = silk_INVERSE32_varQ( gain_syn_Q16, 32 ); + gain_ana_Q16 = silk_INVERSE32_varQ( gain_ana_Q16, 32 ); + for( i = 0; i < order; i++ ) { + coefs_syn_Q24[ i ] = silk_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] ); + coefs_ana_Q24[ i ] = silk_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] ); + } + + /* Apply bandwidth expansion */ + chirp_Q16 = SILK_FIX_CONST( 0.99, 16 ) - silk_DIV32_varQ( + silk_SMULWB( maxabs_Q24 - limit_Q24, silk_SMLABB( SILK_FIX_CONST( 0.8, 10 ), SILK_FIX_CONST( 0.1, 10 ), iter ) ), + silk_MUL( maxabs_Q24, ind + 1 ), 22 ); + silk_bwexpander_32( coefs_syn_Q24, order, chirp_Q16 ); + silk_bwexpander_32( coefs_ana_Q24, order, chirp_Q16 ); + + /* Convert to monic warped coefficients */ + lambda_Q16 = -lambda_Q16; + for( i = order - 1; i > 0; i-- ) { + coefs_syn_Q24[ i - 1 ] = silk_SMLAWB( coefs_syn_Q24[ i - 1 ], coefs_syn_Q24[ i ], lambda_Q16 ); + coefs_ana_Q24[ i - 1 ] = silk_SMLAWB( coefs_ana_Q24[ i - 1 ], coefs_ana_Q24[ i ], lambda_Q16 ); + } + lambda_Q16 = -lambda_Q16; + nom_Q16 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -(opus_int32)lambda_Q16, lambda_Q16 ); + den_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_syn_Q24[ 0 ], lambda_Q16 ); + gain_syn_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 ); + den_Q24 = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_ana_Q24[ 0 ], lambda_Q16 ); + gain_ana_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 ); + for( i = 0; i < order; i++ ) { + coefs_syn_Q24[ i ] = silk_SMULWW( gain_syn_Q16, coefs_syn_Q24[ i ] ); + coefs_ana_Q24[ i ] = silk_SMULWW( gain_ana_Q16, coefs_ana_Q24[ i ] ); + } + } + silk_assert( 0 ); +} + +/**************************************************************/ +/* Compute noise shaping coefficients and initial gain values */ +/**************************************************************/ +void silk_noise_shape_analysis_FIX( + silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */ + silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control FIX */ + const opus_int16 *pitch_res, /* I LPC residual from pitch analysis */ + const opus_int16 *x, /* I Input signal [ frame_length + la_shape ] */ + int arch /* I Run-time architecture */ +) +{ + silk_shape_state_FIX *psShapeSt = &psEnc->sShape; + opus_int k, i, nSamples, Qnrg, b_Q14, warping_Q16, scale = 0; + opus_int32 SNR_adj_dB_Q7, HarmBoost_Q16, HarmShapeGain_Q16, Tilt_Q16, tmp32; + opus_int32 nrg, pre_nrg_Q30, log_energy_Q7, log_energy_prev_Q7, energy_variation_Q7; + opus_int32 delta_Q16, BWExp1_Q16, BWExp2_Q16, gain_mult_Q16, gain_add_Q16, strength_Q16, b_Q8; + opus_int32 auto_corr[ MAX_SHAPE_LPC_ORDER + 1 ]; + opus_int32 refl_coef_Q16[ MAX_SHAPE_LPC_ORDER ]; + opus_int32 AR1_Q24[ MAX_SHAPE_LPC_ORDER ]; + opus_int32 AR2_Q24[ MAX_SHAPE_LPC_ORDER ]; + VARDECL( opus_int16, x_windowed ); + const opus_int16 *x_ptr, *pitch_res_ptr; + SAVE_STACK; + + /* Point to start of first LPC analysis block */ + x_ptr = x - psEnc->sCmn.la_shape; + + /****************/ + /* GAIN CONTROL */ + /****************/ + SNR_adj_dB_Q7 = psEnc->sCmn.SNR_dB_Q7; + + /* Input quality is the average of the quality in the lowest two VAD bands */ + psEncCtrl->input_quality_Q14 = ( opus_int )silk_RSHIFT( (opus_int32)psEnc->sCmn.input_quality_bands_Q15[ 0 ] + + psEnc->sCmn.input_quality_bands_Q15[ 1 ], 2 ); + + /* Coding quality level, between 0.0_Q0 and 1.0_Q0, but in Q14 */ + psEncCtrl->coding_quality_Q14 = silk_RSHIFT( silk_sigm_Q15( silk_RSHIFT_ROUND( SNR_adj_dB_Q7 - + SILK_FIX_CONST( 20.0, 7 ), 4 ) ), 1 ); + + /* Reduce coding SNR during low speech activity */ + if( psEnc->sCmn.useCBR == 0 ) { + b_Q8 = SILK_FIX_CONST( 1.0, 8 ) - psEnc->sCmn.speech_activity_Q8; + b_Q8 = silk_SMULWB( silk_LSHIFT( b_Q8, 8 ), b_Q8 ); + SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, + silk_SMULBB( SILK_FIX_CONST( -BG_SNR_DECR_dB, 7 ) >> ( 4 + 1 ), b_Q8 ), /* Q11*/ + silk_SMULWB( SILK_FIX_CONST( 1.0, 14 ) + psEncCtrl->input_quality_Q14, psEncCtrl->coding_quality_Q14 ) ); /* Q12*/ + } + + if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { + /* Reduce gains for periodic signals */ + SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, SILK_FIX_CONST( HARM_SNR_INCR_dB, 8 ), psEnc->LTPCorr_Q15 ); + } else { + /* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */ + SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, + silk_SMLAWB( SILK_FIX_CONST( 6.0, 9 ), -SILK_FIX_CONST( 0.4, 18 ), psEnc->sCmn.SNR_dB_Q7 ), + SILK_FIX_CONST( 1.0, 14 ) - psEncCtrl->input_quality_Q14 ); + } + + /*************************/ + /* SPARSENESS PROCESSING */ + /*************************/ + /* Set quantizer offset */ + if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { + /* Initially set to 0; may be overruled in process_gains(..) */ + psEnc->sCmn.indices.quantOffsetType = 0; + psEncCtrl->sparseness_Q8 = 0; + } else { + /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */ + nSamples = silk_LSHIFT( psEnc->sCmn.fs_kHz, 1 ); + energy_variation_Q7 = 0; + log_energy_prev_Q7 = 0; + pitch_res_ptr = pitch_res; + for( k = 0; k < silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2; k++ ) { + silk_sum_sqr_shift( &nrg, &scale, pitch_res_ptr, nSamples ); + nrg += silk_RSHIFT( nSamples, scale ); /* Q(-scale)*/ + + log_energy_Q7 = silk_lin2log( nrg ); + if( k > 0 ) { + energy_variation_Q7 += silk_abs( log_energy_Q7 - log_energy_prev_Q7 ); + } + log_energy_prev_Q7 = log_energy_Q7; + pitch_res_ptr += nSamples; + } + + psEncCtrl->sparseness_Q8 = silk_RSHIFT( silk_sigm_Q15( silk_SMULWB( energy_variation_Q7 - + SILK_FIX_CONST( 5.0, 7 ), SILK_FIX_CONST( 0.1, 16 ) ) ), 7 ); + + /* Set quantization offset depending on sparseness measure */ + if( psEncCtrl->sparseness_Q8 > SILK_FIX_CONST( SPARSENESS_THRESHOLD_QNT_OFFSET, 8 ) ) { + psEnc->sCmn.indices.quantOffsetType = 0; + } else { + psEnc->sCmn.indices.quantOffsetType = 1; + } + + /* Increase coding SNR for sparse signals */ + SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, SILK_FIX_CONST( SPARSE_SNR_INCR_dB, 15 ), psEncCtrl->sparseness_Q8 - SILK_FIX_CONST( 0.5, 8 ) ); + } + + /*******************************/ + /* Control bandwidth expansion */ + /*******************************/ + /* More BWE for signals with high prediction gain */ + strength_Q16 = silk_SMULWB( psEncCtrl->predGain_Q16, SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) ); + BWExp1_Q16 = BWExp2_Q16 = silk_DIV32_varQ( SILK_FIX_CONST( BANDWIDTH_EXPANSION, 16 ), + silk_SMLAWW( SILK_FIX_CONST( 1.0, 16 ), strength_Q16, strength_Q16 ), 16 ); + delta_Q16 = silk_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - silk_SMULBB( 3, psEncCtrl->coding_quality_Q14 ), + SILK_FIX_CONST( LOW_RATE_BANDWIDTH_EXPANSION_DELTA, 16 ) ); + BWExp1_Q16 = silk_SUB32( BWExp1_Q16, delta_Q16 ); + BWExp2_Q16 = silk_ADD32( BWExp2_Q16, delta_Q16 ); + /* BWExp1 will be applied after BWExp2, so make it relative */ + BWExp1_Q16 = silk_DIV32_16( silk_LSHIFT( BWExp1_Q16, 14 ), silk_RSHIFT( BWExp2_Q16, 2 ) ); + + if( psEnc->sCmn.warping_Q16 > 0 ) { + /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */ + warping_Q16 = silk_SMLAWB( psEnc->sCmn.warping_Q16, (opus_int32)psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( 0.01, 18 ) ); + } else { + warping_Q16 = 0; + } + + /********************************************/ + /* Compute noise shaping AR coefs and gains */ + /********************************************/ + ALLOC( x_windowed, psEnc->sCmn.shapeWinLength, opus_int16 ); + for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { + /* Apply window: sine slope followed by flat part followed by cosine slope */ + opus_int shift, slope_part, flat_part; + flat_part = psEnc->sCmn.fs_kHz * 3; + slope_part = silk_RSHIFT( psEnc->sCmn.shapeWinLength - flat_part, 1 ); + + silk_apply_sine_window( x_windowed, x_ptr, 1, slope_part ); + shift = slope_part; + silk_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(opus_int16) ); + shift += flat_part; + silk_apply_sine_window( x_windowed + shift, x_ptr + shift, 2, slope_part ); + + /* Update pointer: next LPC analysis block */ + x_ptr += psEnc->sCmn.subfr_length; + + if( psEnc->sCmn.warping_Q16 > 0 ) { + /* Calculate warped auto correlation */ + silk_warped_autocorrelation_FIX( auto_corr, &scale, x_windowed, warping_Q16, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder ); + } else { + /* Calculate regular auto correlation */ + silk_autocorr( auto_corr, &scale, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1, arch ); + } + + /* Add white noise, as a fraction of energy */ + auto_corr[0] = silk_ADD32( auto_corr[0], silk_max_32( silk_SMULWB( silk_RSHIFT( auto_corr[ 0 ], 4 ), + SILK_FIX_CONST( SHAPE_WHITE_NOISE_FRACTION, 20 ) ), 1 ) ); + + /* Calculate the reflection coefficients using schur */ + nrg = silk_schur64( refl_coef_Q16, auto_corr, psEnc->sCmn.shapingLPCOrder ); + silk_assert( nrg >= 0 ); + + /* Convert reflection coefficients to prediction coefficients */ + silk_k2a_Q16( AR2_Q24, refl_coef_Q16, psEnc->sCmn.shapingLPCOrder ); + + Qnrg = -scale; /* range: -12...30*/ + silk_assert( Qnrg >= -12 ); + silk_assert( Qnrg <= 30 ); + + /* Make sure that Qnrg is an even number */ + if( Qnrg & 1 ) { + Qnrg -= 1; + nrg >>= 1; + } + + tmp32 = silk_SQRT_APPROX( nrg ); + Qnrg >>= 1; /* range: -6...15*/ + + psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT_SAT32( tmp32, 16 - Qnrg ); + + if( psEnc->sCmn.warping_Q16 > 0 ) { + /* Adjust gain for warping */ + gain_mult_Q16 = warped_gain( AR2_Q24, warping_Q16, psEnc->sCmn.shapingLPCOrder ); + silk_assert( psEncCtrl->Gains_Q16[ k ] >= 0 ); + if ( silk_SMULWW( silk_RSHIFT_ROUND( psEncCtrl->Gains_Q16[ k ], 1 ), gain_mult_Q16 ) >= ( silk_int32_MAX >> 1 ) ) { + psEncCtrl->Gains_Q16[ k ] = silk_int32_MAX; + } else { + psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 ); + } + } + + /* Bandwidth expansion for synthesis filter shaping */ + silk_bwexpander_32( AR2_Q24, psEnc->sCmn.shapingLPCOrder, BWExp2_Q16 ); + + /* Compute noise shaping filter coefficients */ + silk_memcpy( AR1_Q24, AR2_Q24, psEnc->sCmn.shapingLPCOrder * sizeof( opus_int32 ) ); + + /* Bandwidth expansion for analysis filter shaping */ + silk_assert( BWExp1_Q16 <= SILK_FIX_CONST( 1.0, 16 ) ); + silk_bwexpander_32( AR1_Q24, psEnc->sCmn.shapingLPCOrder, BWExp1_Q16 ); + + /* Ratio of prediction gains, in energy domain */ + pre_nrg_Q30 = silk_LPC_inverse_pred_gain_Q24( AR2_Q24, psEnc->sCmn.shapingLPCOrder ); + nrg = silk_LPC_inverse_pred_gain_Q24( AR1_Q24, psEnc->sCmn.shapingLPCOrder ); + + /*psEncCtrl->GainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg ) = 0.3f + 0.7f * pre_nrg / nrg;*/ + pre_nrg_Q30 = silk_LSHIFT32( silk_SMULWB( pre_nrg_Q30, SILK_FIX_CONST( 0.7, 15 ) ), 1 ); + psEncCtrl->GainsPre_Q14[ k ] = ( opus_int ) SILK_FIX_CONST( 0.3, 14 ) + silk_DIV32_varQ( pre_nrg_Q30, nrg, 14 ); + + /* Convert to monic warped prediction coefficients and limit absolute values */ + limit_warped_coefs( AR2_Q24, AR1_Q24, warping_Q16, SILK_FIX_CONST( 3.999, 24 ), psEnc->sCmn.shapingLPCOrder ); + + /* Convert from Q24 to Q13 and store in int16 */ + for( i = 0; i < psEnc->sCmn.shapingLPCOrder; i++ ) { + psEncCtrl->AR1_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR1_Q24[ i ], 11 ) ); + psEncCtrl->AR2_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR2_Q24[ i ], 11 ) ); + } + } + + /*****************/ + /* Gain tweaking */ + /*****************/ + /* Increase gains during low speech activity and put lower limit on gains */ + gain_mult_Q16 = silk_log2lin( -silk_SMLAWB( -SILK_FIX_CONST( 16.0, 7 ), SNR_adj_dB_Q7, SILK_FIX_CONST( 0.16, 16 ) ) ); + gain_add_Q16 = silk_log2lin( silk_SMLAWB( SILK_FIX_CONST( 16.0, 7 ), SILK_FIX_CONST( MIN_QGAIN_DB, 7 ), SILK_FIX_CONST( 0.16, 16 ) ) ); + silk_assert( gain_mult_Q16 > 0 ); + for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { + psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 ); + silk_assert( psEncCtrl->Gains_Q16[ k ] >= 0 ); + psEncCtrl->Gains_Q16[ k ] = silk_ADD_POS_SAT32( psEncCtrl->Gains_Q16[ k ], gain_add_Q16 ); + } + + gain_mult_Q16 = SILK_FIX_CONST( 1.0, 16 ) + silk_RSHIFT_ROUND( silk_MLA( SILK_FIX_CONST( INPUT_TILT, 26 ), + psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( HIGH_RATE_INPUT_TILT, 12 ) ), 10 ); + for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { + psEncCtrl->GainsPre_Q14[ k ] = silk_SMULWB( gain_mult_Q16, psEncCtrl->GainsPre_Q14[ k ] ); + } + + /************************************************/ + /* Control low-frequency shaping and noise tilt */ + /************************************************/ + /* Less low frequency shaping for noisy inputs */ + strength_Q16 = silk_MUL( SILK_FIX_CONST( LOW_FREQ_SHAPING, 4 ), silk_SMLAWB( SILK_FIX_CONST( 1.0, 12 ), + SILK_FIX_CONST( LOW_QUALITY_LOW_FREQ_SHAPING_DECR, 13 ), psEnc->sCmn.input_quality_bands_Q15[ 0 ] - SILK_FIX_CONST( 1.0, 15 ) ) ); + strength_Q16 = silk_RSHIFT( silk_MUL( strength_Q16, psEnc->sCmn.speech_activity_Q8 ), 8 ); + if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { + /* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */ + /*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/ + opus_int fs_kHz_inv = silk_DIV32_16( SILK_FIX_CONST( 0.2, 14 ), psEnc->sCmn.fs_kHz ); + for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { + b_Q14 = fs_kHz_inv + silk_DIV32_16( SILK_FIX_CONST( 3.0, 14 ), psEncCtrl->pitchL[ k ] ); + /* Pack two coefficients in one int32 */ + psEncCtrl->LF_shp_Q14[ k ] = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 - silk_SMULWB( strength_Q16, b_Q14 ), 16 ); + psEncCtrl->LF_shp_Q14[ k ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) ); + } + silk_assert( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ) < SILK_FIX_CONST( 0.5, 24 ) ); /* Guarantees that second argument to SMULWB() is within range of an opus_int16*/ + Tilt_Q16 = - SILK_FIX_CONST( HP_NOISE_COEF, 16 ) - + silk_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - SILK_FIX_CONST( HP_NOISE_COEF, 16 ), + silk_SMULWB( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ), psEnc->sCmn.speech_activity_Q8 ) ); + } else { + b_Q14 = silk_DIV32_16( 21299, psEnc->sCmn.fs_kHz ); /* 1.3_Q0 = 21299_Q14*/ + /* Pack two coefficients in one int32 */ + psEncCtrl->LF_shp_Q14[ 0 ] = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 - + silk_SMULWB( strength_Q16, silk_SMULWB( SILK_FIX_CONST( 0.6, 16 ), b_Q14 ) ), 16 ); + psEncCtrl->LF_shp_Q14[ 0 ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) ); + for( k = 1; k < psEnc->sCmn.nb_subfr; k++ ) { + psEncCtrl->LF_shp_Q14[ k ] = psEncCtrl->LF_shp_Q14[ 0 ]; + } + Tilt_Q16 = -SILK_FIX_CONST( HP_NOISE_COEF, 16 ); + } + + /****************************/ + /* HARMONIC SHAPING CONTROL */ + /****************************/ + /* Control boosting of harmonic frequencies */ + HarmBoost_Q16 = silk_SMULWB( silk_SMULWB( SILK_FIX_CONST( 1.0, 17 ) - silk_LSHIFT( psEncCtrl->coding_quality_Q14, 3 ), + psEnc->LTPCorr_Q15 ), SILK_FIX_CONST( LOW_RATE_HARMONIC_BOOST, 16 ) ); + + /* More harmonic boost for noisy input signals */ + HarmBoost_Q16 = silk_SMLAWB( HarmBoost_Q16, + SILK_FIX_CONST( 1.0, 16 ) - silk_LSHIFT( psEncCtrl->input_quality_Q14, 2 ), SILK_FIX_CONST( LOW_INPUT_QUALITY_HARMONIC_BOOST, 16 ) ); + + if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) { + /* More harmonic noise shaping for high bitrates or noisy input */ + HarmShapeGain_Q16 = silk_SMLAWB( SILK_FIX_CONST( HARMONIC_SHAPING, 16 ), + SILK_FIX_CONST( 1.0, 16 ) - silk_SMULWB( SILK_FIX_CONST( 1.0, 18 ) - silk_LSHIFT( psEncCtrl->coding_quality_Q14, 4 ), + psEncCtrl->input_quality_Q14 ), SILK_FIX_CONST( HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING, 16 ) ); + + /* Less harmonic noise shaping for less periodic signals */ + HarmShapeGain_Q16 = silk_SMULWB( silk_LSHIFT( HarmShapeGain_Q16, 1 ), + silk_SQRT_APPROX( silk_LSHIFT( psEnc->LTPCorr_Q15, 15 ) ) ); + } else { + HarmShapeGain_Q16 = 0; + } + + /*************************/ + /* Smooth over subframes */ + /*************************/ + for( k = 0; k < MAX_NB_SUBFR; k++ ) { + psShapeSt->HarmBoost_smth_Q16 = + silk_SMLAWB( psShapeSt->HarmBoost_smth_Q16, HarmBoost_Q16 - psShapeSt->HarmBoost_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) ); + psShapeSt->HarmShapeGain_smth_Q16 = + silk_SMLAWB( psShapeSt->HarmShapeGain_smth_Q16, HarmShapeGain_Q16 - psShapeSt->HarmShapeGain_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) ); + psShapeSt->Tilt_smth_Q16 = + silk_SMLAWB( psShapeSt->Tilt_smth_Q16, Tilt_Q16 - psShapeSt->Tilt_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) ); + + psEncCtrl->HarmBoost_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmBoost_smth_Q16, 2 ); + psEncCtrl->HarmShapeGain_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmShapeGain_smth_Q16, 2 ); + psEncCtrl->Tilt_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->Tilt_smth_Q16, 2 ); + } + RESTORE_STACK; +} diff --git a/src/opus-1.1/silk/fixed/pitch_analysis_core_FIX.c b/src/opus-1.1/silk/fixed/pitch_analysis_core_FIX.c new file mode 100644 index 00000000..1641a0fb --- /dev/null +++ b/src/opus-1.1/silk/fixed/pitch_analysis_core_FIX.c @@ -0,0 +1,744 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/*********************************************************** +* Pitch analyser function +********************************************************** */ +#include "SigProc_FIX.h" +#include "pitch_est_defines.h" +#include "stack_alloc.h" +#include "debug.h" +#include "pitch.h" + +#define SCRATCH_SIZE 22 +#define SF_LENGTH_4KHZ ( PE_SUBFR_LENGTH_MS * 4 ) +#define SF_LENGTH_8KHZ ( PE_SUBFR_LENGTH_MS * 8 ) +#define MIN_LAG_4KHZ ( PE_MIN_LAG_MS * 4 ) +#define MIN_LAG_8KHZ ( PE_MIN_LAG_MS * 8 ) +#define MAX_LAG_4KHZ ( PE_MAX_LAG_MS * 4 ) +#define MAX_LAG_8KHZ ( PE_MAX_LAG_MS * 8 - 1 ) +#define CSTRIDE_4KHZ ( MAX_LAG_4KHZ + 1 - MIN_LAG_4KHZ ) +#define CSTRIDE_8KHZ ( MAX_LAG_8KHZ + 3 - ( MIN_LAG_8KHZ - 2 ) ) +#define D_COMP_MIN ( MIN_LAG_8KHZ - 3 ) +#define D_COMP_MAX ( MAX_LAG_8KHZ + 4 ) +#define D_COMP_STRIDE ( D_COMP_MAX - D_COMP_MIN ) + +typedef opus_int32 silk_pe_stage3_vals[ PE_NB_STAGE3_LAGS ]; + +/************************************************************/ +/* Internally used functions */ +/************************************************************/ +static void silk_P_Ana_calc_corr_st3( + silk_pe_stage3_vals cross_corr_st3[], /* O 3 DIM correlation array */ + const opus_int16 frame[], /* I vector to correlate */ + opus_int start_lag, /* I lag offset to search around */ + opus_int sf_length, /* I length of a 5 ms subframe */ + opus_int nb_subfr, /* I number of subframes */ + opus_int complexity, /* I Complexity setting */ + int arch /* I Run-time architecture */ +); + +static void silk_P_Ana_calc_energy_st3( + silk_pe_stage3_vals energies_st3[], /* O 3 DIM energy array */ + const opus_int16 frame[], /* I vector to calc energy in */ + opus_int start_lag, /* I lag offset to search around */ + opus_int sf_length, /* I length of one 5 ms subframe */ + opus_int nb_subfr, /* I number of subframes */ + opus_int complexity /* I Complexity setting */ +); + +/*************************************************************/ +/* FIXED POINT CORE PITCH ANALYSIS FUNCTION */ +/*************************************************************/ +opus_int silk_pitch_analysis_core( /* O Voicing estimate: 0 voiced, 1 unvoiced */ + const opus_int16 *frame, /* I Signal of length PE_FRAME_LENGTH_MS*Fs_kHz */ + opus_int *pitch_out, /* O 4 pitch lag values */ + opus_int16 *lagIndex, /* O Lag Index */ + opus_int8 *contourIndex, /* O Pitch contour Index */ + opus_int *LTPCorr_Q15, /* I/O Normalized correlation; input: value from previous frame */ + opus_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */ + const opus_int32 search_thres1_Q16, /* I First stage threshold for lag candidates 0 - 1 */ + const opus_int search_thres2_Q13, /* I Final threshold for lag candidates 0 - 1 */ + const opus_int Fs_kHz, /* I Sample frequency (kHz) */ + const opus_int complexity, /* I Complexity setting, 0-2, where 2 is highest */ + const opus_int nb_subfr, /* I number of 5 ms subframes */ + int arch /* I Run-time architecture */ +) +{ + VARDECL( opus_int16, frame_8kHz ); + VARDECL( opus_int16, frame_4kHz ); + opus_int32 filt_state[ 6 ]; + const opus_int16 *input_frame_ptr; + opus_int i, k, d, j; + VARDECL( opus_int16, C ); + VARDECL( opus_int32, xcorr32 ); + const opus_int16 *target_ptr, *basis_ptr; + opus_int32 cross_corr, normalizer, energy, shift, energy_basis, energy_target; + opus_int d_srch[ PE_D_SRCH_LENGTH ], Cmax, length_d_srch, length_d_comp; + VARDECL( opus_int16, d_comp ); + opus_int32 sum, threshold, lag_counter; + opus_int CBimax, CBimax_new, CBimax_old, lag, start_lag, end_lag, lag_new; + opus_int32 CC[ PE_NB_CBKS_STAGE2_EXT ], CCmax, CCmax_b, CCmax_new_b, CCmax_new; + VARDECL( silk_pe_stage3_vals, energies_st3 ); + VARDECL( silk_pe_stage3_vals, cross_corr_st3 ); + opus_int frame_length, frame_length_8kHz, frame_length_4kHz; + opus_int sf_length; + opus_int min_lag; + opus_int max_lag; + opus_int32 contour_bias_Q15, diff; + opus_int nb_cbk_search, cbk_size; + opus_int32 delta_lag_log2_sqr_Q7, lag_log2_Q7, prevLag_log2_Q7, prev_lag_bias_Q13; + const opus_int8 *Lag_CB_ptr; + SAVE_STACK; + /* Check for valid sampling frequency */ + silk_assert( Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16 ); + + /* Check for valid complexity setting */ + silk_assert( complexity >= SILK_PE_MIN_COMPLEX ); + silk_assert( complexity <= SILK_PE_MAX_COMPLEX ); + + silk_assert( search_thres1_Q16 >= 0 && search_thres1_Q16 <= (1<<16) ); + silk_assert( search_thres2_Q13 >= 0 && search_thres2_Q13 <= (1<<13) ); + + /* Set up frame lengths max / min lag for the sampling frequency */ + frame_length = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * Fs_kHz; + frame_length_4kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 4; + frame_length_8kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 8; + sf_length = PE_SUBFR_LENGTH_MS * Fs_kHz; + min_lag = PE_MIN_LAG_MS * Fs_kHz; + max_lag = PE_MAX_LAG_MS * Fs_kHz - 1; + + /* Resample from input sampled at Fs_kHz to 8 kHz */ + ALLOC( frame_8kHz, frame_length_8kHz, opus_int16 ); + if( Fs_kHz == 16 ) { + silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) ); + silk_resampler_down2( filt_state, frame_8kHz, frame, frame_length ); + } else if( Fs_kHz == 12 ) { + silk_memset( filt_state, 0, 6 * sizeof( opus_int32 ) ); + silk_resampler_down2_3( filt_state, frame_8kHz, frame, frame_length ); + } else { + silk_assert( Fs_kHz == 8 ); + silk_memcpy( frame_8kHz, frame, frame_length_8kHz * sizeof(opus_int16) ); + } + + /* Decimate again to 4 kHz */ + silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) );/* Set state to zero */ + ALLOC( frame_4kHz, frame_length_4kHz, opus_int16 ); + silk_resampler_down2( filt_state, frame_4kHz, frame_8kHz, frame_length_8kHz ); + + /* Low-pass filter */ + for( i = frame_length_4kHz - 1; i > 0; i-- ) { + frame_4kHz[ i ] = silk_ADD_SAT16( frame_4kHz[ i ], frame_4kHz[ i - 1 ] ); + } + + /******************************************************************************* + ** Scale 4 kHz signal down to prevent correlations measures from overflowing + ** find scaling as max scaling for each 8kHz(?) subframe + *******************************************************************************/ + + /* Inner product is calculated with different lengths, so scale for the worst case */ + silk_sum_sqr_shift( &energy, &shift, frame_4kHz, frame_length_4kHz ); + if( shift > 0 ) { + shift = silk_RSHIFT( shift, 1 ); + for( i = 0; i < frame_length_4kHz; i++ ) { + frame_4kHz[ i ] = silk_RSHIFT( frame_4kHz[ i ], shift ); + } + } + + /****************************************************************************** + * FIRST STAGE, operating in 4 khz + ******************************************************************************/ + ALLOC( C, nb_subfr * CSTRIDE_8KHZ, opus_int16 ); + ALLOC( xcorr32, MAX_LAG_4KHZ-MIN_LAG_4KHZ+1, opus_int32 ); + silk_memset( C, 0, (nb_subfr >> 1) * CSTRIDE_4KHZ * sizeof( opus_int16 ) ); + target_ptr = &frame_4kHz[ silk_LSHIFT( SF_LENGTH_4KHZ, 2 ) ]; + for( k = 0; k < nb_subfr >> 1; k++ ) { + /* Check that we are within range of the array */ + silk_assert( target_ptr >= frame_4kHz ); + silk_assert( target_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz ); + + basis_ptr = target_ptr - MIN_LAG_4KHZ; + + /* Check that we are within range of the array */ + silk_assert( basis_ptr >= frame_4kHz ); + silk_assert( basis_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz ); + + celt_pitch_xcorr( target_ptr, target_ptr - MAX_LAG_4KHZ, xcorr32, SF_LENGTH_8KHZ, MAX_LAG_4KHZ - MIN_LAG_4KHZ + 1, arch ); + + /* Calculate first vector products before loop */ + cross_corr = xcorr32[ MAX_LAG_4KHZ - MIN_LAG_4KHZ ]; + normalizer = silk_inner_prod_aligned( target_ptr, target_ptr, SF_LENGTH_8KHZ ); + normalizer = silk_ADD32( normalizer, silk_inner_prod_aligned( basis_ptr, basis_ptr, SF_LENGTH_8KHZ ) ); + normalizer = silk_ADD32( normalizer, silk_SMULBB( SF_LENGTH_8KHZ, 4000 ) ); + + matrix_ptr( C, k, 0, CSTRIDE_4KHZ ) = + (opus_int16)silk_DIV32_varQ( cross_corr, normalizer, 13 + 1 ); /* Q13 */ + + /* From now on normalizer is computed recursively */ + for( d = MIN_LAG_4KHZ + 1; d <= MAX_LAG_4KHZ; d++ ) { + basis_ptr--; + + /* Check that we are within range of the array */ + silk_assert( basis_ptr >= frame_4kHz ); + silk_assert( basis_ptr + SF_LENGTH_8KHZ <= frame_4kHz + frame_length_4kHz ); + + cross_corr = xcorr32[ MAX_LAG_4KHZ - d ]; + + /* Add contribution of new sample and remove contribution from oldest sample */ + normalizer = silk_ADD32( normalizer, + silk_SMULBB( basis_ptr[ 0 ], basis_ptr[ 0 ] ) - + silk_SMULBB( basis_ptr[ SF_LENGTH_8KHZ ], basis_ptr[ SF_LENGTH_8KHZ ] ) ); + + matrix_ptr( C, k, d - MIN_LAG_4KHZ, CSTRIDE_4KHZ) = + (opus_int16)silk_DIV32_varQ( cross_corr, normalizer, 13 + 1 ); /* Q13 */ + } + /* Update target pointer */ + target_ptr += SF_LENGTH_8KHZ; + } + + /* Combine two subframes into single correlation measure and apply short-lag bias */ + if( nb_subfr == PE_MAX_NB_SUBFR ) { + for( i = MAX_LAG_4KHZ; i >= MIN_LAG_4KHZ; i-- ) { + sum = (opus_int32)matrix_ptr( C, 0, i - MIN_LAG_4KHZ, CSTRIDE_4KHZ ) + + (opus_int32)matrix_ptr( C, 1, i - MIN_LAG_4KHZ, CSTRIDE_4KHZ ); /* Q14 */ + sum = silk_SMLAWB( sum, sum, silk_LSHIFT( -i, 4 ) ); /* Q14 */ + C[ i - MIN_LAG_4KHZ ] = (opus_int16)sum; /* Q14 */ + } + } else { + /* Only short-lag bias */ + for( i = MAX_LAG_4KHZ; i >= MIN_LAG_4KHZ; i-- ) { + sum = silk_LSHIFT( (opus_int32)C[ i - MIN_LAG_4KHZ ], 1 ); /* Q14 */ + sum = silk_SMLAWB( sum, sum, silk_LSHIFT( -i, 4 ) ); /* Q14 */ + C[ i - MIN_LAG_4KHZ ] = (opus_int16)sum; /* Q14 */ + } + } + + /* Sort */ + length_d_srch = silk_ADD_LSHIFT32( 4, complexity, 1 ); + silk_assert( 3 * length_d_srch <= PE_D_SRCH_LENGTH ); + silk_insertion_sort_decreasing_int16( C, d_srch, CSTRIDE_4KHZ, + length_d_srch ); + + /* Escape if correlation is very low already here */ + Cmax = (opus_int)C[ 0 ]; /* Q14 */ + if( Cmax < SILK_FIX_CONST( 0.2, 14 ) ) { + silk_memset( pitch_out, 0, nb_subfr * sizeof( opus_int ) ); + *LTPCorr_Q15 = 0; + *lagIndex = 0; + *contourIndex = 0; + RESTORE_STACK; + return 1; + } + + threshold = silk_SMULWB( search_thres1_Q16, Cmax ); + for( i = 0; i < length_d_srch; i++ ) { + /* Convert to 8 kHz indices for the sorted correlation that exceeds the threshold */ + if( C[ i ] > threshold ) { + d_srch[ i ] = silk_LSHIFT( d_srch[ i ] + MIN_LAG_4KHZ, 1 ); + } else { + length_d_srch = i; + break; + } + } + silk_assert( length_d_srch > 0 ); + + ALLOC( d_comp, D_COMP_STRIDE, opus_int16 ); + for( i = D_COMP_MIN; i < D_COMP_MAX; i++ ) { + d_comp[ i - D_COMP_MIN ] = 0; + } + for( i = 0; i < length_d_srch; i++ ) { + d_comp[ d_srch[ i ] - D_COMP_MIN ] = 1; + } + + /* Convolution */ + for( i = D_COMP_MAX - 1; i >= MIN_LAG_8KHZ; i-- ) { + d_comp[ i - D_COMP_MIN ] += + d_comp[ i - 1 - D_COMP_MIN ] + d_comp[ i - 2 - D_COMP_MIN ]; + } + + length_d_srch = 0; + for( i = MIN_LAG_8KHZ; i < MAX_LAG_8KHZ + 1; i++ ) { + if( d_comp[ i + 1 - D_COMP_MIN ] > 0 ) { + d_srch[ length_d_srch ] = i; + length_d_srch++; + } + } + + /* Convolution */ + for( i = D_COMP_MAX - 1; i >= MIN_LAG_8KHZ; i-- ) { + d_comp[ i - D_COMP_MIN ] += d_comp[ i - 1 - D_COMP_MIN ] + + d_comp[ i - 2 - D_COMP_MIN ] + d_comp[ i - 3 - D_COMP_MIN ]; + } + + length_d_comp = 0; + for( i = MIN_LAG_8KHZ; i < D_COMP_MAX; i++ ) { + if( d_comp[ i - D_COMP_MIN ] > 0 ) { + d_comp[ length_d_comp ] = i - 2; + length_d_comp++; + } + } + + /********************************************************************************** + ** SECOND STAGE, operating at 8 kHz, on lag sections with high correlation + *************************************************************************************/ + + /****************************************************************************** + ** Scale signal down to avoid correlations measures from overflowing + *******************************************************************************/ + /* find scaling as max scaling for each subframe */ + silk_sum_sqr_shift( &energy, &shift, frame_8kHz, frame_length_8kHz ); + if( shift > 0 ) { + shift = silk_RSHIFT( shift, 1 ); + for( i = 0; i < frame_length_8kHz; i++ ) { + frame_8kHz[ i ] = silk_RSHIFT( frame_8kHz[ i ], shift ); + } + } + + /********************************************************************************* + * Find energy of each subframe projected onto its history, for a range of delays + *********************************************************************************/ + silk_memset( C, 0, nb_subfr * CSTRIDE_8KHZ * sizeof( opus_int16 ) ); + + target_ptr = &frame_8kHz[ PE_LTP_MEM_LENGTH_MS * 8 ]; + for( k = 0; k < nb_subfr; k++ ) { + + /* Check that we are within range of the array */ + silk_assert( target_ptr >= frame_8kHz ); + silk_assert( target_ptr + SF_LENGTH_8KHZ <= frame_8kHz + frame_length_8kHz ); + + energy_target = silk_ADD32( silk_inner_prod_aligned( target_ptr, target_ptr, SF_LENGTH_8KHZ ), 1 ); + for( j = 0; j < length_d_comp; j++ ) { + d = d_comp[ j ]; + basis_ptr = target_ptr - d; + + /* Check that we are within range of the array */ + silk_assert( basis_ptr >= frame_8kHz ); + silk_assert( basis_ptr + SF_LENGTH_8KHZ <= frame_8kHz + frame_length_8kHz ); + + cross_corr = silk_inner_prod_aligned( target_ptr, basis_ptr, SF_LENGTH_8KHZ ); + if( cross_corr > 0 ) { + energy_basis = silk_inner_prod_aligned( basis_ptr, basis_ptr, SF_LENGTH_8KHZ ); + matrix_ptr( C, k, d - ( MIN_LAG_8KHZ - 2 ), CSTRIDE_8KHZ ) = + (opus_int16)silk_DIV32_varQ( cross_corr, + silk_ADD32( energy_target, + energy_basis ), + 13 + 1 ); /* Q13 */ + } else { + matrix_ptr( C, k, d - ( MIN_LAG_8KHZ - 2 ), CSTRIDE_8KHZ ) = 0; + } + } + target_ptr += SF_LENGTH_8KHZ; + } + + /* search over lag range and lags codebook */ + /* scale factor for lag codebook, as a function of center lag */ + + CCmax = silk_int32_MIN; + CCmax_b = silk_int32_MIN; + + CBimax = 0; /* To avoid returning undefined lag values */ + lag = -1; /* To check if lag with strong enough correlation has been found */ + + if( prevLag > 0 ) { + if( Fs_kHz == 12 ) { + prevLag = silk_DIV32_16( silk_LSHIFT( prevLag, 1 ), 3 ); + } else if( Fs_kHz == 16 ) { + prevLag = silk_RSHIFT( prevLag, 1 ); + } + prevLag_log2_Q7 = silk_lin2log( (opus_int32)prevLag ); + } else { + prevLag_log2_Q7 = 0; + } + silk_assert( search_thres2_Q13 == silk_SAT16( search_thres2_Q13 ) ); + /* Set up stage 2 codebook based on number of subframes */ + if( nb_subfr == PE_MAX_NB_SUBFR ) { + cbk_size = PE_NB_CBKS_STAGE2_EXT; + Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ]; + if( Fs_kHz == 8 && complexity > SILK_PE_MIN_COMPLEX ) { + /* If input is 8 khz use a larger codebook here because it is last stage */ + nb_cbk_search = PE_NB_CBKS_STAGE2_EXT; + } else { + nb_cbk_search = PE_NB_CBKS_STAGE2; + } + } else { + cbk_size = PE_NB_CBKS_STAGE2_10MS; + Lag_CB_ptr = &silk_CB_lags_stage2_10_ms[ 0 ][ 0 ]; + nb_cbk_search = PE_NB_CBKS_STAGE2_10MS; + } + + for( k = 0; k < length_d_srch; k++ ) { + d = d_srch[ k ]; + for( j = 0; j < nb_cbk_search; j++ ) { + CC[ j ] = 0; + for( i = 0; i < nb_subfr; i++ ) { + opus_int d_subfr; + /* Try all codebooks */ + d_subfr = d + matrix_ptr( Lag_CB_ptr, i, j, cbk_size ); + CC[ j ] = CC[ j ] + + (opus_int32)matrix_ptr( C, i, + d_subfr - ( MIN_LAG_8KHZ - 2 ), + CSTRIDE_8KHZ ); + } + } + /* Find best codebook */ + CCmax_new = silk_int32_MIN; + CBimax_new = 0; + for( i = 0; i < nb_cbk_search; i++ ) { + if( CC[ i ] > CCmax_new ) { + CCmax_new = CC[ i ]; + CBimax_new = i; + } + } + + /* Bias towards shorter lags */ + lag_log2_Q7 = silk_lin2log( d ); /* Q7 */ + silk_assert( lag_log2_Q7 == silk_SAT16( lag_log2_Q7 ) ); + silk_assert( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 13 ) == silk_SAT16( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 13 ) ) ); + CCmax_new_b = CCmax_new - silk_RSHIFT( silk_SMULBB( nb_subfr * SILK_FIX_CONST( PE_SHORTLAG_BIAS, 13 ), lag_log2_Q7 ), 7 ); /* Q13 */ + + /* Bias towards previous lag */ + silk_assert( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 13 ) == silk_SAT16( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 13 ) ) ); + if( prevLag > 0 ) { + delta_lag_log2_sqr_Q7 = lag_log2_Q7 - prevLag_log2_Q7; + silk_assert( delta_lag_log2_sqr_Q7 == silk_SAT16( delta_lag_log2_sqr_Q7 ) ); + delta_lag_log2_sqr_Q7 = silk_RSHIFT( silk_SMULBB( delta_lag_log2_sqr_Q7, delta_lag_log2_sqr_Q7 ), 7 ); + prev_lag_bias_Q13 = silk_RSHIFT( silk_SMULBB( nb_subfr * SILK_FIX_CONST( PE_PREVLAG_BIAS, 13 ), *LTPCorr_Q15 ), 15 ); /* Q13 */ + prev_lag_bias_Q13 = silk_DIV32( silk_MUL( prev_lag_bias_Q13, delta_lag_log2_sqr_Q7 ), delta_lag_log2_sqr_Q7 + SILK_FIX_CONST( 0.5, 7 ) ); + CCmax_new_b -= prev_lag_bias_Q13; /* Q13 */ + } + + if( CCmax_new_b > CCmax_b && /* Find maximum biased correlation */ + CCmax_new > silk_SMULBB( nb_subfr, search_thres2_Q13 ) && /* Correlation needs to be high enough to be voiced */ + silk_CB_lags_stage2[ 0 ][ CBimax_new ] <= MIN_LAG_8KHZ /* Lag must be in range */ + ) { + CCmax_b = CCmax_new_b; + CCmax = CCmax_new; + lag = d; + CBimax = CBimax_new; + } + } + + if( lag == -1 ) { + /* No suitable candidate found */ + silk_memset( pitch_out, 0, nb_subfr * sizeof( opus_int ) ); + *LTPCorr_Q15 = 0; + *lagIndex = 0; + *contourIndex = 0; + RESTORE_STACK; + return 1; + } + + /* Output normalized correlation */ + *LTPCorr_Q15 = (opus_int)silk_LSHIFT( silk_DIV32_16( CCmax, nb_subfr ), 2 ); + silk_assert( *LTPCorr_Q15 >= 0 ); + + if( Fs_kHz > 8 ) { + VARDECL( opus_int16, scratch_mem ); + /***************************************************************************/ + /* Scale input signal down to avoid correlations measures from overflowing */ + /***************************************************************************/ + /* find scaling as max scaling for each subframe */ + silk_sum_sqr_shift( &energy, &shift, frame, frame_length ); + ALLOC( scratch_mem, shift > 0 ? frame_length : ALLOC_NONE, opus_int16 ); + if( shift > 0 ) { + /* Move signal to scratch mem because the input signal should be unchanged */ + shift = silk_RSHIFT( shift, 1 ); + for( i = 0; i < frame_length; i++ ) { + scratch_mem[ i ] = silk_RSHIFT( frame[ i ], shift ); + } + input_frame_ptr = scratch_mem; + } else { + input_frame_ptr = frame; + } + + /* Search in original signal */ + + CBimax_old = CBimax; + /* Compensate for decimation */ + silk_assert( lag == silk_SAT16( lag ) ); + if( Fs_kHz == 12 ) { + lag = silk_RSHIFT( silk_SMULBB( lag, 3 ), 1 ); + } else if( Fs_kHz == 16 ) { + lag = silk_LSHIFT( lag, 1 ); + } else { + lag = silk_SMULBB( lag, 3 ); + } + + lag = silk_LIMIT_int( lag, min_lag, max_lag ); + start_lag = silk_max_int( lag - 2, min_lag ); + end_lag = silk_min_int( lag + 2, max_lag ); + lag_new = lag; /* to avoid undefined lag */ + CBimax = 0; /* to avoid undefined lag */ + + CCmax = silk_int32_MIN; + /* pitch lags according to second stage */ + for( k = 0; k < nb_subfr; k++ ) { + pitch_out[ k ] = lag + 2 * silk_CB_lags_stage2[ k ][ CBimax_old ]; + } + + /* Set up codebook parameters according to complexity setting and frame length */ + if( nb_subfr == PE_MAX_NB_SUBFR ) { + nb_cbk_search = (opus_int)silk_nb_cbk_searchs_stage3[ complexity ]; + cbk_size = PE_NB_CBKS_STAGE3_MAX; + Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ]; + } else { + nb_cbk_search = PE_NB_CBKS_STAGE3_10MS; + cbk_size = PE_NB_CBKS_STAGE3_10MS; + Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ]; + } + + /* Calculate the correlations and energies needed in stage 3 */ + ALLOC( energies_st3, nb_subfr * nb_cbk_search, silk_pe_stage3_vals ); + ALLOC( cross_corr_st3, nb_subfr * nb_cbk_search, silk_pe_stage3_vals ); + silk_P_Ana_calc_corr_st3( cross_corr_st3, input_frame_ptr, start_lag, sf_length, nb_subfr, complexity, arch ); + silk_P_Ana_calc_energy_st3( energies_st3, input_frame_ptr, start_lag, sf_length, nb_subfr, complexity ); + + lag_counter = 0; + silk_assert( lag == silk_SAT16( lag ) ); + contour_bias_Q15 = silk_DIV32_16( SILK_FIX_CONST( PE_FLATCONTOUR_BIAS, 15 ), lag ); + + target_ptr = &input_frame_ptr[ PE_LTP_MEM_LENGTH_MS * Fs_kHz ]; + energy_target = silk_ADD32( silk_inner_prod_aligned( target_ptr, target_ptr, nb_subfr * sf_length ), 1 ); + for( d = start_lag; d <= end_lag; d++ ) { + for( j = 0; j < nb_cbk_search; j++ ) { + cross_corr = 0; + energy = energy_target; + for( k = 0; k < nb_subfr; k++ ) { + cross_corr = silk_ADD32( cross_corr, + matrix_ptr( cross_corr_st3, k, j, + nb_cbk_search )[ lag_counter ] ); + energy = silk_ADD32( energy, + matrix_ptr( energies_st3, k, j, + nb_cbk_search )[ lag_counter ] ); + silk_assert( energy >= 0 ); + } + if( cross_corr > 0 ) { + CCmax_new = silk_DIV32_varQ( cross_corr, energy, 13 + 1 ); /* Q13 */ + /* Reduce depending on flatness of contour */ + diff = silk_int16_MAX - silk_MUL( contour_bias_Q15, j ); /* Q15 */ + silk_assert( diff == silk_SAT16( diff ) ); + CCmax_new = silk_SMULWB( CCmax_new, diff ); /* Q14 */ + } else { + CCmax_new = 0; + } + + if( CCmax_new > CCmax && ( d + silk_CB_lags_stage3[ 0 ][ j ] ) <= max_lag ) { + CCmax = CCmax_new; + lag_new = d; + CBimax = j; + } + } + lag_counter++; + } + + for( k = 0; k < nb_subfr; k++ ) { + pitch_out[ k ] = lag_new + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size ); + pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], min_lag, PE_MAX_LAG_MS * Fs_kHz ); + } + *lagIndex = (opus_int16)( lag_new - min_lag); + *contourIndex = (opus_int8)CBimax; + } else { /* Fs_kHz == 8 */ + /* Save Lags */ + for( k = 0; k < nb_subfr; k++ ) { + pitch_out[ k ] = lag + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size ); + pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], MIN_LAG_8KHZ, PE_MAX_LAG_MS * 8 ); + } + *lagIndex = (opus_int16)( lag - MIN_LAG_8KHZ ); + *contourIndex = (opus_int8)CBimax; + } + silk_assert( *lagIndex >= 0 ); + /* return as voiced */ + RESTORE_STACK; + return 0; +} + +/*********************************************************************** + * Calculates the correlations used in stage 3 search. In order to cover + * the whole lag codebook for all the searched offset lags (lag +- 2), + * the following correlations are needed in each sub frame: + * + * sf1: lag range [-8,...,7] total 16 correlations + * sf2: lag range [-4,...,4] total 9 correlations + * sf3: lag range [-3,....4] total 8 correltions + * sf4: lag range [-6,....8] total 15 correlations + * + * In total 48 correlations. The direct implementation computed in worst + * case 4*12*5 = 240 correlations, but more likely around 120. + ***********************************************************************/ +static void silk_P_Ana_calc_corr_st3( + silk_pe_stage3_vals cross_corr_st3[], /* O 3 DIM correlation array */ + const opus_int16 frame[], /* I vector to correlate */ + opus_int start_lag, /* I lag offset to search around */ + opus_int sf_length, /* I length of a 5 ms subframe */ + opus_int nb_subfr, /* I number of subframes */ + opus_int complexity, /* I Complexity setting */ + int arch /* I Run-time architecture */ +) +{ + const opus_int16 *target_ptr; + opus_int i, j, k, lag_counter, lag_low, lag_high; + opus_int nb_cbk_search, delta, idx, cbk_size; + VARDECL( opus_int32, scratch_mem ); + VARDECL( opus_int32, xcorr32 ); + const opus_int8 *Lag_range_ptr, *Lag_CB_ptr; + SAVE_STACK; + + silk_assert( complexity >= SILK_PE_MIN_COMPLEX ); + silk_assert( complexity <= SILK_PE_MAX_COMPLEX ); + + if( nb_subfr == PE_MAX_NB_SUBFR ) { + Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ]; + Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ]; + nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ]; + cbk_size = PE_NB_CBKS_STAGE3_MAX; + } else { + silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1); + Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ]; + Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ]; + nb_cbk_search = PE_NB_CBKS_STAGE3_10MS; + cbk_size = PE_NB_CBKS_STAGE3_10MS; + } + ALLOC( scratch_mem, SCRATCH_SIZE, opus_int32 ); + ALLOC( xcorr32, SCRATCH_SIZE, opus_int32 ); + + target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ]; /* Pointer to middle of frame */ + for( k = 0; k < nb_subfr; k++ ) { + lag_counter = 0; + + /* Calculate the correlations for each subframe */ + lag_low = matrix_ptr( Lag_range_ptr, k, 0, 2 ); + lag_high = matrix_ptr( Lag_range_ptr, k, 1, 2 ); + silk_assert(lag_high-lag_low+1 <= SCRATCH_SIZE); + celt_pitch_xcorr( target_ptr, target_ptr - start_lag - lag_high, xcorr32, sf_length, lag_high - lag_low + 1, arch ); + for( j = lag_low; j <= lag_high; j++ ) { + silk_assert( lag_counter < SCRATCH_SIZE ); + scratch_mem[ lag_counter ] = xcorr32[ lag_high - j ]; + lag_counter++; + } + + delta = matrix_ptr( Lag_range_ptr, k, 0, 2 ); + for( i = 0; i < nb_cbk_search; i++ ) { + /* Fill out the 3 dim array that stores the correlations for */ + /* each code_book vector for each start lag */ + idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta; + for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) { + silk_assert( idx + j < SCRATCH_SIZE ); + silk_assert( idx + j < lag_counter ); + matrix_ptr( cross_corr_st3, k, i, nb_cbk_search )[ j ] = + scratch_mem[ idx + j ]; + } + } + target_ptr += sf_length; + } + RESTORE_STACK; +} + +/********************************************************************/ +/* Calculate the energies for first two subframes. The energies are */ +/* calculated recursively. */ +/********************************************************************/ +static void silk_P_Ana_calc_energy_st3( + silk_pe_stage3_vals energies_st3[], /* O 3 DIM energy array */ + const opus_int16 frame[], /* I vector to calc energy in */ + opus_int start_lag, /* I lag offset to search around */ + opus_int sf_length, /* I length of one 5 ms subframe */ + opus_int nb_subfr, /* I number of subframes */ + opus_int complexity /* I Complexity setting */ +) +{ + const opus_int16 *target_ptr, *basis_ptr; + opus_int32 energy; + opus_int k, i, j, lag_counter; + opus_int nb_cbk_search, delta, idx, cbk_size, lag_diff; + VARDECL( opus_int32, scratch_mem ); + const opus_int8 *Lag_range_ptr, *Lag_CB_ptr; + SAVE_STACK; + + silk_assert( complexity >= SILK_PE_MIN_COMPLEX ); + silk_assert( complexity <= SILK_PE_MAX_COMPLEX ); + + if( nb_subfr == PE_MAX_NB_SUBFR ) { + Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ]; + Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ]; + nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ]; + cbk_size = PE_NB_CBKS_STAGE3_MAX; + } else { + silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1); + Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ]; + Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ]; + nb_cbk_search = PE_NB_CBKS_STAGE3_10MS; + cbk_size = PE_NB_CBKS_STAGE3_10MS; + } + ALLOC( scratch_mem, SCRATCH_SIZE, opus_int32 ); + + target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ]; + for( k = 0; k < nb_subfr; k++ ) { + lag_counter = 0; + + /* Calculate the energy for first lag */ + basis_ptr = target_ptr - ( start_lag + matrix_ptr( Lag_range_ptr, k, 0, 2 ) ); + energy = silk_inner_prod_aligned( basis_ptr, basis_ptr, sf_length ); + silk_assert( energy >= 0 ); + scratch_mem[ lag_counter ] = energy; + lag_counter++; + + lag_diff = ( matrix_ptr( Lag_range_ptr, k, 1, 2 ) - matrix_ptr( Lag_range_ptr, k, 0, 2 ) + 1 ); + for( i = 1; i < lag_diff; i++ ) { + /* remove part outside new window */ + energy -= silk_SMULBB( basis_ptr[ sf_length - i ], basis_ptr[ sf_length - i ] ); + silk_assert( energy >= 0 ); + + /* add part that comes into window */ + energy = silk_ADD_SAT32( energy, silk_SMULBB( basis_ptr[ -i ], basis_ptr[ -i ] ) ); + silk_assert( energy >= 0 ); + silk_assert( lag_counter < SCRATCH_SIZE ); + scratch_mem[ lag_counter ] = energy; + lag_counter++; + } + + delta = matrix_ptr( Lag_range_ptr, k, 0, 2 ); + for( i = 0; i < nb_cbk_search; i++ ) { + /* Fill out the 3 dim array that stores the correlations for */ + /* each code_book vector for each start lag */ + idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta; + for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) { + silk_assert( idx + j < SCRATCH_SIZE ); + silk_assert( idx + j < lag_counter ); + matrix_ptr( energies_st3, k, i, nb_cbk_search )[ j ] = + scratch_mem[ idx + j ]; + silk_assert( + matrix_ptr( energies_st3, k, i, nb_cbk_search )[ j ] >= 0 ); + } + } + target_ptr += sf_length; + } + RESTORE_STACK; +} diff --git a/src/opus-1.1/silk/fixed/prefilter_FIX.c b/src/opus-1.1/silk/fixed/prefilter_FIX.c new file mode 100644 index 00000000..d381730c --- /dev/null +++ b/src/opus-1.1/silk/fixed/prefilter_FIX.c @@ -0,0 +1,209 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main_FIX.h" +#include "stack_alloc.h" +#include "tuning_parameters.h" + +/* Prefilter for finding Quantizer input signal */ +static OPUS_INLINE void silk_prefilt_FIX( + silk_prefilter_state_FIX *P, /* I/O state */ + opus_int32 st_res_Q12[], /* I short term residual signal */ + opus_int32 xw_Q3[], /* O prefiltered signal */ + opus_int32 HarmShapeFIRPacked_Q12, /* I Harmonic shaping coeficients */ + opus_int Tilt_Q14, /* I Tilt shaping coeficient */ + opus_int32 LF_shp_Q14, /* I Low-frequancy shaping coeficients */ + opus_int lag, /* I Lag for harmonic shaping */ + opus_int length /* I Length of signals */ +); + +void silk_warped_LPC_analysis_filter_FIX( + opus_int32 state[], /* I/O State [order + 1] */ + opus_int32 res_Q2[], /* O Residual signal [length] */ + const opus_int16 coef_Q13[], /* I Coefficients [order] */ + const opus_int16 input[], /* I Input signal [length] */ + const opus_int16 lambda_Q16, /* I Warping factor */ + const opus_int length, /* I Length of input signal */ + const opus_int order /* I Filter order (even) */ +) +{ + opus_int n, i; + opus_int32 acc_Q11, tmp1, tmp2; + + /* Order must be even */ + silk_assert( ( order & 1 ) == 0 ); + + for( n = 0; n < length; n++ ) { + /* Output of lowpass section */ + tmp2 = silk_SMLAWB( state[ 0 ], state[ 1 ], lambda_Q16 ); + state[ 0 ] = silk_LSHIFT( input[ n ], 14 ); + /* Output of allpass section */ + tmp1 = silk_SMLAWB( state[ 1 ], state[ 2 ] - tmp2, lambda_Q16 ); + state[ 1 ] = tmp2; + acc_Q11 = silk_RSHIFT( order, 1 ); + acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ 0 ] ); + /* Loop over allpass sections */ + for( i = 2; i < order; i += 2 ) { + /* Output of allpass section */ + tmp2 = silk_SMLAWB( state[ i ], state[ i + 1 ] - tmp1, lambda_Q16 ); + state[ i ] = tmp1; + acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ i - 1 ] ); + /* Output of allpass section */ + tmp1 = silk_SMLAWB( state[ i + 1 ], state[ i + 2 ] - tmp2, lambda_Q16 ); + state[ i + 1 ] = tmp2; + acc_Q11 = silk_SMLAWB( acc_Q11, tmp2, coef_Q13[ i ] ); + } + state[ order ] = tmp1; + acc_Q11 = silk_SMLAWB( acc_Q11, tmp1, coef_Q13[ order - 1 ] ); + res_Q2[ n ] = silk_LSHIFT( (opus_int32)input[ n ], 2 ) - silk_RSHIFT_ROUND( acc_Q11, 9 ); + } +} + +void silk_prefilter_FIX( + silk_encoder_state_FIX *psEnc, /* I/O Encoder state */ + const silk_encoder_control_FIX *psEncCtrl, /* I Encoder control */ + opus_int32 xw_Q3[], /* O Weighted signal */ + const opus_int16 x[] /* I Speech signal */ +) +{ + silk_prefilter_state_FIX *P = &psEnc->sPrefilt; + opus_int j, k, lag; + opus_int32 tmp_32; + const opus_int16 *AR1_shp_Q13; + const opus_int16 *px; + opus_int32 *pxw_Q3; + opus_int HarmShapeGain_Q12, Tilt_Q14; + opus_int32 HarmShapeFIRPacked_Q12, LF_shp_Q14; + VARDECL( opus_int32, x_filt_Q12 ); + VARDECL( opus_int32, st_res_Q2 ); + opus_int16 B_Q10[ 2 ]; + SAVE_STACK; + + /* Set up pointers */ + px = x; + pxw_Q3 = xw_Q3; + lag = P->lagPrev; + ALLOC( x_filt_Q12, psEnc->sCmn.subfr_length, opus_int32 ); + ALLOC( st_res_Q2, psEnc->sCmn.subfr_length, opus_int32 ); + for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { + /* Update Variables that change per sub frame */ + if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { + lag = psEncCtrl->pitchL[ k ]; + } + + /* Noise shape parameters */ + HarmShapeGain_Q12 = silk_SMULWB( (opus_int32)psEncCtrl->HarmShapeGain_Q14[ k ], 16384 - psEncCtrl->HarmBoost_Q14[ k ] ); + silk_assert( HarmShapeGain_Q12 >= 0 ); + HarmShapeFIRPacked_Q12 = silk_RSHIFT( HarmShapeGain_Q12, 2 ); + HarmShapeFIRPacked_Q12 |= silk_LSHIFT( (opus_int32)silk_RSHIFT( HarmShapeGain_Q12, 1 ), 16 ); + Tilt_Q14 = psEncCtrl->Tilt_Q14[ k ]; + LF_shp_Q14 = psEncCtrl->LF_shp_Q14[ k ]; + AR1_shp_Q13 = &psEncCtrl->AR1_Q13[ k * MAX_SHAPE_LPC_ORDER ]; + + /* Short term FIR filtering*/ + silk_warped_LPC_analysis_filter_FIX( P->sAR_shp, st_res_Q2, AR1_shp_Q13, px, + psEnc->sCmn.warping_Q16, psEnc->sCmn.subfr_length, psEnc->sCmn.shapingLPCOrder ); + + /* Reduce (mainly) low frequencies during harmonic emphasis */ + B_Q10[ 0 ] = silk_RSHIFT_ROUND( psEncCtrl->GainsPre_Q14[ k ], 4 ); + tmp_32 = silk_SMLABB( SILK_FIX_CONST( INPUT_TILT, 26 ), psEncCtrl->HarmBoost_Q14[ k ], HarmShapeGain_Q12 ); /* Q26 */ + tmp_32 = silk_SMLABB( tmp_32, psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( HIGH_RATE_INPUT_TILT, 12 ) ); /* Q26 */ + tmp_32 = silk_SMULWB( tmp_32, -psEncCtrl->GainsPre_Q14[ k ] ); /* Q24 */ + tmp_32 = silk_RSHIFT_ROUND( tmp_32, 14 ); /* Q10 */ + B_Q10[ 1 ]= silk_SAT16( tmp_32 ); + x_filt_Q12[ 0 ] = silk_MLA( silk_MUL( st_res_Q2[ 0 ], B_Q10[ 0 ] ), P->sHarmHP_Q2, B_Q10[ 1 ] ); + for( j = 1; j < psEnc->sCmn.subfr_length; j++ ) { + x_filt_Q12[ j ] = silk_MLA( silk_MUL( st_res_Q2[ j ], B_Q10[ 0 ] ), st_res_Q2[ j - 1 ], B_Q10[ 1 ] ); + } + P->sHarmHP_Q2 = st_res_Q2[ psEnc->sCmn.subfr_length - 1 ]; + + silk_prefilt_FIX( P, x_filt_Q12, pxw_Q3, HarmShapeFIRPacked_Q12, Tilt_Q14, LF_shp_Q14, lag, psEnc->sCmn.subfr_length ); + + px += psEnc->sCmn.subfr_length; + pxw_Q3 += psEnc->sCmn.subfr_length; + } + + P->lagPrev = psEncCtrl->pitchL[ psEnc->sCmn.nb_subfr - 1 ]; + RESTORE_STACK; +} + +/* Prefilter for finding Quantizer input signal */ +static OPUS_INLINE void silk_prefilt_FIX( + silk_prefilter_state_FIX *P, /* I/O state */ + opus_int32 st_res_Q12[], /* I short term residual signal */ + opus_int32 xw_Q3[], /* O prefiltered signal */ + opus_int32 HarmShapeFIRPacked_Q12, /* I Harmonic shaping coeficients */ + opus_int Tilt_Q14, /* I Tilt shaping coeficient */ + opus_int32 LF_shp_Q14, /* I Low-frequancy shaping coeficients */ + opus_int lag, /* I Lag for harmonic shaping */ + opus_int length /* I Length of signals */ +) +{ + opus_int i, idx, LTP_shp_buf_idx; + opus_int32 n_LTP_Q12, n_Tilt_Q10, n_LF_Q10; + opus_int32 sLF_MA_shp_Q12, sLF_AR_shp_Q12; + opus_int16 *LTP_shp_buf; + + /* To speed up use temp variables instead of using the struct */ + LTP_shp_buf = P->sLTP_shp; + LTP_shp_buf_idx = P->sLTP_shp_buf_idx; + sLF_AR_shp_Q12 = P->sLF_AR_shp_Q12; + sLF_MA_shp_Q12 = P->sLF_MA_shp_Q12; + + for( i = 0; i < length; i++ ) { + if( lag > 0 ) { + /* unrolled loop */ + silk_assert( HARM_SHAPE_FIR_TAPS == 3 ); + idx = lag + LTP_shp_buf_idx; + n_LTP_Q12 = silk_SMULBB( LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 - 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 ); + n_LTP_Q12 = silk_SMLABT( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 ) & LTP_MASK ], HarmShapeFIRPacked_Q12 ); + n_LTP_Q12 = silk_SMLABB( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 + 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 ); + } else { + n_LTP_Q12 = 0; + } + + n_Tilt_Q10 = silk_SMULWB( sLF_AR_shp_Q12, Tilt_Q14 ); + n_LF_Q10 = silk_SMLAWB( silk_SMULWT( sLF_AR_shp_Q12, LF_shp_Q14 ), sLF_MA_shp_Q12, LF_shp_Q14 ); + + sLF_AR_shp_Q12 = silk_SUB32( st_res_Q12[ i ], silk_LSHIFT( n_Tilt_Q10, 2 ) ); + sLF_MA_shp_Q12 = silk_SUB32( sLF_AR_shp_Q12, silk_LSHIFT( n_LF_Q10, 2 ) ); + + LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK; + LTP_shp_buf[ LTP_shp_buf_idx ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sLF_MA_shp_Q12, 12 ) ); + + xw_Q3[i] = silk_RSHIFT_ROUND( silk_SUB32( sLF_MA_shp_Q12, n_LTP_Q12 ), 9 ); + } + + /* Copy temp variable back to state */ + P->sLF_AR_shp_Q12 = sLF_AR_shp_Q12; + P->sLF_MA_shp_Q12 = sLF_MA_shp_Q12; + P->sLTP_shp_buf_idx = LTP_shp_buf_idx; +} diff --git a/src/opus-1.1/silk/fixed/process_gains_FIX.c b/src/opus-1.1/silk/fixed/process_gains_FIX.c new file mode 100644 index 00000000..05aba317 --- /dev/null +++ b/src/opus-1.1/silk/fixed/process_gains_FIX.c @@ -0,0 +1,117 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main_FIX.h" +#include "tuning_parameters.h" + +/* Processing of gains */ +void silk_process_gains_FIX( + silk_encoder_state_FIX *psEnc, /* I/O Encoder state */ + silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control */ + opus_int condCoding /* I The type of conditional coding to use */ +) +{ + silk_shape_state_FIX *psShapeSt = &psEnc->sShape; + opus_int k; + opus_int32 s_Q16, InvMaxSqrVal_Q16, gain, gain_squared, ResNrg, ResNrgPart, quant_offset_Q10; + + /* Gain reduction when LTP coding gain is high */ + if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { + /*s = -0.5f * silk_sigmoid( 0.25f * ( psEncCtrl->LTPredCodGain - 12.0f ) ); */ + s_Q16 = -silk_sigm_Q15( silk_RSHIFT_ROUND( psEncCtrl->LTPredCodGain_Q7 - SILK_FIX_CONST( 12.0, 7 ), 4 ) ); + for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { + psEncCtrl->Gains_Q16[ k ] = silk_SMLAWB( psEncCtrl->Gains_Q16[ k ], psEncCtrl->Gains_Q16[ k ], s_Q16 ); + } + } + + /* Limit the quantized signal */ + /* InvMaxSqrVal = pow( 2.0f, 0.33f * ( 21.0f - SNR_dB ) ) / subfr_length; */ + InvMaxSqrVal_Q16 = silk_DIV32_16( silk_log2lin( + silk_SMULWB( SILK_FIX_CONST( 21 + 16 / 0.33, 7 ) - psEnc->sCmn.SNR_dB_Q7, SILK_FIX_CONST( 0.33, 16 ) ) ), psEnc->sCmn.subfr_length ); + + for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { + /* Soft limit on ratio residual energy and squared gains */ + ResNrg = psEncCtrl->ResNrg[ k ]; + ResNrgPart = silk_SMULWW( ResNrg, InvMaxSqrVal_Q16 ); + if( psEncCtrl->ResNrgQ[ k ] > 0 ) { + ResNrgPart = silk_RSHIFT_ROUND( ResNrgPart, psEncCtrl->ResNrgQ[ k ] ); + } else { + if( ResNrgPart >= silk_RSHIFT( silk_int32_MAX, -psEncCtrl->ResNrgQ[ k ] ) ) { + ResNrgPart = silk_int32_MAX; + } else { + ResNrgPart = silk_LSHIFT( ResNrgPart, -psEncCtrl->ResNrgQ[ k ] ); + } + } + gain = psEncCtrl->Gains_Q16[ k ]; + gain_squared = silk_ADD_SAT32( ResNrgPart, silk_SMMUL( gain, gain ) ); + if( gain_squared < silk_int16_MAX ) { + /* recalculate with higher precision */ + gain_squared = silk_SMLAWW( silk_LSHIFT( ResNrgPart, 16 ), gain, gain ); + silk_assert( gain_squared > 0 ); + gain = silk_SQRT_APPROX( gain_squared ); /* Q8 */ + gain = silk_min( gain, silk_int32_MAX >> 8 ); + psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT_SAT32( gain, 8 ); /* Q16 */ + } else { + gain = silk_SQRT_APPROX( gain_squared ); /* Q0 */ + gain = silk_min( gain, silk_int32_MAX >> 16 ); + psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT_SAT32( gain, 16 ); /* Q16 */ + } + } + + /* Save unquantized gains and gain Index */ + silk_memcpy( psEncCtrl->GainsUnq_Q16, psEncCtrl->Gains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) ); + psEncCtrl->lastGainIndexPrev = psShapeSt->LastGainIndex; + + /* Quantize gains */ + silk_gains_quant( psEnc->sCmn.indices.GainsIndices, psEncCtrl->Gains_Q16, + &psShapeSt->LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); + + /* Set quantizer offset for voiced signals. Larger offset when LTP coding gain is low or tilt is high (ie low-pass) */ + if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { + if( psEncCtrl->LTPredCodGain_Q7 + silk_RSHIFT( psEnc->sCmn.input_tilt_Q15, 8 ) > SILK_FIX_CONST( 1.0, 7 ) ) { + psEnc->sCmn.indices.quantOffsetType = 0; + } else { + psEnc->sCmn.indices.quantOffsetType = 1; + } + } + + /* Quantizer boundary adjustment */ + quant_offset_Q10 = silk_Quantization_Offsets_Q10[ psEnc->sCmn.indices.signalType >> 1 ][ psEnc->sCmn.indices.quantOffsetType ]; + psEncCtrl->Lambda_Q10 = SILK_FIX_CONST( LAMBDA_OFFSET, 10 ) + + silk_SMULBB( SILK_FIX_CONST( LAMBDA_DELAYED_DECISIONS, 10 ), psEnc->sCmn.nStatesDelayedDecision ) + + silk_SMULWB( SILK_FIX_CONST( LAMBDA_SPEECH_ACT, 18 ), psEnc->sCmn.speech_activity_Q8 ) + + silk_SMULWB( SILK_FIX_CONST( LAMBDA_INPUT_QUALITY, 12 ), psEncCtrl->input_quality_Q14 ) + + silk_SMULWB( SILK_FIX_CONST( LAMBDA_CODING_QUALITY, 12 ), psEncCtrl->coding_quality_Q14 ) + + silk_SMULWB( SILK_FIX_CONST( LAMBDA_QUANT_OFFSET, 16 ), quant_offset_Q10 ); + + silk_assert( psEncCtrl->Lambda_Q10 > 0 ); + silk_assert( psEncCtrl->Lambda_Q10 < SILK_FIX_CONST( 2, 10 ) ); +} diff --git a/src/opus-1.1/silk/fixed/regularize_correlations_FIX.c b/src/opus-1.1/silk/fixed/regularize_correlations_FIX.c new file mode 100644 index 00000000..a2836b05 --- /dev/null +++ b/src/opus-1.1/silk/fixed/regularize_correlations_FIX.c @@ -0,0 +1,47 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main_FIX.h" + +/* Add noise to matrix diagonal */ +void silk_regularize_correlations_FIX( + opus_int32 *XX, /* I/O Correlation matrices */ + opus_int32 *xx, /* I/O Correlation values */ + opus_int32 noise, /* I Noise to add */ + opus_int D /* I Dimension of XX */ +) +{ + opus_int i; + for( i = 0; i < D; i++ ) { + matrix_ptr( &XX[ 0 ], i, i, D ) = silk_ADD32( matrix_ptr( &XX[ 0 ], i, i, D ), noise ); + } + xx[ 0 ] += noise; +} diff --git a/src/opus-1.1/silk/fixed/residual_energy16_FIX.c b/src/opus-1.1/silk/fixed/residual_energy16_FIX.c new file mode 100644 index 00000000..ebffb2a6 --- /dev/null +++ b/src/opus-1.1/silk/fixed/residual_energy16_FIX.c @@ -0,0 +1,103 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main_FIX.h" + +/* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */ +opus_int32 silk_residual_energy16_covar_FIX( + const opus_int16 *c, /* I Prediction vector */ + const opus_int32 *wXX, /* I Correlation matrix */ + const opus_int32 *wXx, /* I Correlation vector */ + opus_int32 wxx, /* I Signal energy */ + opus_int D, /* I Dimension */ + opus_int cQ /* I Q value for c vector 0 - 15 */ +) +{ + opus_int i, j, lshifts, Qxtra; + opus_int32 c_max, w_max, tmp, tmp2, nrg; + opus_int cn[ MAX_MATRIX_SIZE ]; + const opus_int32 *pRow; + + /* Safety checks */ + silk_assert( D >= 0 ); + silk_assert( D <= 16 ); + silk_assert( cQ > 0 ); + silk_assert( cQ < 16 ); + + lshifts = 16 - cQ; + Qxtra = lshifts; + + c_max = 0; + for( i = 0; i < D; i++ ) { + c_max = silk_max_32( c_max, silk_abs( (opus_int32)c[ i ] ) ); + } + Qxtra = silk_min_int( Qxtra, silk_CLZ32( c_max ) - 17 ); + + w_max = silk_max_32( wXX[ 0 ], wXX[ D * D - 1 ] ); + Qxtra = silk_min_int( Qxtra, silk_CLZ32( silk_MUL( D, silk_RSHIFT( silk_SMULWB( w_max, c_max ), 4 ) ) ) - 5 ); + Qxtra = silk_max_int( Qxtra, 0 ); + for( i = 0; i < D; i++ ) { + cn[ i ] = silk_LSHIFT( ( opus_int )c[ i ], Qxtra ); + silk_assert( silk_abs(cn[i]) <= ( silk_int16_MAX + 1 ) ); /* Check that silk_SMLAWB can be used */ + } + lshifts -= Qxtra; + + /* Compute wxx - 2 * wXx * c */ + tmp = 0; + for( i = 0; i < D; i++ ) { + tmp = silk_SMLAWB( tmp, wXx[ i ], cn[ i ] ); + } + nrg = silk_RSHIFT( wxx, 1 + lshifts ) - tmp; /* Q: -lshifts - 1 */ + + /* Add c' * wXX * c, assuming wXX is symmetric */ + tmp2 = 0; + for( i = 0; i < D; i++ ) { + tmp = 0; + pRow = &wXX[ i * D ]; + for( j = i + 1; j < D; j++ ) { + tmp = silk_SMLAWB( tmp, pRow[ j ], cn[ j ] ); + } + tmp = silk_SMLAWB( tmp, silk_RSHIFT( pRow[ i ], 1 ), cn[ i ] ); + tmp2 = silk_SMLAWB( tmp2, tmp, cn[ i ] ); + } + nrg = silk_ADD_LSHIFT32( nrg, tmp2, lshifts ); /* Q: -lshifts - 1 */ + + /* Keep one bit free always, because we add them for LSF interpolation */ + if( nrg < 1 ) { + nrg = 1; + } else if( nrg > silk_RSHIFT( silk_int32_MAX, lshifts + 2 ) ) { + nrg = silk_int32_MAX >> 1; + } else { + nrg = silk_LSHIFT( nrg, lshifts + 1 ); /* Q0 */ + } + return nrg; + +} diff --git a/src/opus-1.1/silk/fixed/residual_energy_FIX.c b/src/opus-1.1/silk/fixed/residual_energy_FIX.c new file mode 100644 index 00000000..105ae318 --- /dev/null +++ b/src/opus-1.1/silk/fixed/residual_energy_FIX.c @@ -0,0 +1,97 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main_FIX.h" +#include "stack_alloc.h" + +/* Calculates residual energies of input subframes where all subframes have LPC_order */ +/* of preceding samples */ +void silk_residual_energy_FIX( + opus_int32 nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */ + opus_int nrgsQ[ MAX_NB_SUBFR ], /* O Q value per subframe */ + const opus_int16 x[], /* I Input signal */ + opus_int16 a_Q12[ 2 ][ MAX_LPC_ORDER ], /* I AR coefs for each frame half */ + const opus_int32 gains[ MAX_NB_SUBFR ], /* I Quantization gains */ + const opus_int subfr_length, /* I Subframe length */ + const opus_int nb_subfr, /* I Number of subframes */ + const opus_int LPC_order /* I LPC order */ +) +{ + opus_int offset, i, j, rshift, lz1, lz2; + opus_int16 *LPC_res_ptr; + VARDECL( opus_int16, LPC_res ); + const opus_int16 *x_ptr; + opus_int32 tmp32; + SAVE_STACK; + + x_ptr = x; + offset = LPC_order + subfr_length; + + /* Filter input to create the LPC residual for each frame half, and measure subframe energies */ + ALLOC( LPC_res, ( MAX_NB_SUBFR >> 1 ) * offset, opus_int16 ); + silk_assert( ( nb_subfr >> 1 ) * ( MAX_NB_SUBFR >> 1 ) == nb_subfr ); + for( i = 0; i < nb_subfr >> 1; i++ ) { + /* Calculate half frame LPC residual signal including preceding samples */ + silk_LPC_analysis_filter( LPC_res, x_ptr, a_Q12[ i ], ( MAX_NB_SUBFR >> 1 ) * offset, LPC_order ); + + /* Point to first subframe of the just calculated LPC residual signal */ + LPC_res_ptr = LPC_res + LPC_order; + for( j = 0; j < ( MAX_NB_SUBFR >> 1 ); j++ ) { + /* Measure subframe energy */ + silk_sum_sqr_shift( &nrgs[ i * ( MAX_NB_SUBFR >> 1 ) + j ], &rshift, LPC_res_ptr, subfr_length ); + + /* Set Q values for the measured energy */ + nrgsQ[ i * ( MAX_NB_SUBFR >> 1 ) + j ] = -rshift; + + /* Move to next subframe */ + LPC_res_ptr += offset; + } + /* Move to next frame half */ + x_ptr += ( MAX_NB_SUBFR >> 1 ) * offset; + } + + /* Apply the squared subframe gains */ + for( i = 0; i < nb_subfr; i++ ) { + /* Fully upscale gains and energies */ + lz1 = silk_CLZ32( nrgs[ i ] ) - 1; + lz2 = silk_CLZ32( gains[ i ] ) - 1; + + tmp32 = silk_LSHIFT32( gains[ i ], lz2 ); + + /* Find squared gains */ + tmp32 = silk_SMMUL( tmp32, tmp32 ); /* Q( 2 * lz2 - 32 )*/ + + /* Scale energies */ + nrgs[ i ] = silk_SMMUL( tmp32, silk_LSHIFT32( nrgs[ i ], lz1 ) ); /* Q( nrgsQ[ i ] + lz1 + 2 * lz2 - 32 - 32 )*/ + nrgsQ[ i ] += lz1 + 2 * lz2 - 32 - 32; + } + RESTORE_STACK; +} diff --git a/src/opus-1.1/silk/fixed/schur64_FIX.c b/src/opus-1.1/silk/fixed/schur64_FIX.c new file mode 100644 index 00000000..764a10ef --- /dev/null +++ b/src/opus-1.1/silk/fixed/schur64_FIX.c @@ -0,0 +1,92 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SigProc_FIX.h" + +/* Slower than schur(), but more accurate. */ +/* Uses SMULL(), available on armv4 */ +opus_int32 silk_schur64( /* O returns residual energy */ + opus_int32 rc_Q16[], /* O Reflection coefficients [order] Q16 */ + const opus_int32 c[], /* I Correlations [order+1] */ + opus_int32 order /* I Prediction order */ +) +{ + opus_int k, n; + opus_int32 C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ]; + opus_int32 Ctmp1_Q30, Ctmp2_Q30, rc_tmp_Q31; + + silk_assert( order==6||order==8||order==10||order==12||order==14||order==16 ); + + /* Check for invalid input */ + if( c[ 0 ] <= 0 ) { + silk_memset( rc_Q16, 0, order * sizeof( opus_int32 ) ); + return 0; + } + + for( k = 0; k < order + 1; k++ ) { + C[ k ][ 0 ] = C[ k ][ 1 ] = c[ k ]; + } + + for( k = 0; k < order; k++ ) { + /* Check that we won't be getting an unstable rc, otherwise stop here. */ + if (silk_abs_int32(C[ k + 1 ][ 0 ]) >= C[ 0 ][ 1 ]) { + if ( C[ k + 1 ][ 0 ] > 0 ) { + rc_Q16[ k ] = -SILK_FIX_CONST( .99f, 16 ); + } else { + rc_Q16[ k ] = SILK_FIX_CONST( .99f, 16 ); + } + k++; + break; + } + + /* Get reflection coefficient: divide two Q30 values and get result in Q31 */ + rc_tmp_Q31 = silk_DIV32_varQ( -C[ k + 1 ][ 0 ], C[ 0 ][ 1 ], 31 ); + + /* Save the output */ + rc_Q16[ k ] = silk_RSHIFT_ROUND( rc_tmp_Q31, 15 ); + + /* Update correlations */ + for( n = 0; n < order - k; n++ ) { + Ctmp1_Q30 = C[ n + k + 1 ][ 0 ]; + Ctmp2_Q30 = C[ n ][ 1 ]; + + /* Multiply and add the highest int32 */ + C[ n + k + 1 ][ 0 ] = Ctmp1_Q30 + silk_SMMUL( silk_LSHIFT( Ctmp2_Q30, 1 ), rc_tmp_Q31 ); + C[ n ][ 1 ] = Ctmp2_Q30 + silk_SMMUL( silk_LSHIFT( Ctmp1_Q30, 1 ), rc_tmp_Q31 ); + } + } + + for(; k < order; k++ ) { + rc_Q16[ k ] = 0; + } + + return silk_max_32( 1, C[ 0 ][ 1 ] ); +} diff --git a/src/opus-1.1/silk/fixed/schur_FIX.c b/src/opus-1.1/silk/fixed/schur_FIX.c new file mode 100644 index 00000000..c4c0ef23 --- /dev/null +++ b/src/opus-1.1/silk/fixed/schur_FIX.c @@ -0,0 +1,106 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SigProc_FIX.h" + +/* Faster than schur64(), but much less accurate. */ +/* uses SMLAWB(), requiring armv5E and higher. */ +opus_int32 silk_schur( /* O Returns residual energy */ + opus_int16 *rc_Q15, /* O reflection coefficients [order] Q15 */ + const opus_int32 *c, /* I correlations [order+1] */ + const opus_int32 order /* I prediction order */ +) +{ + opus_int k, n, lz; + opus_int32 C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ]; + opus_int32 Ctmp1, Ctmp2, rc_tmp_Q15; + + silk_assert( order==6||order==8||order==10||order==12||order==14||order==16 ); + + /* Get number of leading zeros */ + lz = silk_CLZ32( c[ 0 ] ); + + /* Copy correlations and adjust level to Q30 */ + if( lz < 2 ) { + /* lz must be 1, so shift one to the right */ + for( k = 0; k < order + 1; k++ ) { + C[ k ][ 0 ] = C[ k ][ 1 ] = silk_RSHIFT( c[ k ], 1 ); + } + } else if( lz > 2 ) { + /* Shift to the left */ + lz -= 2; + for( k = 0; k < order + 1; k++ ) { + C[ k ][ 0 ] = C[ k ][ 1 ] = silk_LSHIFT( c[ k ], lz ); + } + } else { + /* No need to shift */ + for( k = 0; k < order + 1; k++ ) { + C[ k ][ 0 ] = C[ k ][ 1 ] = c[ k ]; + } + } + + for( k = 0; k < order; k++ ) { + /* Check that we won't be getting an unstable rc, otherwise stop here. */ + if (silk_abs_int32(C[ k + 1 ][ 0 ]) >= C[ 0 ][ 1 ]) { + if ( C[ k + 1 ][ 0 ] > 0 ) { + rc_Q15[ k ] = -SILK_FIX_CONST( .99f, 15 ); + } else { + rc_Q15[ k ] = SILK_FIX_CONST( .99f, 15 ); + } + k++; + break; + } + + /* Get reflection coefficient */ + rc_tmp_Q15 = -silk_DIV32_16( C[ k + 1 ][ 0 ], silk_max_32( silk_RSHIFT( C[ 0 ][ 1 ], 15 ), 1 ) ); + + /* Clip (shouldn't happen for properly conditioned inputs) */ + rc_tmp_Q15 = silk_SAT16( rc_tmp_Q15 ); + + /* Store */ + rc_Q15[ k ] = (opus_int16)rc_tmp_Q15; + + /* Update correlations */ + for( n = 0; n < order - k; n++ ) { + Ctmp1 = C[ n + k + 1 ][ 0 ]; + Ctmp2 = C[ n ][ 1 ]; + C[ n + k + 1 ][ 0 ] = silk_SMLAWB( Ctmp1, silk_LSHIFT( Ctmp2, 1 ), rc_tmp_Q15 ); + C[ n ][ 1 ] = silk_SMLAWB( Ctmp2, silk_LSHIFT( Ctmp1, 1 ), rc_tmp_Q15 ); + } + } + + for(; k < order; k++ ) { + rc_Q15[ k ] = 0; + } + + /* return residual energy */ + return silk_max_32( 1, C[ 0 ][ 1 ] ); +} diff --git a/src/opus-1.1/silk/fixed/solve_LS_FIX.c b/src/opus-1.1/silk/fixed/solve_LS_FIX.c new file mode 100644 index 00000000..51d7d49d --- /dev/null +++ b/src/opus-1.1/silk/fixed/solve_LS_FIX.c @@ -0,0 +1,249 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main_FIX.h" +#include "stack_alloc.h" +#include "tuning_parameters.h" + +/*****************************/ +/* Internal function headers */ +/*****************************/ + +typedef struct { + opus_int32 Q36_part; + opus_int32 Q48_part; +} inv_D_t; + +/* Factorize square matrix A into LDL form */ +static OPUS_INLINE void silk_LDL_factorize_FIX( + opus_int32 *A, /* I/O Pointer to Symetric Square Matrix */ + opus_int M, /* I Size of Matrix */ + opus_int32 *L_Q16, /* I/O Pointer to Square Upper triangular Matrix */ + inv_D_t *inv_D /* I/O Pointer to vector holding inverted diagonal elements of D */ +); + +/* Solve Lx = b, when L is lower triangular and has ones on the diagonal */ +static OPUS_INLINE void silk_LS_SolveFirst_FIX( + const opus_int32 *L_Q16, /* I Pointer to Lower Triangular Matrix */ + opus_int M, /* I Dim of Matrix equation */ + const opus_int32 *b, /* I b Vector */ + opus_int32 *x_Q16 /* O x Vector */ +); + +/* Solve L^t*x = b, where L is lower triangular with ones on the diagonal */ +static OPUS_INLINE void silk_LS_SolveLast_FIX( + const opus_int32 *L_Q16, /* I Pointer to Lower Triangular Matrix */ + const opus_int M, /* I Dim of Matrix equation */ + const opus_int32 *b, /* I b Vector */ + opus_int32 *x_Q16 /* O x Vector */ +); + +static OPUS_INLINE void silk_LS_divide_Q16_FIX( + opus_int32 T[], /* I/O Numenator vector */ + inv_D_t *inv_D, /* I 1 / D vector */ + opus_int M /* I dimension */ +); + +/* Solves Ax = b, assuming A is symmetric */ +void silk_solve_LDL_FIX( + opus_int32 *A, /* I Pointer to symetric square matrix A */ + opus_int M, /* I Size of matrix */ + const opus_int32 *b, /* I Pointer to b vector */ + opus_int32 *x_Q16 /* O Pointer to x solution vector */ +) +{ + VARDECL( opus_int32, L_Q16 ); + opus_int32 Y[ MAX_MATRIX_SIZE ]; + inv_D_t inv_D[ MAX_MATRIX_SIZE ]; + SAVE_STACK; + + silk_assert( M <= MAX_MATRIX_SIZE ); + ALLOC( L_Q16, M * M, opus_int32 ); + + /*************************************************** + Factorize A by LDL such that A = L*D*L', + where L is lower triangular with ones on diagonal + ****************************************************/ + silk_LDL_factorize_FIX( A, M, L_Q16, inv_D ); + + /**************************************************** + * substitute D*L'*x = Y. ie: + L*D*L'*x = b => L*Y = b <=> Y = inv(L)*b + ******************************************************/ + silk_LS_SolveFirst_FIX( L_Q16, M, b, Y ); + + /**************************************************** + D*L'*x = Y <=> L'*x = inv(D)*Y, because D is + diagonal just multiply with 1/d_i + ****************************************************/ + silk_LS_divide_Q16_FIX( Y, inv_D, M ); + + /**************************************************** + x = inv(L') * inv(D) * Y + *****************************************************/ + silk_LS_SolveLast_FIX( L_Q16, M, Y, x_Q16 ); + RESTORE_STACK; +} + +static OPUS_INLINE void silk_LDL_factorize_FIX( + opus_int32 *A, /* I/O Pointer to Symetric Square Matrix */ + opus_int M, /* I Size of Matrix */ + opus_int32 *L_Q16, /* I/O Pointer to Square Upper triangular Matrix */ + inv_D_t *inv_D /* I/O Pointer to vector holding inverted diagonal elements of D */ +) +{ + opus_int i, j, k, status, loop_count; + const opus_int32 *ptr1, *ptr2; + opus_int32 diag_min_value, tmp_32, err; + opus_int32 v_Q0[ MAX_MATRIX_SIZE ], D_Q0[ MAX_MATRIX_SIZE ]; + opus_int32 one_div_diag_Q36, one_div_diag_Q40, one_div_diag_Q48; + + silk_assert( M <= MAX_MATRIX_SIZE ); + + status = 1; + diag_min_value = silk_max_32( silk_SMMUL( silk_ADD_SAT32( A[ 0 ], A[ silk_SMULBB( M, M ) - 1 ] ), SILK_FIX_CONST( FIND_LTP_COND_FAC, 31 ) ), 1 << 9 ); + for( loop_count = 0; loop_count < M && status == 1; loop_count++ ) { + status = 0; + for( j = 0; j < M; j++ ) { + ptr1 = matrix_adr( L_Q16, j, 0, M ); + tmp_32 = 0; + for( i = 0; i < j; i++ ) { + v_Q0[ i ] = silk_SMULWW( D_Q0[ i ], ptr1[ i ] ); /* Q0 */ + tmp_32 = silk_SMLAWW( tmp_32, v_Q0[ i ], ptr1[ i ] ); /* Q0 */ + } + tmp_32 = silk_SUB32( matrix_ptr( A, j, j, M ), tmp_32 ); + + if( tmp_32 < diag_min_value ) { + tmp_32 = silk_SUB32( silk_SMULBB( loop_count + 1, diag_min_value ), tmp_32 ); + /* Matrix not positive semi-definite, or ill conditioned */ + for( i = 0; i < M; i++ ) { + matrix_ptr( A, i, i, M ) = silk_ADD32( matrix_ptr( A, i, i, M ), tmp_32 ); + } + status = 1; + break; + } + D_Q0[ j ] = tmp_32; /* always < max(Correlation) */ + + /* two-step division */ + one_div_diag_Q36 = silk_INVERSE32_varQ( tmp_32, 36 ); /* Q36 */ + one_div_diag_Q40 = silk_LSHIFT( one_div_diag_Q36, 4 ); /* Q40 */ + err = silk_SUB32( (opus_int32)1 << 24, silk_SMULWW( tmp_32, one_div_diag_Q40 ) ); /* Q24 */ + one_div_diag_Q48 = silk_SMULWW( err, one_div_diag_Q40 ); /* Q48 */ + + /* Save 1/Ds */ + inv_D[ j ].Q36_part = one_div_diag_Q36; + inv_D[ j ].Q48_part = one_div_diag_Q48; + + matrix_ptr( L_Q16, j, j, M ) = 65536; /* 1.0 in Q16 */ + ptr1 = matrix_adr( A, j, 0, M ); + ptr2 = matrix_adr( L_Q16, j + 1, 0, M ); + for( i = j + 1; i < M; i++ ) { + tmp_32 = 0; + for( k = 0; k < j; k++ ) { + tmp_32 = silk_SMLAWW( tmp_32, v_Q0[ k ], ptr2[ k ] ); /* Q0 */ + } + tmp_32 = silk_SUB32( ptr1[ i ], tmp_32 ); /* always < max(Correlation) */ + + /* tmp_32 / D_Q0[j] : Divide to Q16 */ + matrix_ptr( L_Q16, i, j, M ) = silk_ADD32( silk_SMMUL( tmp_32, one_div_diag_Q48 ), + silk_RSHIFT( silk_SMULWW( tmp_32, one_div_diag_Q36 ), 4 ) ); + + /* go to next column */ + ptr2 += M; + } + } + } + + silk_assert( status == 0 ); +} + +static OPUS_INLINE void silk_LS_divide_Q16_FIX( + opus_int32 T[], /* I/O Numenator vector */ + inv_D_t *inv_D, /* I 1 / D vector */ + opus_int M /* I dimension */ +) +{ + opus_int i; + opus_int32 tmp_32; + opus_int32 one_div_diag_Q36, one_div_diag_Q48; + + for( i = 0; i < M; i++ ) { + one_div_diag_Q36 = inv_D[ i ].Q36_part; + one_div_diag_Q48 = inv_D[ i ].Q48_part; + + tmp_32 = T[ i ]; + T[ i ] = silk_ADD32( silk_SMMUL( tmp_32, one_div_diag_Q48 ), silk_RSHIFT( silk_SMULWW( tmp_32, one_div_diag_Q36 ), 4 ) ); + } +} + +/* Solve Lx = b, when L is lower triangular and has ones on the diagonal */ +static OPUS_INLINE void silk_LS_SolveFirst_FIX( + const opus_int32 *L_Q16, /* I Pointer to Lower Triangular Matrix */ + opus_int M, /* I Dim of Matrix equation */ + const opus_int32 *b, /* I b Vector */ + opus_int32 *x_Q16 /* O x Vector */ +) +{ + opus_int i, j; + const opus_int32 *ptr32; + opus_int32 tmp_32; + + for( i = 0; i < M; i++ ) { + ptr32 = matrix_adr( L_Q16, i, 0, M ); + tmp_32 = 0; + for( j = 0; j < i; j++ ) { + tmp_32 = silk_SMLAWW( tmp_32, ptr32[ j ], x_Q16[ j ] ); + } + x_Q16[ i ] = silk_SUB32( b[ i ], tmp_32 ); + } +} + +/* Solve L^t*x = b, where L is lower triangular with ones on the diagonal */ +static OPUS_INLINE void silk_LS_SolveLast_FIX( + const opus_int32 *L_Q16, /* I Pointer to Lower Triangular Matrix */ + const opus_int M, /* I Dim of Matrix equation */ + const opus_int32 *b, /* I b Vector */ + opus_int32 *x_Q16 /* O x Vector */ +) +{ + opus_int i, j; + const opus_int32 *ptr32; + opus_int32 tmp_32; + + for( i = M - 1; i >= 0; i-- ) { + ptr32 = matrix_adr( L_Q16, 0, i, M ); + tmp_32 = 0; + for( j = M - 1; j > i; j-- ) { + tmp_32 = silk_SMLAWW( tmp_32, ptr32[ silk_SMULBB( j, M ) ], x_Q16[ j ] ); + } + x_Q16[ i ] = silk_SUB32( b[ i ], tmp_32 ); + } +} diff --git a/src/opus-1.1/silk/fixed/structs_FIX.h b/src/opus-1.1/silk/fixed/structs_FIX.h new file mode 100644 index 00000000..244b4793 --- /dev/null +++ b/src/opus-1.1/silk/fixed/structs_FIX.h @@ -0,0 +1,133 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifndef SILK_STRUCTS_FIX_H +#define SILK_STRUCTS_FIX_H + +#include "typedef.h" +#include "main.h" +#include "structs.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************/ +/* Noise shaping analysis state */ +/********************************/ +typedef struct { + opus_int8 LastGainIndex; + opus_int32 HarmBoost_smth_Q16; + opus_int32 HarmShapeGain_smth_Q16; + opus_int32 Tilt_smth_Q16; +} silk_shape_state_FIX; + +/********************************/ +/* Prefilter state */ +/********************************/ +typedef struct { + opus_int16 sLTP_shp[ LTP_BUF_LENGTH ]; + opus_int32 sAR_shp[ MAX_SHAPE_LPC_ORDER + 1 ]; + opus_int sLTP_shp_buf_idx; + opus_int32 sLF_AR_shp_Q12; + opus_int32 sLF_MA_shp_Q12; + opus_int32 sHarmHP_Q2; + opus_int32 rand_seed; + opus_int lagPrev; +} silk_prefilter_state_FIX; + +/********************************/ +/* Encoder state FIX */ +/********************************/ +typedef struct { + silk_encoder_state sCmn; /* Common struct, shared with floating-point code */ + silk_shape_state_FIX sShape; /* Shape state */ + silk_prefilter_state_FIX sPrefilt; /* Prefilter State */ + + /* Buffer for find pitch and noise shape analysis */ + silk_DWORD_ALIGN opus_int16 x_buf[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ];/* Buffer for find pitch and noise shape analysis */ + opus_int LTPCorr_Q15; /* Normalized correlation from pitch lag estimator */ +} silk_encoder_state_FIX; + +/************************/ +/* Encoder control FIX */ +/************************/ +typedef struct { + /* Prediction and coding parameters */ + opus_int32 Gains_Q16[ MAX_NB_SUBFR ]; + silk_DWORD_ALIGN opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ]; + opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ]; + opus_int LTP_scale_Q14; + opus_int pitchL[ MAX_NB_SUBFR ]; + + /* Noise shaping parameters */ + /* Testing */ + silk_DWORD_ALIGN opus_int16 AR1_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ]; + silk_DWORD_ALIGN opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ]; + opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ]; /* Packs two int16 coefficients per int32 value */ + opus_int GainsPre_Q14[ MAX_NB_SUBFR ]; + opus_int HarmBoost_Q14[ MAX_NB_SUBFR ]; + opus_int Tilt_Q14[ MAX_NB_SUBFR ]; + opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ]; + opus_int Lambda_Q10; + opus_int input_quality_Q14; + opus_int coding_quality_Q14; + + /* measures */ + opus_int sparseness_Q8; + opus_int32 predGain_Q16; + opus_int LTPredCodGain_Q7; + opus_int32 ResNrg[ MAX_NB_SUBFR ]; /* Residual energy per subframe */ + opus_int ResNrgQ[ MAX_NB_SUBFR ]; /* Q domain for the residual energy > 0 */ + + /* Parameters for CBR mode */ + opus_int32 GainsUnq_Q16[ MAX_NB_SUBFR ]; + opus_int8 lastGainIndexPrev; +} silk_encoder_control_FIX; + +/************************/ +/* Encoder Super Struct */ +/************************/ +typedef struct { + silk_encoder_state_FIX state_Fxx[ ENCODER_NUM_CHANNELS ]; + stereo_enc_state sStereo; + opus_int32 nBitsExceeded; + opus_int nChannelsAPI; + opus_int nChannelsInternal; + opus_int nPrevChannelsInternal; + opus_int timeSinceSwitchAllowed_ms; + opus_int allowBandwidthSwitch; + opus_int prev_decode_only_middle; +} silk_encoder; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/opus-1.1/silk/fixed/vector_ops_FIX.c b/src/opus-1.1/silk/fixed/vector_ops_FIX.c new file mode 100644 index 00000000..509c8b35 --- /dev/null +++ b/src/opus-1.1/silk/fixed/vector_ops_FIX.c @@ -0,0 +1,96 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SigProc_FIX.h" + +/* Copy and multiply a vector by a constant */ +void silk_scale_copy_vector16( + opus_int16 *data_out, + const opus_int16 *data_in, + opus_int32 gain_Q16, /* I Gain in Q16 */ + const opus_int dataSize /* I Length */ +) +{ + opus_int i; + opus_int32 tmp32; + + for( i = 0; i < dataSize; i++ ) { + tmp32 = silk_SMULWB( gain_Q16, data_in[ i ] ); + data_out[ i ] = (opus_int16)silk_CHECK_FIT16( tmp32 ); + } +} + +/* Multiply a vector by a constant */ +void silk_scale_vector32_Q26_lshift_18( + opus_int32 *data1, /* I/O Q0/Q18 */ + opus_int32 gain_Q26, /* I Q26 */ + opus_int dataSize /* I length */ +) +{ + opus_int i; + + for( i = 0; i < dataSize; i++ ) { + data1[ i ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( silk_SMULL( data1[ i ], gain_Q26 ), 8 ) ); /* OUTPUT: Q18 */ + } +} + +/* sum = for(i=0;i6, memory access can be reduced by half. */ +opus_int32 silk_inner_prod_aligned( + const opus_int16 *const inVec1, /* I input vector 1 */ + const opus_int16 *const inVec2, /* I input vector 2 */ + const opus_int len /* I vector lengths */ +) +{ + opus_int i; + opus_int32 sum = 0; + for( i = 0; i < len; i++ ) { + sum = silk_SMLABB( sum, inVec1[ i ], inVec2[ i ] ); + } + return sum; +} + +opus_int64 silk_inner_prod16_aligned_64( + const opus_int16 *inVec1, /* I input vector 1 */ + const opus_int16 *inVec2, /* I input vector 2 */ + const opus_int len /* I vector lengths */ +) +{ + opus_int i; + opus_int64 sum = 0; + for( i = 0; i < len; i++ ) { + sum = silk_SMLALBB( sum, inVec1[ i ], inVec2[ i ] ); + } + return sum; +} diff --git a/src/opus-1.1/silk/fixed/warped_autocorrelation_FIX.c b/src/opus-1.1/silk/fixed/warped_autocorrelation_FIX.c new file mode 100644 index 00000000..a4a579b1 --- /dev/null +++ b/src/opus-1.1/silk/fixed/warped_autocorrelation_FIX.c @@ -0,0 +1,88 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main_FIX.h" + +#define QC 10 +#define QS 14 + +/* Autocorrelations for a warped frequency axis */ +void silk_warped_autocorrelation_FIX( + opus_int32 *corr, /* O Result [order + 1] */ + opus_int *scale, /* O Scaling of the correlation vector */ + const opus_int16 *input, /* I Input data to correlate */ + const opus_int warping_Q16, /* I Warping coefficient */ + const opus_int length, /* I Length of input */ + const opus_int order /* I Correlation order (even) */ +) +{ + opus_int n, i, lsh; + opus_int32 tmp1_QS, tmp2_QS; + opus_int32 state_QS[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 }; + opus_int64 corr_QC[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0 }; + + /* Order must be even */ + silk_assert( ( order & 1 ) == 0 ); + silk_assert( 2 * QS - QC >= 0 ); + + /* Loop over samples */ + for( n = 0; n < length; n++ ) { + tmp1_QS = silk_LSHIFT32( (opus_int32)input[ n ], QS ); + /* Loop over allpass sections */ + for( i = 0; i < order; i += 2 ) { + /* Output of allpass section */ + tmp2_QS = silk_SMLAWB( state_QS[ i ], state_QS[ i + 1 ] - tmp1_QS, warping_Q16 ); + state_QS[ i ] = tmp1_QS; + corr_QC[ i ] += silk_RSHIFT64( silk_SMULL( tmp1_QS, state_QS[ 0 ] ), 2 * QS - QC ); + /* Output of allpass section */ + tmp1_QS = silk_SMLAWB( state_QS[ i + 1 ], state_QS[ i + 2 ] - tmp2_QS, warping_Q16 ); + state_QS[ i + 1 ] = tmp2_QS; + corr_QC[ i + 1 ] += silk_RSHIFT64( silk_SMULL( tmp2_QS, state_QS[ 0 ] ), 2 * QS - QC ); + } + state_QS[ order ] = tmp1_QS; + corr_QC[ order ] += silk_RSHIFT64( silk_SMULL( tmp1_QS, state_QS[ 0 ] ), 2 * QS - QC ); + } + + lsh = silk_CLZ64( corr_QC[ 0 ] ) - 35; + lsh = silk_LIMIT( lsh, -12 - QC, 30 - QC ); + *scale = -( QC + lsh ); + silk_assert( *scale >= -30 && *scale <= 12 ); + if( lsh >= 0 ) { + for( i = 0; i < order + 1; i++ ) { + corr[ i ] = (opus_int32)silk_CHECK_FIT32( silk_LSHIFT64( corr_QC[ i ], lsh ) ); + } + } else { + for( i = 0; i < order + 1; i++ ) { + corr[ i ] = (opus_int32)silk_CHECK_FIT32( silk_RSHIFT64( corr_QC[ i ], -lsh ) ); + } + } + silk_assert( corr_QC[ 0 ] >= 0 ); /* If breaking, decrease QC*/ +} diff --git a/src/opus-1.1/silk/float/LPC_analysis_filter_FLP.c b/src/opus-1.1/silk/float/LPC_analysis_filter_FLP.c new file mode 100644 index 00000000..cae89a0a --- /dev/null +++ b/src/opus-1.1/silk/float/LPC_analysis_filter_FLP.c @@ -0,0 +1,249 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "main_FLP.h" + +/************************************************/ +/* LPC analysis filter */ +/* NB! State is kept internally and the */ +/* filter always starts with zero state */ +/* first Order output samples are set to zero */ +/************************************************/ + +/* 16th order LPC analysis filter, does not write first 16 samples */ +static OPUS_INLINE void silk_LPC_analysis_filter16_FLP( + silk_float r_LPC[], /* O LPC residual signal */ + const silk_float PredCoef[], /* I LPC coefficients */ + const silk_float s[], /* I Input signal */ + const opus_int length /* I Length of input signal */ +) +{ + opus_int ix; + silk_float LPC_pred; + const silk_float *s_ptr; + + for( ix = 16; ix < length; ix++ ) { + s_ptr = &s[ix - 1]; + + /* short-term prediction */ + LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] + + s_ptr[ -1 ] * PredCoef[ 1 ] + + s_ptr[ -2 ] * PredCoef[ 2 ] + + s_ptr[ -3 ] * PredCoef[ 3 ] + + s_ptr[ -4 ] * PredCoef[ 4 ] + + s_ptr[ -5 ] * PredCoef[ 5 ] + + s_ptr[ -6 ] * PredCoef[ 6 ] + + s_ptr[ -7 ] * PredCoef[ 7 ] + + s_ptr[ -8 ] * PredCoef[ 8 ] + + s_ptr[ -9 ] * PredCoef[ 9 ] + + s_ptr[ -10 ] * PredCoef[ 10 ] + + s_ptr[ -11 ] * PredCoef[ 11 ] + + s_ptr[ -12 ] * PredCoef[ 12 ] + + s_ptr[ -13 ] * PredCoef[ 13 ] + + s_ptr[ -14 ] * PredCoef[ 14 ] + + s_ptr[ -15 ] * PredCoef[ 15 ]; + + /* prediction error */ + r_LPC[ix] = s_ptr[ 1 ] - LPC_pred; + } +} + +/* 12th order LPC analysis filter, does not write first 12 samples */ +static OPUS_INLINE void silk_LPC_analysis_filter12_FLP( + silk_float r_LPC[], /* O LPC residual signal */ + const silk_float PredCoef[], /* I LPC coefficients */ + const silk_float s[], /* I Input signal */ + const opus_int length /* I Length of input signal */ +) +{ + opus_int ix; + silk_float LPC_pred; + const silk_float *s_ptr; + + for( ix = 12; ix < length; ix++ ) { + s_ptr = &s[ix - 1]; + + /* short-term prediction */ + LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] + + s_ptr[ -1 ] * PredCoef[ 1 ] + + s_ptr[ -2 ] * PredCoef[ 2 ] + + s_ptr[ -3 ] * PredCoef[ 3 ] + + s_ptr[ -4 ] * PredCoef[ 4 ] + + s_ptr[ -5 ] * PredCoef[ 5 ] + + s_ptr[ -6 ] * PredCoef[ 6 ] + + s_ptr[ -7 ] * PredCoef[ 7 ] + + s_ptr[ -8 ] * PredCoef[ 8 ] + + s_ptr[ -9 ] * PredCoef[ 9 ] + + s_ptr[ -10 ] * PredCoef[ 10 ] + + s_ptr[ -11 ] * PredCoef[ 11 ]; + + /* prediction error */ + r_LPC[ix] = s_ptr[ 1 ] - LPC_pred; + } +} + +/* 10th order LPC analysis filter, does not write first 10 samples */ +static OPUS_INLINE void silk_LPC_analysis_filter10_FLP( + silk_float r_LPC[], /* O LPC residual signal */ + const silk_float PredCoef[], /* I LPC coefficients */ + const silk_float s[], /* I Input signal */ + const opus_int length /* I Length of input signal */ +) +{ + opus_int ix; + silk_float LPC_pred; + const silk_float *s_ptr; + + for( ix = 10; ix < length; ix++ ) { + s_ptr = &s[ix - 1]; + + /* short-term prediction */ + LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] + + s_ptr[ -1 ] * PredCoef[ 1 ] + + s_ptr[ -2 ] * PredCoef[ 2 ] + + s_ptr[ -3 ] * PredCoef[ 3 ] + + s_ptr[ -4 ] * PredCoef[ 4 ] + + s_ptr[ -5 ] * PredCoef[ 5 ] + + s_ptr[ -6 ] * PredCoef[ 6 ] + + s_ptr[ -7 ] * PredCoef[ 7 ] + + s_ptr[ -8 ] * PredCoef[ 8 ] + + s_ptr[ -9 ] * PredCoef[ 9 ]; + + /* prediction error */ + r_LPC[ix] = s_ptr[ 1 ] - LPC_pred; + } +} + +/* 8th order LPC analysis filter, does not write first 8 samples */ +static OPUS_INLINE void silk_LPC_analysis_filter8_FLP( + silk_float r_LPC[], /* O LPC residual signal */ + const silk_float PredCoef[], /* I LPC coefficients */ + const silk_float s[], /* I Input signal */ + const opus_int length /* I Length of input signal */ +) +{ + opus_int ix; + silk_float LPC_pred; + const silk_float *s_ptr; + + for( ix = 8; ix < length; ix++ ) { + s_ptr = &s[ix - 1]; + + /* short-term prediction */ + LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] + + s_ptr[ -1 ] * PredCoef[ 1 ] + + s_ptr[ -2 ] * PredCoef[ 2 ] + + s_ptr[ -3 ] * PredCoef[ 3 ] + + s_ptr[ -4 ] * PredCoef[ 4 ] + + s_ptr[ -5 ] * PredCoef[ 5 ] + + s_ptr[ -6 ] * PredCoef[ 6 ] + + s_ptr[ -7 ] * PredCoef[ 7 ]; + + /* prediction error */ + r_LPC[ix] = s_ptr[ 1 ] - LPC_pred; + } +} + +/* 6th order LPC analysis filter, does not write first 6 samples */ +static OPUS_INLINE void silk_LPC_analysis_filter6_FLP( + silk_float r_LPC[], /* O LPC residual signal */ + const silk_float PredCoef[], /* I LPC coefficients */ + const silk_float s[], /* I Input signal */ + const opus_int length /* I Length of input signal */ +) +{ + opus_int ix; + silk_float LPC_pred; + const silk_float *s_ptr; + + for( ix = 6; ix < length; ix++ ) { + s_ptr = &s[ix - 1]; + + /* short-term prediction */ + LPC_pred = s_ptr[ 0 ] * PredCoef[ 0 ] + + s_ptr[ -1 ] * PredCoef[ 1 ] + + s_ptr[ -2 ] * PredCoef[ 2 ] + + s_ptr[ -3 ] * PredCoef[ 3 ] + + s_ptr[ -4 ] * PredCoef[ 4 ] + + s_ptr[ -5 ] * PredCoef[ 5 ]; + + /* prediction error */ + r_LPC[ix] = s_ptr[ 1 ] - LPC_pred; + } +} + +/************************************************/ +/* LPC analysis filter */ +/* NB! State is kept internally and the */ +/* filter always starts with zero state */ +/* first Order output samples are set to zero */ +/************************************************/ +void silk_LPC_analysis_filter_FLP( + silk_float r_LPC[], /* O LPC residual signal */ + const silk_float PredCoef[], /* I LPC coefficients */ + const silk_float s[], /* I Input signal */ + const opus_int length, /* I Length of input signal */ + const opus_int Order /* I LPC order */ +) +{ + silk_assert( Order <= length ); + + switch( Order ) { + case 6: + silk_LPC_analysis_filter6_FLP( r_LPC, PredCoef, s, length ); + break; + + case 8: + silk_LPC_analysis_filter8_FLP( r_LPC, PredCoef, s, length ); + break; + + case 10: + silk_LPC_analysis_filter10_FLP( r_LPC, PredCoef, s, length ); + break; + + case 12: + silk_LPC_analysis_filter12_FLP( r_LPC, PredCoef, s, length ); + break; + + case 16: + silk_LPC_analysis_filter16_FLP( r_LPC, PredCoef, s, length ); + break; + + default: + silk_assert( 0 ); + break; + } + + /* Set first Order output samples to zero */ + silk_memset( r_LPC, 0, Order * sizeof( silk_float ) ); +} + diff --git a/src/opus-1.1/silk/float/LPC_inv_pred_gain_FLP.c b/src/opus-1.1/silk/float/LPC_inv_pred_gain_FLP.c new file mode 100644 index 00000000..25178bac --- /dev/null +++ b/src/opus-1.1/silk/float/LPC_inv_pred_gain_FLP.c @@ -0,0 +1,76 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SigProc_FIX.h" +#include "SigProc_FLP.h" + +#define RC_THRESHOLD 0.9999f + +/* compute inverse of LPC prediction gain, and */ +/* test if LPC coefficients are stable (all poles within unit circle) */ +/* this code is based on silk_a2k_FLP() */ +silk_float silk_LPC_inverse_pred_gain_FLP( /* O return inverse prediction gain, energy domain */ + const silk_float *A, /* I prediction coefficients [order] */ + opus_int32 order /* I prediction order */ +) +{ + opus_int k, n; + double invGain, rc, rc_mult1, rc_mult2; + silk_float Atmp[ 2 ][ SILK_MAX_ORDER_LPC ]; + silk_float *Aold, *Anew; + + Anew = Atmp[ order & 1 ]; + silk_memcpy( Anew, A, order * sizeof(silk_float) ); + + invGain = 1.0; + for( k = order - 1; k > 0; k-- ) { + rc = -Anew[ k ]; + if( rc > RC_THRESHOLD || rc < -RC_THRESHOLD ) { + return 0.0f; + } + rc_mult1 = 1.0f - rc * rc; + rc_mult2 = 1.0f / rc_mult1; + invGain *= rc_mult1; + /* swap pointers */ + Aold = Anew; + Anew = Atmp[ k & 1 ]; + for( n = 0; n < k; n++ ) { + Anew[ n ] = (silk_float)( ( Aold[ n ] - Aold[ k - n - 1 ] * rc ) * rc_mult2 ); + } + } + rc = -Anew[ 0 ]; + if( rc > RC_THRESHOLD || rc < -RC_THRESHOLD ) { + return 0.0f; + } + rc_mult1 = 1.0f - rc * rc; + invGain *= rc_mult1; + return (silk_float)invGain; +} diff --git a/src/opus-1.1/silk/float/LTP_analysis_filter_FLP.c b/src/opus-1.1/silk/float/LTP_analysis_filter_FLP.c new file mode 100644 index 00000000..849b7c1c --- /dev/null +++ b/src/opus-1.1/silk/float/LTP_analysis_filter_FLP.c @@ -0,0 +1,75 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main_FLP.h" + +void silk_LTP_analysis_filter_FLP( + silk_float *LTP_res, /* O LTP res MAX_NB_SUBFR*(pre_lgth+subfr_lngth) */ + const silk_float *x, /* I Input signal, with preceding samples */ + const silk_float B[ LTP_ORDER * MAX_NB_SUBFR ], /* I LTP coefficients for each subframe */ + const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ + const silk_float invGains[ MAX_NB_SUBFR ], /* I Inverse quantization gains */ + const opus_int subfr_length, /* I Length of each subframe */ + const opus_int nb_subfr, /* I number of subframes */ + const opus_int pre_length /* I Preceding samples for each subframe */ +) +{ + const silk_float *x_ptr, *x_lag_ptr; + silk_float Btmp[ LTP_ORDER ]; + silk_float *LTP_res_ptr; + silk_float inv_gain; + opus_int k, i, j; + + x_ptr = x; + LTP_res_ptr = LTP_res; + for( k = 0; k < nb_subfr; k++ ) { + x_lag_ptr = x_ptr - pitchL[ k ]; + inv_gain = invGains[ k ]; + for( i = 0; i < LTP_ORDER; i++ ) { + Btmp[ i ] = B[ k * LTP_ORDER + i ]; + } + + /* LTP analysis FIR filter */ + for( i = 0; i < subfr_length + pre_length; i++ ) { + LTP_res_ptr[ i ] = x_ptr[ i ]; + /* Subtract long-term prediction */ + for( j = 0; j < LTP_ORDER; j++ ) { + LTP_res_ptr[ i ] -= Btmp[ j ] * x_lag_ptr[ LTP_ORDER / 2 - j ]; + } + LTP_res_ptr[ i ] *= inv_gain; + x_lag_ptr++; + } + + /* Update pointers */ + LTP_res_ptr += subfr_length + pre_length; + x_ptr += subfr_length; + } +} diff --git a/src/opus-1.1/silk/float/LTP_scale_ctrl_FLP.c b/src/opus-1.1/silk/float/LTP_scale_ctrl_FLP.c new file mode 100644 index 00000000..8dbe29d0 --- /dev/null +++ b/src/opus-1.1/silk/float/LTP_scale_ctrl_FLP.c @@ -0,0 +1,52 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main_FLP.h" + +void silk_LTP_scale_ctrl_FLP( + silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ + silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ + opus_int condCoding /* I The type of conditional coding to use */ +) +{ + opus_int round_loss; + + if( condCoding == CODE_INDEPENDENTLY ) { + /* Only scale if first frame in packet */ + round_loss = psEnc->sCmn.PacketLoss_perc + psEnc->sCmn.nFramesPerPacket; + psEnc->sCmn.indices.LTP_scaleIndex = (opus_int8)silk_LIMIT( round_loss * psEncCtrl->LTPredCodGain * 0.1f, 0.0f, 2.0f ); + } else { + /* Default is minimum scaling */ + psEnc->sCmn.indices.LTP_scaleIndex = 0; + } + + psEncCtrl->LTP_scale = (silk_float)silk_LTPScales_table_Q14[ psEnc->sCmn.indices.LTP_scaleIndex ] / 16384.0f; +} diff --git a/src/opus-1.1/silk/float/SigProc_FLP.h b/src/opus-1.1/silk/float/SigProc_FLP.h new file mode 100644 index 00000000..f0cb3733 --- /dev/null +++ b/src/opus-1.1/silk/float/SigProc_FLP.h @@ -0,0 +1,204 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifndef SILK_SIGPROC_FLP_H +#define SILK_SIGPROC_FLP_H + +#include "SigProc_FIX.h" +#include "float_cast.h" +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************************************************/ +/* SIGNAL PROCESSING FUNCTIONS */ +/********************************************************************/ + +/* Chirp (bw expand) LP AR filter */ +void silk_bwexpander_FLP( + silk_float *ar, /* I/O AR filter to be expanded (without leading 1) */ + const opus_int d, /* I length of ar */ + const silk_float chirp /* I chirp factor (typically in range (0..1) ) */ +); + +/* compute inverse of LPC prediction gain, and */ +/* test if LPC coefficients are stable (all poles within unit circle) */ +/* this code is based on silk_FLP_a2k() */ +silk_float silk_LPC_inverse_pred_gain_FLP( /* O return inverse prediction gain, energy domain */ + const silk_float *A, /* I prediction coefficients [order] */ + opus_int32 order /* I prediction order */ +); + +silk_float silk_schur_FLP( /* O returns residual energy */ + silk_float refl_coef[], /* O reflection coefficients (length order) */ + const silk_float auto_corr[], /* I autocorrelation sequence (length order+1) */ + opus_int order /* I order */ +); + +void silk_k2a_FLP( + silk_float *A, /* O prediction coefficients [order] */ + const silk_float *rc, /* I reflection coefficients [order] */ + opus_int32 order /* I prediction order */ +); + +/* Solve the normal equations using the Levinson-Durbin recursion */ +silk_float silk_levinsondurbin_FLP( /* O prediction error energy */ + silk_float A[], /* O prediction coefficients [order] */ + const silk_float corr[], /* I input auto-correlations [order + 1] */ + const opus_int order /* I prediction order */ +); + +/* compute autocorrelation */ +void silk_autocorrelation_FLP( + silk_float *results, /* O result (length correlationCount) */ + const silk_float *inputData, /* I input data to correlate */ + opus_int inputDataSize, /* I length of input */ + opus_int correlationCount /* I number of correlation taps to compute */ +); + +opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced, 1 unvoiced */ + const silk_float *frame, /* I Signal of length PE_FRAME_LENGTH_MS*Fs_kHz */ + opus_int *pitch_out, /* O Pitch lag values [nb_subfr] */ + opus_int16 *lagIndex, /* O Lag Index */ + opus_int8 *contourIndex, /* O Pitch contour Index */ + silk_float *LTPCorr, /* I/O Normalized correlation; input: value from previous frame */ + opus_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */ + const silk_float search_thres1, /* I First stage threshold for lag candidates 0 - 1 */ + const silk_float search_thres2, /* I Final threshold for lag candidates 0 - 1 */ + const opus_int Fs_kHz, /* I sample frequency (kHz) */ + const opus_int complexity, /* I Complexity setting, 0-2, where 2 is highest */ + const opus_int nb_subfr, /* I Number of 5 ms subframes */ + int arch /* I Run-time architecture */ +); + +void silk_insertion_sort_decreasing_FLP( + silk_float *a, /* I/O Unsorted / Sorted vector */ + opus_int *idx, /* O Index vector for the sorted elements */ + const opus_int L, /* I Vector length */ + const opus_int K /* I Number of correctly sorted positions */ +); + +/* Compute reflection coefficients from input signal */ +silk_float silk_burg_modified_FLP( /* O returns residual energy */ + silk_float A[], /* O prediction coefficients (length order) */ + const silk_float x[], /* I input signal, length: nb_subfr*(D+L_sub) */ + const silk_float minInvGain, /* I minimum inverse prediction gain */ + const opus_int subfr_length, /* I input signal subframe length (incl. D preceding samples) */ + const opus_int nb_subfr, /* I number of subframes stacked in x */ + const opus_int D /* I order */ +); + +/* multiply a vector by a constant */ +void silk_scale_vector_FLP( + silk_float *data1, + silk_float gain, + opus_int dataSize +); + +/* copy and multiply a vector by a constant */ +void silk_scale_copy_vector_FLP( + silk_float *data_out, + const silk_float *data_in, + silk_float gain, + opus_int dataSize +); + +/* inner product of two silk_float arrays, with result as double */ +double silk_inner_product_FLP( + const silk_float *data1, + const silk_float *data2, + opus_int dataSize +); + +/* sum of squares of a silk_float array, with result as double */ +double silk_energy_FLP( + const silk_float *data, + opus_int dataSize +); + +/********************************************************************/ +/* MACROS */ +/********************************************************************/ + +#define PI (3.1415926536f) + +#define silk_min_float( a, b ) (((a) < (b)) ? (a) : (b)) +#define silk_max_float( a, b ) (((a) > (b)) ? (a) : (b)) +#define silk_abs_float( a ) ((silk_float)fabs(a)) + +/* sigmoid function */ +static OPUS_INLINE silk_float silk_sigmoid( silk_float x ) +{ + return (silk_float)(1.0 / (1.0 + exp(-x))); +} + +/* floating-point to integer conversion (rounding) */ +static OPUS_INLINE opus_int32 silk_float2int( silk_float x ) +{ + return (opus_int32)float2int( x ); +} + +/* floating-point to integer conversion (rounding) */ +static OPUS_INLINE void silk_float2short_array( + opus_int16 *out, + const silk_float *in, + opus_int32 length +) +{ + opus_int32 k; + for( k = length - 1; k >= 0; k-- ) { + out[k] = silk_SAT16( (opus_int32)float2int( in[k] ) ); + } +} + +/* integer to floating-point conversion */ +static OPUS_INLINE void silk_short2float_array( + silk_float *out, + const opus_int16 *in, + opus_int32 length +) +{ + opus_int32 k; + for( k = length - 1; k >= 0; k-- ) { + out[k] = (silk_float)in[k]; + } +} + +/* using log2() helps the fixed-point conversion */ +static OPUS_INLINE silk_float silk_log2( double x ) +{ + return ( silk_float )( 3.32192809488736 * log10( x ) ); +} + +#ifdef __cplusplus +} +#endif + +#endif /* SILK_SIGPROC_FLP_H */ diff --git a/src/opus-1.1/silk/float/apply_sine_window_FLP.c b/src/opus-1.1/silk/float/apply_sine_window_FLP.c new file mode 100644 index 00000000..6aae57c0 --- /dev/null +++ b/src/opus-1.1/silk/float/apply_sine_window_FLP.c @@ -0,0 +1,81 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main_FLP.h" + +/* Apply sine window to signal vector */ +/* Window types: */ +/* 1 -> sine window from 0 to pi/2 */ +/* 2 -> sine window from pi/2 to pi */ +void silk_apply_sine_window_FLP( + silk_float px_win[], /* O Pointer to windowed signal */ + const silk_float px[], /* I Pointer to input signal */ + const opus_int win_type, /* I Selects a window type */ + const opus_int length /* I Window length, multiple of 4 */ +) +{ + opus_int k; + silk_float freq, c, S0, S1; + + silk_assert( win_type == 1 || win_type == 2 ); + + /* Length must be multiple of 4 */ + silk_assert( ( length & 3 ) == 0 ); + + freq = PI / ( length + 1 ); + + /* Approximation of 2 * cos(f) */ + c = 2.0f - freq * freq; + + /* Initialize state */ + if( win_type < 2 ) { + /* Start from 0 */ + S0 = 0.0f; + /* Approximation of sin(f) */ + S1 = freq; + } else { + /* Start from 1 */ + S0 = 1.0f; + /* Approximation of cos(f) */ + S1 = 0.5f * c; + } + + /* Uses the recursive equation: sin(n*f) = 2 * cos(f) * sin((n-1)*f) - sin((n-2)*f) */ + /* 4 samples at a time */ + for( k = 0; k < length; k += 4 ) { + px_win[ k + 0 ] = px[ k + 0 ] * 0.5f * ( S0 + S1 ); + px_win[ k + 1 ] = px[ k + 1 ] * S1; + S0 = c * S1 - S0; + px_win[ k + 2 ] = px[ k + 2 ] * 0.5f * ( S1 + S0 ); + px_win[ k + 3 ] = px[ k + 3 ] * S0; + S1 = c * S0 - S1; + } +} diff --git a/src/opus-1.1/silk/float/autocorrelation_FLP.c b/src/opus-1.1/silk/float/autocorrelation_FLP.c new file mode 100644 index 00000000..8b8a9e65 --- /dev/null +++ b/src/opus-1.1/silk/float/autocorrelation_FLP.c @@ -0,0 +1,52 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "typedef.h" +#include "SigProc_FLP.h" + +/* compute autocorrelation */ +void silk_autocorrelation_FLP( + silk_float *results, /* O result (length correlationCount) */ + const silk_float *inputData, /* I input data to correlate */ + opus_int inputDataSize, /* I length of input */ + opus_int correlationCount /* I number of correlation taps to compute */ +) +{ + opus_int i; + + if( correlationCount > inputDataSize ) { + correlationCount = inputDataSize; + } + + for( i = 0; i < correlationCount; i++ ) { + results[ i ] = (silk_float)silk_inner_product_FLP( inputData, inputData + i, inputDataSize - i ); + } +} diff --git a/src/opus-1.1/silk/float/burg_modified_FLP.c b/src/opus-1.1/silk/float/burg_modified_FLP.c new file mode 100644 index 00000000..ea5dc25a --- /dev/null +++ b/src/opus-1.1/silk/float/burg_modified_FLP.c @@ -0,0 +1,186 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SigProc_FLP.h" +#include "tuning_parameters.h" +#include "define.h" + +#define MAX_FRAME_SIZE 384 /* subfr_length * nb_subfr = ( 0.005 * 16000 + 16 ) * 4 = 384*/ + +/* Compute reflection coefficients from input signal */ +silk_float silk_burg_modified_FLP( /* O returns residual energy */ + silk_float A[], /* O prediction coefficients (length order) */ + const silk_float x[], /* I input signal, length: nb_subfr*(D+L_sub) */ + const silk_float minInvGain, /* I minimum inverse prediction gain */ + const opus_int subfr_length, /* I input signal subframe length (incl. D preceding samples) */ + const opus_int nb_subfr, /* I number of subframes stacked in x */ + const opus_int D /* I order */ +) +{ + opus_int k, n, s, reached_max_gain; + double C0, invGain, num, nrg_f, nrg_b, rc, Atmp, tmp1, tmp2; + const silk_float *x_ptr; + double C_first_row[ SILK_MAX_ORDER_LPC ], C_last_row[ SILK_MAX_ORDER_LPC ]; + double CAf[ SILK_MAX_ORDER_LPC + 1 ], CAb[ SILK_MAX_ORDER_LPC + 1 ]; + double Af[ SILK_MAX_ORDER_LPC ]; + + silk_assert( subfr_length * nb_subfr <= MAX_FRAME_SIZE ); + + /* Compute autocorrelations, added over subframes */ + C0 = silk_energy_FLP( x, nb_subfr * subfr_length ); + silk_memset( C_first_row, 0, SILK_MAX_ORDER_LPC * sizeof( double ) ); + for( s = 0; s < nb_subfr; s++ ) { + x_ptr = x + s * subfr_length; + for( n = 1; n < D + 1; n++ ) { + C_first_row[ n - 1 ] += silk_inner_product_FLP( x_ptr, x_ptr + n, subfr_length - n ); + } + } + silk_memcpy( C_last_row, C_first_row, SILK_MAX_ORDER_LPC * sizeof( double ) ); + + /* Initialize */ + CAb[ 0 ] = CAf[ 0 ] = C0 + FIND_LPC_COND_FAC * C0 + 1e-9f; + invGain = 1.0f; + reached_max_gain = 0; + for( n = 0; n < D; n++ ) { + /* Update first row of correlation matrix (without first element) */ + /* Update last row of correlation matrix (without last element, stored in reversed order) */ + /* Update C * Af */ + /* Update C * flipud(Af) (stored in reversed order) */ + for( s = 0; s < nb_subfr; s++ ) { + x_ptr = x + s * subfr_length; + tmp1 = x_ptr[ n ]; + tmp2 = x_ptr[ subfr_length - n - 1 ]; + for( k = 0; k < n; k++ ) { + C_first_row[ k ] -= x_ptr[ n ] * x_ptr[ n - k - 1 ]; + C_last_row[ k ] -= x_ptr[ subfr_length - n - 1 ] * x_ptr[ subfr_length - n + k ]; + Atmp = Af[ k ]; + tmp1 += x_ptr[ n - k - 1 ] * Atmp; + tmp2 += x_ptr[ subfr_length - n + k ] * Atmp; + } + for( k = 0; k <= n; k++ ) { + CAf[ k ] -= tmp1 * x_ptr[ n - k ]; + CAb[ k ] -= tmp2 * x_ptr[ subfr_length - n + k - 1 ]; + } + } + tmp1 = C_first_row[ n ]; + tmp2 = C_last_row[ n ]; + for( k = 0; k < n; k++ ) { + Atmp = Af[ k ]; + tmp1 += C_last_row[ n - k - 1 ] * Atmp; + tmp2 += C_first_row[ n - k - 1 ] * Atmp; + } + CAf[ n + 1 ] = tmp1; + CAb[ n + 1 ] = tmp2; + + /* Calculate nominator and denominator for the next order reflection (parcor) coefficient */ + num = CAb[ n + 1 ]; + nrg_b = CAb[ 0 ]; + nrg_f = CAf[ 0 ]; + for( k = 0; k < n; k++ ) { + Atmp = Af[ k ]; + num += CAb[ n - k ] * Atmp; + nrg_b += CAb[ k + 1 ] * Atmp; + nrg_f += CAf[ k + 1 ] * Atmp; + } + silk_assert( nrg_f > 0.0 ); + silk_assert( nrg_b > 0.0 ); + + /* Calculate the next order reflection (parcor) coefficient */ + rc = -2.0 * num / ( nrg_f + nrg_b ); + silk_assert( rc > -1.0 && rc < 1.0 ); + + /* Update inverse prediction gain */ + tmp1 = invGain * ( 1.0 - rc * rc ); + if( tmp1 <= minInvGain ) { + /* Max prediction gain exceeded; set reflection coefficient such that max prediction gain is exactly hit */ + rc = sqrt( 1.0 - minInvGain / invGain ); + if( num > 0 ) { + /* Ensure adjusted reflection coefficients has the original sign */ + rc = -rc; + } + invGain = minInvGain; + reached_max_gain = 1; + } else { + invGain = tmp1; + } + + /* Update the AR coefficients */ + for( k = 0; k < (n + 1) >> 1; k++ ) { + tmp1 = Af[ k ]; + tmp2 = Af[ n - k - 1 ]; + Af[ k ] = tmp1 + rc * tmp2; + Af[ n - k - 1 ] = tmp2 + rc * tmp1; + } + Af[ n ] = rc; + + if( reached_max_gain ) { + /* Reached max prediction gain; set remaining coefficients to zero and exit loop */ + for( k = n + 1; k < D; k++ ) { + Af[ k ] = 0.0; + } + break; + } + + /* Update C * Af and C * Ab */ + for( k = 0; k <= n + 1; k++ ) { + tmp1 = CAf[ k ]; + CAf[ k ] += rc * CAb[ n - k + 1 ]; + CAb[ n - k + 1 ] += rc * tmp1; + } + } + + if( reached_max_gain ) { + /* Convert to silk_float */ + for( k = 0; k < D; k++ ) { + A[ k ] = (silk_float)( -Af[ k ] ); + } + /* Subtract energy of preceding samples from C0 */ + for( s = 0; s < nb_subfr; s++ ) { + C0 -= silk_energy_FLP( x + s * subfr_length, D ); + } + /* Approximate residual energy */ + nrg_f = C0 * invGain; + } else { + /* Compute residual energy and store coefficients as silk_float */ + nrg_f = CAf[ 0 ]; + tmp1 = 1.0; + for( k = 0; k < D; k++ ) { + Atmp = Af[ k ]; + nrg_f += CAf[ k + 1 ] * Atmp; + tmp1 += Atmp * Atmp; + A[ k ] = (silk_float)(-Atmp); + } + nrg_f -= FIND_LPC_COND_FAC * C0 * tmp1; + } + + /* Return residual energy */ + return (silk_float)nrg_f; +} diff --git a/src/opus-1.1/silk/float/bwexpander_FLP.c b/src/opus-1.1/silk/float/bwexpander_FLP.c new file mode 100644 index 00000000..d55a4d79 --- /dev/null +++ b/src/opus-1.1/silk/float/bwexpander_FLP.c @@ -0,0 +1,49 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SigProc_FLP.h" + +/* Chirp (bw expand) LP AR filter */ +void silk_bwexpander_FLP( + silk_float *ar, /* I/O AR filter to be expanded (without leading 1) */ + const opus_int d, /* I length of ar */ + const silk_float chirp /* I chirp factor (typically in range (0..1) ) */ +) +{ + opus_int i; + silk_float cfac = chirp; + + for( i = 0; i < d - 1; i++ ) { + ar[ i ] *= cfac; + cfac *= chirp; + } + ar[ d - 1 ] *= cfac; +} diff --git a/src/opus-1.1/silk/float/corrMatrix_FLP.c b/src/opus-1.1/silk/float/corrMatrix_FLP.c new file mode 100644 index 00000000..eae6a1cf --- /dev/null +++ b/src/opus-1.1/silk/float/corrMatrix_FLP.c @@ -0,0 +1,93 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/********************************************************************** + * Correlation matrix computations for LS estimate. + **********************************************************************/ + +#include "main_FLP.h" + +/* Calculates correlation vector X'*t */ +void silk_corrVector_FLP( + const silk_float *x, /* I x vector [L+order-1] used to create X */ + const silk_float *t, /* I Target vector [L] */ + const opus_int L, /* I Length of vecors */ + const opus_int Order, /* I Max lag for correlation */ + silk_float *Xt /* O X'*t correlation vector [order] */ +) +{ + opus_int lag; + const silk_float *ptr1; + + ptr1 = &x[ Order - 1 ]; /* Points to first sample of column 0 of X: X[:,0] */ + for( lag = 0; lag < Order; lag++ ) { + /* Calculate X[:,lag]'*t */ + Xt[ lag ] = (silk_float)silk_inner_product_FLP( ptr1, t, L ); + ptr1--; /* Next column of X */ + } +} + +/* Calculates correlation matrix X'*X */ +void silk_corrMatrix_FLP( + const silk_float *x, /* I x vector [ L+order-1 ] used to create X */ + const opus_int L, /* I Length of vectors */ + const opus_int Order, /* I Max lag for correlation */ + silk_float *XX /* O X'*X correlation matrix [order x order] */ +) +{ + opus_int j, lag; + double energy; + const silk_float *ptr1, *ptr2; + + ptr1 = &x[ Order - 1 ]; /* First sample of column 0 of X */ + energy = silk_energy_FLP( ptr1, L ); /* X[:,0]'*X[:,0] */ + matrix_ptr( XX, 0, 0, Order ) = ( silk_float )energy; + for( j = 1; j < Order; j++ ) { + /* Calculate X[:,j]'*X[:,j] */ + energy += ptr1[ -j ] * ptr1[ -j ] - ptr1[ L - j ] * ptr1[ L - j ]; + matrix_ptr( XX, j, j, Order ) = ( silk_float )energy; + } + + ptr2 = &x[ Order - 2 ]; /* First sample of column 1 of X */ + for( lag = 1; lag < Order; lag++ ) { + /* Calculate X[:,0]'*X[:,lag] */ + energy = silk_inner_product_FLP( ptr1, ptr2, L ); + matrix_ptr( XX, lag, 0, Order ) = ( silk_float )energy; + matrix_ptr( XX, 0, lag, Order ) = ( silk_float )energy; + /* Calculate X[:,j]'*X[:,j + lag] */ + for( j = 1; j < ( Order - lag ); j++ ) { + energy += ptr1[ -j ] * ptr2[ -j ] - ptr1[ L - j ] * ptr2[ L - j ]; + matrix_ptr( XX, lag + j, j, Order ) = ( silk_float )energy; + matrix_ptr( XX, j, lag + j, Order ) = ( silk_float )energy; + } + ptr2--; /* Next column of X */ + } +} diff --git a/src/opus-1.1/silk/float/encode_frame_FLP.c b/src/opus-1.1/silk/float/encode_frame_FLP.c new file mode 100644 index 00000000..d54e2686 --- /dev/null +++ b/src/opus-1.1/silk/float/encode_frame_FLP.c @@ -0,0 +1,372 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main_FLP.h" +#include "tuning_parameters.h" + +/* Low Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode with lower bitrate */ +static OPUS_INLINE void silk_LBRR_encode_FLP( + silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ + silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ + const silk_float xfw[], /* I Input signal */ + opus_int condCoding /* I The type of conditional coding used so far for this frame */ +); + +void silk_encode_do_VAD_FLP( + silk_encoder_state_FLP *psEnc /* I/O Encoder state FLP */ +) +{ + /****************************/ + /* Voice Activity Detection */ + /****************************/ + silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf + 1 ); + + /**************************************************/ + /* Convert speech activity into VAD and DTX flags */ + /**************************************************/ + if( psEnc->sCmn.speech_activity_Q8 < SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ) ) { + psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY; + psEnc->sCmn.noSpeechCounter++; + if( psEnc->sCmn.noSpeechCounter < NB_SPEECH_FRAMES_BEFORE_DTX ) { + psEnc->sCmn.inDTX = 0; + } else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) { + psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX; + psEnc->sCmn.inDTX = 0; + } + psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 0; + } else { + psEnc->sCmn.noSpeechCounter = 0; + psEnc->sCmn.inDTX = 0; + psEnc->sCmn.indices.signalType = TYPE_UNVOICED; + psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 1; + } +} + +/****************/ +/* Encode frame */ +/****************/ +opus_int silk_encode_frame_FLP( + silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ + opus_int32 *pnBytesOut, /* O Number of payload bytes; */ + ec_enc *psRangeEnc, /* I/O compressor data structure */ + opus_int condCoding, /* I The type of conditional coding to use */ + opus_int maxBits, /* I If > 0: maximum number of output bits */ + opus_int useCBR /* I Flag to force constant-bitrate operation */ +) +{ + silk_encoder_control_FLP sEncCtrl; + opus_int i, iter, maxIter, found_upper, found_lower, ret = 0; + silk_float *x_frame, *res_pitch_frame; + silk_float xfw[ MAX_FRAME_LENGTH ]; + silk_float res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ]; + ec_enc sRangeEnc_copy, sRangeEnc_copy2; + silk_nsq_state sNSQ_copy, sNSQ_copy2; + opus_int32 seed_copy, nBits, nBits_lower, nBits_upper, gainMult_lower, gainMult_upper; + opus_int32 gainsID, gainsID_lower, gainsID_upper; + opus_int16 gainMult_Q8; + opus_int16 ec_prevLagIndex_copy; + opus_int ec_prevSignalType_copy; + opus_int8 LastGainIndex_copy2; + opus_int32 pGains_Q16[ MAX_NB_SUBFR ]; + opus_uint8 ec_buf_copy[ 1275 ]; + + /* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */ + LastGainIndex_copy2 = nBits_lower = nBits_upper = gainMult_lower = gainMult_upper = 0; + + psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3; + + /**************************************************************/ + /* Set up Input Pointers, and insert frame in input buffer */ + /**************************************************************/ + /* pointers aligned with start of frame to encode */ + x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length; /* start of frame to encode */ + res_pitch_frame = res_pitch + psEnc->sCmn.ltp_mem_length; /* start of pitch LPC residual frame */ + + /***************************************/ + /* Ensure smooth bandwidth transitions */ + /***************************************/ + silk_LP_variable_cutoff( &psEnc->sCmn.sLP, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length ); + + /*******************************************/ + /* Copy new frame to front of input buffer */ + /*******************************************/ + silk_short2float_array( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length ); + + /* Add tiny signal to avoid high CPU load from denormalized floating point numbers */ + for( i = 0; i < 8; i++ ) { + x_frame[ LA_SHAPE_MS * psEnc->sCmn.fs_kHz + i * ( psEnc->sCmn.frame_length >> 3 ) ] += ( 1 - ( i & 2 ) ) * 1e-6f; + } + + if( !psEnc->sCmn.prefillFlag ) { + /*****************************************/ + /* Find pitch lags, initial LPC analysis */ + /*****************************************/ + silk_find_pitch_lags_FLP( psEnc, &sEncCtrl, res_pitch, x_frame, psEnc->sCmn.arch ); + + /************************/ + /* Noise shape analysis */ + /************************/ + silk_noise_shape_analysis_FLP( psEnc, &sEncCtrl, res_pitch_frame, x_frame ); + + /***************************************************/ + /* Find linear prediction coefficients (LPC + LTP) */ + /***************************************************/ + silk_find_pred_coefs_FLP( psEnc, &sEncCtrl, res_pitch, x_frame, condCoding ); + + /****************************************/ + /* Process gains */ + /****************************************/ + silk_process_gains_FLP( psEnc, &sEncCtrl, condCoding ); + + /*****************************************/ + /* Prefiltering for noise shaper */ + /*****************************************/ + silk_prefilter_FLP( psEnc, &sEncCtrl, xfw, x_frame ); + + /****************************************/ + /* Low Bitrate Redundant Encoding */ + /****************************************/ + silk_LBRR_encode_FLP( psEnc, &sEncCtrl, xfw, condCoding ); + + /* Loop over quantizer and entroy coding to control bitrate */ + maxIter = 6; + gainMult_Q8 = SILK_FIX_CONST( 1, 8 ); + found_lower = 0; + found_upper = 0; + gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr ); + gainsID_lower = -1; + gainsID_upper = -1; + /* Copy part of the input state */ + silk_memcpy( &sRangeEnc_copy, psRangeEnc, sizeof( ec_enc ) ); + silk_memcpy( &sNSQ_copy, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); + seed_copy = psEnc->sCmn.indices.Seed; + ec_prevLagIndex_copy = psEnc->sCmn.ec_prevLagIndex; + ec_prevSignalType_copy = psEnc->sCmn.ec_prevSignalType; + for( iter = 0; ; iter++ ) { + if( gainsID == gainsID_lower ) { + nBits = nBits_lower; + } else if( gainsID == gainsID_upper ) { + nBits = nBits_upper; + } else { + /* Restore part of the input state */ + if( iter > 0 ) { + silk_memcpy( psRangeEnc, &sRangeEnc_copy, sizeof( ec_enc ) ); + silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy, sizeof( silk_nsq_state ) ); + psEnc->sCmn.indices.Seed = seed_copy; + psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy; + psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy; + } + + /*****************************************/ + /* Noise shaping quantization */ + /*****************************************/ + silk_NSQ_wrapper_FLP( psEnc, &sEncCtrl, &psEnc->sCmn.indices, &psEnc->sCmn.sNSQ, psEnc->sCmn.pulses, xfw ); + + /****************************************/ + /* Encode Parameters */ + /****************************************/ + silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding ); + + /****************************************/ + /* Encode Excitation Signal */ + /****************************************/ + silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType, + psEnc->sCmn.pulses, psEnc->sCmn.frame_length ); + + nBits = ec_tell( psRangeEnc ); + + if( useCBR == 0 && iter == 0 && nBits <= maxBits ) { + break; + } + } + + if( iter == maxIter ) { + if( found_lower && ( gainsID == gainsID_lower || nBits > maxBits ) ) { + /* Restore output state from earlier iteration that did meet the bitrate budget */ + silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) ); + silk_assert( sRangeEnc_copy2.offs <= 1275 ); + silk_memcpy( psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs ); + silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy2, sizeof( silk_nsq_state ) ); + psEnc->sShape.LastGainIndex = LastGainIndex_copy2; + } + break; + } + + if( nBits > maxBits ) { + if( found_lower == 0 && iter >= 2 ) { + /* Adjust the quantizer's rate/distortion tradeoff and discard previous "upper" results */ + sEncCtrl.Lambda *= 1.5f; + found_upper = 0; + gainsID_upper = -1; + } else { + found_upper = 1; + nBits_upper = nBits; + gainMult_upper = gainMult_Q8; + gainsID_upper = gainsID; + } + } else if( nBits < maxBits - 5 ) { + found_lower = 1; + nBits_lower = nBits; + gainMult_lower = gainMult_Q8; + if( gainsID != gainsID_lower ) { + gainsID_lower = gainsID; + /* Copy part of the output state */ + silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) ); + silk_assert( psRangeEnc->offs <= 1275 ); + silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs ); + silk_memcpy( &sNSQ_copy2, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); + LastGainIndex_copy2 = psEnc->sShape.LastGainIndex; + } + } else { + /* Within 5 bits of budget: close enough */ + break; + } + + if( ( found_lower & found_upper ) == 0 ) { + /* Adjust gain according to high-rate rate/distortion curve */ + opus_int32 gain_factor_Q16; + gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) ); + gain_factor_Q16 = silk_min_32( gain_factor_Q16, SILK_FIX_CONST( 2, 16 ) ); + if( nBits > maxBits ) { + gain_factor_Q16 = silk_max_32( gain_factor_Q16, SILK_FIX_CONST( 1.3, 16 ) ); + } + gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 ); + } else { + /* Adjust gain by interpolating */ + gainMult_Q8 = gainMult_lower + ( ( gainMult_upper - gainMult_lower ) * ( maxBits - nBits_lower ) ) / ( nBits_upper - nBits_lower ); + /* New gain multplier must be between 25% and 75% of old range (note that gainMult_upper < gainMult_lower) */ + if( gainMult_Q8 > silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ) ) { + gainMult_Q8 = silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ); + } else + if( gainMult_Q8 < silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ) ) { + gainMult_Q8 = silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ); + } + } + + for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { + pGains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], gainMult_Q8 ), 8 ); + } + + /* Quantize gains */ + psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev; + silk_gains_quant( psEnc->sCmn.indices.GainsIndices, pGains_Q16, + &psEnc->sShape.LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); + + /* Unique identifier of gains vector */ + gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr ); + + /* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */ + for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { + sEncCtrl.Gains[ i ] = pGains_Q16[ i ] / 65536.0f; + } + } + } + + /* Update input buffer */ + silk_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ], + ( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( silk_float ) ); + + /* Exit without entropy coding */ + if( psEnc->sCmn.prefillFlag ) { + /* No payload */ + *pnBytesOut = 0; + return ret; + } + + /* Parameters needed for next frame */ + psEnc->sCmn.prevLag = sEncCtrl.pitchL[ psEnc->sCmn.nb_subfr - 1 ]; + psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType; + + /****************************************/ + /* Finalize payload */ + /****************************************/ + psEnc->sCmn.first_frame_after_reset = 0; + /* Payload size */ + *pnBytesOut = silk_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 ); + + return ret; +} + +/* Low-Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode excitation at lower bitrate */ +static OPUS_INLINE void silk_LBRR_encode_FLP( + silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ + silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ + const silk_float xfw[], /* I Input signal */ + opus_int condCoding /* I The type of conditional coding used so far for this frame */ +) +{ + opus_int k; + opus_int32 Gains_Q16[ MAX_NB_SUBFR ]; + silk_float TempGains[ MAX_NB_SUBFR ]; + SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesEncoded ]; + silk_nsq_state sNSQ_LBRR; + + /*******************************************/ + /* Control use of inband LBRR */ + /*******************************************/ + if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SILK_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) { + psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded ] = 1; + + /* Copy noise shaping quantizer state and quantization indices from regular encoding */ + silk_memcpy( &sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); + silk_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) ); + + /* Save original gains */ + silk_memcpy( TempGains, psEncCtrl->Gains, psEnc->sCmn.nb_subfr * sizeof( silk_float ) ); + + if( psEnc->sCmn.nFramesEncoded == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded - 1 ] == 0 ) { + /* First frame in packet or previous frame not LBRR coded */ + psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex; + + /* Increase Gains to get target LBRR rate */ + psIndices_LBRR->GainsIndices[ 0 ] += psEnc->sCmn.LBRR_GainIncreases; + psIndices_LBRR->GainsIndices[ 0 ] = silk_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 ); + } + + /* Decode to get gains in sync with decoder */ + silk_gains_dequant( Gains_Q16, psIndices_LBRR->GainsIndices, + &psEnc->sCmn.LBRRprevLastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); + + /* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */ + for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { + psEncCtrl->Gains[ k ] = Gains_Q16[ k ] * ( 1.0f / 65536.0f ); + } + + /*****************************************/ + /* Noise shaping quantization */ + /*****************************************/ + silk_NSQ_wrapper_FLP( psEnc, psEncCtrl, psIndices_LBRR, &sNSQ_LBRR, + psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], xfw ); + + /* Restore original gains */ + silk_memcpy( psEncCtrl->Gains, TempGains, psEnc->sCmn.nb_subfr * sizeof( silk_float ) ); + } +} diff --git a/src/opus-1.1/silk/float/energy_FLP.c b/src/opus-1.1/silk/float/energy_FLP.c new file mode 100644 index 00000000..24b8179f --- /dev/null +++ b/src/opus-1.1/silk/float/energy_FLP.c @@ -0,0 +1,60 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SigProc_FLP.h" + +/* sum of squares of a silk_float array, with result as double */ +double silk_energy_FLP( + const silk_float *data, + opus_int dataSize +) +{ + opus_int i, dataSize4; + double result; + + /* 4x unrolled loop */ + result = 0.0; + dataSize4 = dataSize & 0xFFFC; + for( i = 0; i < dataSize4; i += 4 ) { + result += data[ i + 0 ] * (double)data[ i + 0 ] + + data[ i + 1 ] * (double)data[ i + 1 ] + + data[ i + 2 ] * (double)data[ i + 2 ] + + data[ i + 3 ] * (double)data[ i + 3 ]; + } + + /* add any remaining products */ + for( ; i < dataSize; i++ ) { + result += data[ i ] * (double)data[ i ]; + } + + silk_assert( result >= 0.0 ); + return result; +} diff --git a/src/opus-1.1/silk/float/find_LPC_FLP.c b/src/opus-1.1/silk/float/find_LPC_FLP.c new file mode 100644 index 00000000..61c1ad95 --- /dev/null +++ b/src/opus-1.1/silk/float/find_LPC_FLP.c @@ -0,0 +1,104 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "define.h" +#include "main_FLP.h" +#include "tuning_parameters.h" + +/* LPC analysis */ +void silk_find_LPC_FLP( + silk_encoder_state *psEncC, /* I/O Encoder state */ + opus_int16 NLSF_Q15[], /* O NLSFs */ + const silk_float x[], /* I Input signal */ + const silk_float minInvGain /* I Inverse of max prediction gain */ +) +{ + opus_int k, subfr_length; + silk_float a[ MAX_LPC_ORDER ]; + + /* Used only for NLSF interpolation */ + silk_float res_nrg, res_nrg_2nd, res_nrg_interp; + opus_int16 NLSF0_Q15[ MAX_LPC_ORDER ]; + silk_float a_tmp[ MAX_LPC_ORDER ]; + silk_float LPC_res[ MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ]; + + subfr_length = psEncC->subfr_length + psEncC->predictLPCOrder; + + /* Default: No interpolation */ + psEncC->indices.NLSFInterpCoef_Q2 = 4; + + /* Burg AR analysis for the full frame */ + res_nrg = silk_burg_modified_FLP( a, x, minInvGain, subfr_length, psEncC->nb_subfr, psEncC->predictLPCOrder ); + + if( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) { + /* Optimal solution for last 10 ms; subtract residual energy here, as that's easier than */ + /* adding it to the residual energy of the first 10 ms in each iteration of the search below */ + res_nrg -= silk_burg_modified_FLP( a_tmp, x + ( MAX_NB_SUBFR / 2 ) * subfr_length, minInvGain, subfr_length, MAX_NB_SUBFR / 2, psEncC->predictLPCOrder ); + + /* Convert to NLSFs */ + silk_A2NLSF_FLP( NLSF_Q15, a_tmp, psEncC->predictLPCOrder ); + + /* Search over interpolation indices to find the one with lowest residual energy */ + res_nrg_2nd = silk_float_MAX; + for( k = 3; k >= 0; k-- ) { + /* Interpolate NLSFs for first half */ + silk_interpolate( NLSF0_Q15, psEncC->prev_NLSFq_Q15, NLSF_Q15, k, psEncC->predictLPCOrder ); + + /* Convert to LPC for residual energy evaluation */ + silk_NLSF2A_FLP( a_tmp, NLSF0_Q15, psEncC->predictLPCOrder ); + + /* Calculate residual energy with LSF interpolation */ + silk_LPC_analysis_filter_FLP( LPC_res, a_tmp, x, 2 * subfr_length, psEncC->predictLPCOrder ); + res_nrg_interp = (silk_float)( + silk_energy_FLP( LPC_res + psEncC->predictLPCOrder, subfr_length - psEncC->predictLPCOrder ) + + silk_energy_FLP( LPC_res + psEncC->predictLPCOrder + subfr_length, subfr_length - psEncC->predictLPCOrder ) ); + + /* Determine whether current interpolated NLSFs are best so far */ + if( res_nrg_interp < res_nrg ) { + /* Interpolation has lower residual energy */ + res_nrg = res_nrg_interp; + psEncC->indices.NLSFInterpCoef_Q2 = (opus_int8)k; + } else if( res_nrg_interp > res_nrg_2nd ) { + /* No reason to continue iterating - residual energies will continue to climb */ + break; + } + res_nrg_2nd = res_nrg_interp; + } + } + + if( psEncC->indices.NLSFInterpCoef_Q2 == 4 ) { + /* NLSF interpolation is currently inactive, calculate NLSFs from full frame AR coefficients */ + silk_A2NLSF_FLP( NLSF_Q15, a, psEncC->predictLPCOrder ); + } + + silk_assert( psEncC->indices.NLSFInterpCoef_Q2 == 4 || + ( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) ); +} diff --git a/src/opus-1.1/silk/float/find_LTP_FLP.c b/src/opus-1.1/silk/float/find_LTP_FLP.c new file mode 100644 index 00000000..72299960 --- /dev/null +++ b/src/opus-1.1/silk/float/find_LTP_FLP.c @@ -0,0 +1,132 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main_FLP.h" +#include "tuning_parameters.h" + +void silk_find_LTP_FLP( + silk_float b[ MAX_NB_SUBFR * LTP_ORDER ], /* O LTP coefs */ + silk_float WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */ + silk_float *LTPredCodGain, /* O LTP coding gain */ + const silk_float r_lpc[], /* I LPC residual */ + const opus_int lag[ MAX_NB_SUBFR ], /* I LTP lags */ + const silk_float Wght[ MAX_NB_SUBFR ], /* I Weights */ + const opus_int subfr_length, /* I Subframe length */ + const opus_int nb_subfr, /* I number of subframes */ + const opus_int mem_offset /* I Number of samples in LTP memory */ +) +{ + opus_int i, k; + silk_float *b_ptr, temp, *WLTP_ptr; + silk_float LPC_res_nrg, LPC_LTP_res_nrg; + silk_float d[ MAX_NB_SUBFR ], m, g, delta_b[ LTP_ORDER ]; + silk_float w[ MAX_NB_SUBFR ], nrg[ MAX_NB_SUBFR ], regu; + silk_float Rr[ LTP_ORDER ], rr[ MAX_NB_SUBFR ]; + const silk_float *r_ptr, *lag_ptr; + + b_ptr = b; + WLTP_ptr = WLTP; + r_ptr = &r_lpc[ mem_offset ]; + for( k = 0; k < nb_subfr; k++ ) { + lag_ptr = r_ptr - ( lag[ k ] + LTP_ORDER / 2 ); + + silk_corrMatrix_FLP( lag_ptr, subfr_length, LTP_ORDER, WLTP_ptr ); + silk_corrVector_FLP( lag_ptr, r_ptr, subfr_length, LTP_ORDER, Rr ); + + rr[ k ] = ( silk_float )silk_energy_FLP( r_ptr, subfr_length ); + regu = 1.0f + rr[ k ] + + matrix_ptr( WLTP_ptr, 0, 0, LTP_ORDER ) + + matrix_ptr( WLTP_ptr, LTP_ORDER-1, LTP_ORDER-1, LTP_ORDER ); + regu *= LTP_DAMPING / 3; + silk_regularize_correlations_FLP( WLTP_ptr, &rr[ k ], regu, LTP_ORDER ); + silk_solve_LDL_FLP( WLTP_ptr, LTP_ORDER, Rr, b_ptr ); + + /* Calculate residual energy */ + nrg[ k ] = silk_residual_energy_covar_FLP( b_ptr, WLTP_ptr, Rr, rr[ k ], LTP_ORDER ); + + temp = Wght[ k ] / ( nrg[ k ] * Wght[ k ] + 0.01f * subfr_length ); + silk_scale_vector_FLP( WLTP_ptr, temp, LTP_ORDER * LTP_ORDER ); + w[ k ] = matrix_ptr( WLTP_ptr, LTP_ORDER / 2, LTP_ORDER / 2, LTP_ORDER ); + + r_ptr += subfr_length; + b_ptr += LTP_ORDER; + WLTP_ptr += LTP_ORDER * LTP_ORDER; + } + + /* Compute LTP coding gain */ + if( LTPredCodGain != NULL ) { + LPC_LTP_res_nrg = 1e-6f; + LPC_res_nrg = 0.0f; + for( k = 0; k < nb_subfr; k++ ) { + LPC_res_nrg += rr[ k ] * Wght[ k ]; + LPC_LTP_res_nrg += nrg[ k ] * Wght[ k ]; + } + + silk_assert( LPC_LTP_res_nrg > 0 ); + *LTPredCodGain = 3.0f * silk_log2( LPC_res_nrg / LPC_LTP_res_nrg ); + } + + /* Smoothing */ + /* d = sum( B, 1 ); */ + b_ptr = b; + for( k = 0; k < nb_subfr; k++ ) { + d[ k ] = 0; + for( i = 0; i < LTP_ORDER; i++ ) { + d[ k ] += b_ptr[ i ]; + } + b_ptr += LTP_ORDER; + } + /* m = ( w * d' ) / ( sum( w ) + 1e-3 ); */ + temp = 1e-3f; + for( k = 0; k < nb_subfr; k++ ) { + temp += w[ k ]; + } + m = 0; + for( k = 0; k < nb_subfr; k++ ) { + m += d[ k ] * w[ k ]; + } + m = m / temp; + + b_ptr = b; + for( k = 0; k < nb_subfr; k++ ) { + g = LTP_SMOOTHING / ( LTP_SMOOTHING + w[ k ] ) * ( m - d[ k ] ); + temp = 0; + for( i = 0; i < LTP_ORDER; i++ ) { + delta_b[ i ] = silk_max_float( b_ptr[ i ], 0.1f ); + temp += delta_b[ i ]; + } + temp = g / temp; + for( i = 0; i < LTP_ORDER; i++ ) { + b_ptr[ i ] = b_ptr[ i ] + delta_b[ i ] * temp; + } + b_ptr += LTP_ORDER; + } +} diff --git a/src/opus-1.1/silk/float/find_pitch_lags_FLP.c b/src/opus-1.1/silk/float/find_pitch_lags_FLP.c new file mode 100644 index 00000000..f3b22d25 --- /dev/null +++ b/src/opus-1.1/silk/float/find_pitch_lags_FLP.c @@ -0,0 +1,132 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "main_FLP.h" +#include "tuning_parameters.h" + +void silk_find_pitch_lags_FLP( + silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ + silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ + silk_float res[], /* O Residual */ + const silk_float x[], /* I Speech signal */ + int arch /* I Run-time architecture */ +) +{ + opus_int buf_len; + silk_float thrhld, res_nrg; + const silk_float *x_buf_ptr, *x_buf; + silk_float auto_corr[ MAX_FIND_PITCH_LPC_ORDER + 1 ]; + silk_float A[ MAX_FIND_PITCH_LPC_ORDER ]; + silk_float refl_coef[ MAX_FIND_PITCH_LPC_ORDER ]; + silk_float Wsig[ FIND_PITCH_LPC_WIN_MAX ]; + silk_float *Wsig_ptr; + + /******************************************/ + /* Set up buffer lengths etc based on Fs */ + /******************************************/ + buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length; + + /* Safety check */ + silk_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length ); + + x_buf = x - psEnc->sCmn.ltp_mem_length; + + /******************************************/ + /* Estimate LPC AR coeficients */ + /******************************************/ + + /* Calculate windowed signal */ + + /* First LA_LTP samples */ + x_buf_ptr = x_buf + buf_len - psEnc->sCmn.pitch_LPC_win_length; + Wsig_ptr = Wsig; + silk_apply_sine_window_FLP( Wsig_ptr, x_buf_ptr, 1, psEnc->sCmn.la_pitch ); + + /* Middle non-windowed samples */ + Wsig_ptr += psEnc->sCmn.la_pitch; + x_buf_ptr += psEnc->sCmn.la_pitch; + silk_memcpy( Wsig_ptr, x_buf_ptr, ( psEnc->sCmn.pitch_LPC_win_length - ( psEnc->sCmn.la_pitch << 1 ) ) * sizeof( silk_float ) ); + + /* Last LA_LTP samples */ + Wsig_ptr += psEnc->sCmn.pitch_LPC_win_length - ( psEnc->sCmn.la_pitch << 1 ); + x_buf_ptr += psEnc->sCmn.pitch_LPC_win_length - ( psEnc->sCmn.la_pitch << 1 ); + silk_apply_sine_window_FLP( Wsig_ptr, x_buf_ptr, 2, psEnc->sCmn.la_pitch ); + + /* Calculate autocorrelation sequence */ + silk_autocorrelation_FLP( auto_corr, Wsig, psEnc->sCmn.pitch_LPC_win_length, psEnc->sCmn.pitchEstimationLPCOrder + 1 ); + + /* Add white noise, as a fraction of the energy */ + auto_corr[ 0 ] += auto_corr[ 0 ] * FIND_PITCH_WHITE_NOISE_FRACTION + 1; + + /* Calculate the reflection coefficients using Schur */ + res_nrg = silk_schur_FLP( refl_coef, auto_corr, psEnc->sCmn.pitchEstimationLPCOrder ); + + /* Prediction gain */ + psEncCtrl->predGain = auto_corr[ 0 ] / silk_max_float( res_nrg, 1.0f ); + + /* Convert reflection coefficients to prediction coefficients */ + silk_k2a_FLP( A, refl_coef, psEnc->sCmn.pitchEstimationLPCOrder ); + + /* Bandwidth expansion */ + silk_bwexpander_FLP( A, psEnc->sCmn.pitchEstimationLPCOrder, FIND_PITCH_BANDWIDTH_EXPANSION ); + + /*****************************************/ + /* LPC analysis filtering */ + /*****************************************/ + silk_LPC_analysis_filter_FLP( res, A, x_buf, buf_len, psEnc->sCmn.pitchEstimationLPCOrder ); + + if( psEnc->sCmn.indices.signalType != TYPE_NO_VOICE_ACTIVITY && psEnc->sCmn.first_frame_after_reset == 0 ) { + /* Threshold for pitch estimator */ + thrhld = 0.6f; + thrhld -= 0.004f * psEnc->sCmn.pitchEstimationLPCOrder; + thrhld -= 0.1f * psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f ); + thrhld -= 0.15f * (psEnc->sCmn.prevSignalType >> 1); + thrhld -= 0.1f * psEnc->sCmn.input_tilt_Q15 * ( 1.0f / 32768.0f ); + + /*****************************************/ + /* Call Pitch estimator */ + /*****************************************/ + if( silk_pitch_analysis_core_FLP( res, psEncCtrl->pitchL, &psEnc->sCmn.indices.lagIndex, + &psEnc->sCmn.indices.contourIndex, &psEnc->LTPCorr, psEnc->sCmn.prevLag, psEnc->sCmn.pitchEstimationThreshold_Q16 / 65536.0f, + thrhld, psEnc->sCmn.fs_kHz, psEnc->sCmn.pitchEstimationComplexity, psEnc->sCmn.nb_subfr, arch ) == 0 ) + { + psEnc->sCmn.indices.signalType = TYPE_VOICED; + } else { + psEnc->sCmn.indices.signalType = TYPE_UNVOICED; + } + } else { + silk_memset( psEncCtrl->pitchL, 0, sizeof( psEncCtrl->pitchL ) ); + psEnc->sCmn.indices.lagIndex = 0; + psEnc->sCmn.indices.contourIndex = 0; + psEnc->LTPCorr = 0; + } +} diff --git a/src/opus-1.1/silk/float/find_pred_coefs_FLP.c b/src/opus-1.1/silk/float/find_pred_coefs_FLP.c new file mode 100644 index 00000000..ea2c6c43 --- /dev/null +++ b/src/opus-1.1/silk/float/find_pred_coefs_FLP.c @@ -0,0 +1,117 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main_FLP.h" + +/* Find LPC and LTP coefficients */ +void silk_find_pred_coefs_FLP( + silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ + silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ + const silk_float res_pitch[], /* I Residual from pitch analysis */ + const silk_float x[], /* I Speech signal */ + opus_int condCoding /* I The type of conditional coding to use */ +) +{ + opus_int i; + silk_float WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ]; + silk_float invGains[ MAX_NB_SUBFR ], Wght[ MAX_NB_SUBFR ]; + opus_int16 NLSF_Q15[ MAX_LPC_ORDER ]; + const silk_float *x_ptr; + silk_float *x_pre_ptr, LPC_in_pre[ MAX_NB_SUBFR * MAX_LPC_ORDER + MAX_FRAME_LENGTH ]; + silk_float minInvGain; + + /* Weighting for weighted least squares */ + for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { + silk_assert( psEncCtrl->Gains[ i ] > 0.0f ); + invGains[ i ] = 1.0f / psEncCtrl->Gains[ i ]; + Wght[ i ] = invGains[ i ] * invGains[ i ]; + } + + if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { + /**********/ + /* VOICED */ + /**********/ + silk_assert( psEnc->sCmn.ltp_mem_length - psEnc->sCmn.predictLPCOrder >= psEncCtrl->pitchL[ 0 ] + LTP_ORDER / 2 ); + + /* LTP analysis */ + silk_find_LTP_FLP( psEncCtrl->LTPCoef, WLTP, &psEncCtrl->LTPredCodGain, res_pitch, + psEncCtrl->pitchL, Wght, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.ltp_mem_length ); + + /* Quantize LTP gain parameters */ + silk_quant_LTP_gains_FLP( psEncCtrl->LTPCoef, psEnc->sCmn.indices.LTPIndex, &psEnc->sCmn.indices.PERIndex, + &psEnc->sCmn.sum_log_gain_Q7, WLTP, psEnc->sCmn.mu_LTP_Q9, psEnc->sCmn.LTPQuantLowComplexity, psEnc->sCmn.nb_subfr ); + + /* Control LTP scaling */ + silk_LTP_scale_ctrl_FLP( psEnc, psEncCtrl, condCoding ); + + /* Create LTP residual */ + silk_LTP_analysis_filter_FLP( LPC_in_pre, x - psEnc->sCmn.predictLPCOrder, psEncCtrl->LTPCoef, + psEncCtrl->pitchL, invGains, psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder ); + } else { + /************/ + /* UNVOICED */ + /************/ + /* Create signal with prepended subframes, scaled by inverse gains */ + x_ptr = x - psEnc->sCmn.predictLPCOrder; + x_pre_ptr = LPC_in_pre; + for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { + silk_scale_copy_vector_FLP( x_pre_ptr, x_ptr, invGains[ i ], + psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder ); + x_pre_ptr += psEnc->sCmn.subfr_length + psEnc->sCmn.predictLPCOrder; + x_ptr += psEnc->sCmn.subfr_length; + } + silk_memset( psEncCtrl->LTPCoef, 0, psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( silk_float ) ); + psEncCtrl->LTPredCodGain = 0.0f; + psEnc->sCmn.sum_log_gain_Q7 = 0; + } + + /* Limit on total predictive coding gain */ + if( psEnc->sCmn.first_frame_after_reset ) { + minInvGain = 1.0f / MAX_PREDICTION_POWER_GAIN_AFTER_RESET; + } else { + minInvGain = (silk_float)pow( 2, psEncCtrl->LTPredCodGain / 3 ) / MAX_PREDICTION_POWER_GAIN; + minInvGain /= 0.25f + 0.75f * psEncCtrl->coding_quality; + } + + /* LPC_in_pre contains the LTP-filtered input for voiced, and the unfiltered input for unvoiced */ + silk_find_LPC_FLP( &psEnc->sCmn, NLSF_Q15, LPC_in_pre, minInvGain ); + + /* Quantize LSFs */ + silk_process_NLSFs_FLP( &psEnc->sCmn, psEncCtrl->PredCoef, NLSF_Q15, psEnc->sCmn.prev_NLSFq_Q15 ); + + /* Calculate residual energy using quantized LPC coefficients */ + silk_residual_energy_FLP( psEncCtrl->ResNrg, LPC_in_pre, psEncCtrl->PredCoef, psEncCtrl->Gains, + psEnc->sCmn.subfr_length, psEnc->sCmn.nb_subfr, psEnc->sCmn.predictLPCOrder ); + + /* Copy to prediction struct for use in next frame for interpolation */ + silk_memcpy( psEnc->sCmn.prev_NLSFq_Q15, NLSF_Q15, sizeof( psEnc->sCmn.prev_NLSFq_Q15 ) ); +} + diff --git a/src/opus-1.1/silk/float/inner_product_FLP.c b/src/opus-1.1/silk/float/inner_product_FLP.c new file mode 100644 index 00000000..029c0129 --- /dev/null +++ b/src/opus-1.1/silk/float/inner_product_FLP.c @@ -0,0 +1,60 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SigProc_FLP.h" + +/* inner product of two silk_float arrays, with result as double */ +double silk_inner_product_FLP( + const silk_float *data1, + const silk_float *data2, + opus_int dataSize +) +{ + opus_int i, dataSize4; + double result; + + /* 4x unrolled loop */ + result = 0.0; + dataSize4 = dataSize & 0xFFFC; + for( i = 0; i < dataSize4; i += 4 ) { + result += data1[ i + 0 ] * (double)data2[ i + 0 ] + + data1[ i + 1 ] * (double)data2[ i + 1 ] + + data1[ i + 2 ] * (double)data2[ i + 2 ] + + data1[ i + 3 ] * (double)data2[ i + 3 ]; + } + + /* add any remaining products */ + for( ; i < dataSize; i++ ) { + result += data1[ i ] * (double)data2[ i ]; + } + + return result; +} diff --git a/src/opus-1.1/silk/float/k2a_FLP.c b/src/opus-1.1/silk/float/k2a_FLP.c new file mode 100644 index 00000000..12af4e76 --- /dev/null +++ b/src/opus-1.1/silk/float/k2a_FLP.c @@ -0,0 +1,53 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SigProc_FLP.h" + +/* step up function, converts reflection coefficients to prediction coefficients */ +void silk_k2a_FLP( + silk_float *A, /* O prediction coefficients [order] */ + const silk_float *rc, /* I reflection coefficients [order] */ + opus_int32 order /* I prediction order */ +) +{ + opus_int k, n; + silk_float Atmp[ SILK_MAX_ORDER_LPC ]; + + for( k = 0; k < order; k++ ) { + for( n = 0; n < k; n++ ) { + Atmp[ n ] = A[ n ]; + } + for( n = 0; n < k; n++ ) { + A[ n ] += Atmp[ k - n - 1 ] * rc[ k ]; + } + A[ k ] = -rc[ k ]; + } +} diff --git a/src/opus-1.1/silk/float/levinsondurbin_FLP.c b/src/opus-1.1/silk/float/levinsondurbin_FLP.c new file mode 100644 index 00000000..f0ba6069 --- /dev/null +++ b/src/opus-1.1/silk/float/levinsondurbin_FLP.c @@ -0,0 +1,81 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SigProc_FLP.h" + +/* Solve the normal equations using the Levinson-Durbin recursion */ +silk_float silk_levinsondurbin_FLP( /* O prediction error energy */ + silk_float A[], /* O prediction coefficients [order] */ + const silk_float corr[], /* I input auto-correlations [order + 1] */ + const opus_int order /* I prediction order */ +) +{ + opus_int i, mHalf, m; + silk_float min_nrg, nrg, t, km, Atmp1, Atmp2; + + min_nrg = 1e-12f * corr[ 0 ] + 1e-9f; + nrg = corr[ 0 ]; + nrg = silk_max_float(min_nrg, nrg); + A[ 0 ] = corr[ 1 ] / nrg; + nrg -= A[ 0 ] * corr[ 1 ]; + nrg = silk_max_float(min_nrg, nrg); + + for( m = 1; m < order; m++ ) + { + t = corr[ m + 1 ]; + for( i = 0; i < m; i++ ) { + t -= A[ i ] * corr[ m - i ]; + } + + /* reflection coefficient */ + km = t / nrg; + + /* residual energy */ + nrg -= km * t; + nrg = silk_max_float(min_nrg, nrg); + + mHalf = m >> 1; + for( i = 0; i < mHalf; i++ ) { + Atmp1 = A[ i ]; + Atmp2 = A[ m - i - 1 ]; + A[ m - i - 1 ] -= km * Atmp1; + A[ i ] -= km * Atmp2; + } + if( m & 1 ) { + A[ mHalf ] -= km * A[ mHalf ]; + } + A[ m ] = km; + } + + /* return the residual energy */ + return nrg; +} + diff --git a/src/opus-1.1/silk/float/main_FLP.h b/src/opus-1.1/silk/float/main_FLP.h new file mode 100644 index 00000000..fb553b61 --- /dev/null +++ b/src/opus-1.1/silk/float/main_FLP.h @@ -0,0 +1,312 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifndef SILK_MAIN_FLP_H +#define SILK_MAIN_FLP_H + +#include "SigProc_FLP.h" +#include "SigProc_FIX.h" +#include "structs_FLP.h" +#include "main.h" +#include "define.h" +#include "debug.h" +#include "entenc.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define silk_encoder_state_Fxx silk_encoder_state_FLP +#define silk_encode_do_VAD_Fxx silk_encode_do_VAD_FLP +#define silk_encode_frame_Fxx silk_encode_frame_FLP + +/*********************/ +/* Encoder Functions */ +/*********************/ + +/* High-pass filter with cutoff frequency adaptation based on pitch lag statistics */ +void silk_HP_variable_cutoff( + silk_encoder_state_Fxx state_Fxx[] /* I/O Encoder states */ +); + +/* Encoder main function */ +void silk_encode_do_VAD_FLP( + silk_encoder_state_FLP *psEnc /* I/O Encoder state FLP */ +); + +/* Encoder main function */ +opus_int silk_encode_frame_FLP( + silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ + opus_int32 *pnBytesOut, /* O Number of payload bytes; */ + ec_enc *psRangeEnc, /* I/O compressor data structure */ + opus_int condCoding, /* I The type of conditional coding to use */ + opus_int maxBits, /* I If > 0: maximum number of output bits */ + opus_int useCBR /* I Flag to force constant-bitrate operation */ +); + +/* Initializes the Silk encoder state */ +opus_int silk_init_encoder( + silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ + int arch /* I Run-tim architecture */ +); + +/* Control the Silk encoder */ +opus_int silk_control_encoder( + silk_encoder_state_FLP *psEnc, /* I/O Pointer to Silk encoder state FLP */ + silk_EncControlStruct *encControl, /* I Control structure */ + const opus_int32 TargetRate_bps, /* I Target max bitrate (bps) */ + const opus_int allow_bw_switch, /* I Flag to allow switching audio bandwidth */ + const opus_int channelNb, /* I Channel number */ + const opus_int force_fs_kHz +); + +/****************/ +/* Prefiltering */ +/****************/ +void silk_prefilter_FLP( + silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ + const silk_encoder_control_FLP *psEncCtrl, /* I Encoder control FLP */ + silk_float xw[], /* O Weighted signal */ + const silk_float x[] /* I Speech signal */ +); + +/**************************/ +/* Noise shaping analysis */ +/**************************/ +/* Compute noise shaping coefficients and initial gain values */ +void silk_noise_shape_analysis_FLP( + silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ + silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ + const silk_float *pitch_res, /* I LPC residual from pitch analysis */ + const silk_float *x /* I Input signal [frame_length + la_shape] */ +); + +/* Autocorrelations for a warped frequency axis */ +void silk_warped_autocorrelation_FLP( + silk_float *corr, /* O Result [order + 1] */ + const silk_float *input, /* I Input data to correlate */ + const silk_float warping, /* I Warping coefficient */ + const opus_int length, /* I Length of input */ + const opus_int order /* I Correlation order (even) */ +); + +/* Calculation of LTP state scaling */ +void silk_LTP_scale_ctrl_FLP( + silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ + silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ + opus_int condCoding /* I The type of conditional coding to use */ +); + +/**********************************************/ +/* Prediction Analysis */ +/**********************************************/ +/* Find pitch lags */ +void silk_find_pitch_lags_FLP( + silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ + silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ + silk_float res[], /* O Residual */ + const silk_float x[], /* I Speech signal */ + int arch /* I Run-time architecture */ +); + +/* Find LPC and LTP coefficients */ +void silk_find_pred_coefs_FLP( + silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ + silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ + const silk_float res_pitch[], /* I Residual from pitch analysis */ + const silk_float x[], /* I Speech signal */ + opus_int condCoding /* I The type of conditional coding to use */ +); + +/* LPC analysis */ +void silk_find_LPC_FLP( + silk_encoder_state *psEncC, /* I/O Encoder state */ + opus_int16 NLSF_Q15[], /* O NLSFs */ + const silk_float x[], /* I Input signal */ + const silk_float minInvGain /* I Prediction gain from LTP (dB) */ +); + +/* LTP analysis */ +void silk_find_LTP_FLP( + silk_float b[ MAX_NB_SUBFR * LTP_ORDER ], /* O LTP coefs */ + silk_float WLTP[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* O Weight for LTP quantization */ + silk_float *LTPredCodGain, /* O LTP coding gain */ + const silk_float r_lpc[], /* I LPC residual */ + const opus_int lag[ MAX_NB_SUBFR ], /* I LTP lags */ + const silk_float Wght[ MAX_NB_SUBFR ], /* I Weights */ + const opus_int subfr_length, /* I Subframe length */ + const opus_int nb_subfr, /* I number of subframes */ + const opus_int mem_offset /* I Number of samples in LTP memory */ +); + +void silk_LTP_analysis_filter_FLP( + silk_float *LTP_res, /* O LTP res MAX_NB_SUBFR*(pre_lgth+subfr_lngth) */ + const silk_float *x, /* I Input signal, with preceding samples */ + const silk_float B[ LTP_ORDER * MAX_NB_SUBFR ], /* I LTP coefficients for each subframe */ + const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ + const silk_float invGains[ MAX_NB_SUBFR ], /* I Inverse quantization gains */ + const opus_int subfr_length, /* I Length of each subframe */ + const opus_int nb_subfr, /* I number of subframes */ + const opus_int pre_length /* I Preceding samples for each subframe */ +); + +/* Calculates residual energies of input subframes where all subframes have LPC_order */ +/* of preceding samples */ +void silk_residual_energy_FLP( + silk_float nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */ + const silk_float x[], /* I Input signal */ + silk_float a[ 2 ][ MAX_LPC_ORDER ], /* I AR coefs for each frame half */ + const silk_float gains[], /* I Quantization gains */ + const opus_int subfr_length, /* I Subframe length */ + const opus_int nb_subfr, /* I number of subframes */ + const opus_int LPC_order /* I LPC order */ +); + +/* 16th order LPC analysis filter */ +void silk_LPC_analysis_filter_FLP( + silk_float r_LPC[], /* O LPC residual signal */ + const silk_float PredCoef[], /* I LPC coefficients */ + const silk_float s[], /* I Input signal */ + const opus_int length, /* I Length of input signal */ + const opus_int Order /* I LPC order */ +); + +/* LTP tap quantizer */ +void silk_quant_LTP_gains_FLP( + silk_float B[ MAX_NB_SUBFR * LTP_ORDER ], /* I/O (Un-)quantized LTP gains */ + opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook index */ + opus_int8 *periodicity_index, /* O Periodicity index */ + opus_int32 *sum_log_gain_Q7, /* I/O Cumulative max prediction gain */ + const silk_float W[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* I Error weights */ + const opus_int mu_Q10, /* I Mu value (R/D tradeoff) */ + const opus_int lowComplexity, /* I Flag for low complexity */ + const opus_int nb_subfr /* I number of subframes */ +); + +/* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */ +silk_float silk_residual_energy_covar_FLP( /* O Weighted residual energy */ + const silk_float *c, /* I Filter coefficients */ + silk_float *wXX, /* I/O Weighted correlation matrix, reg. out */ + const silk_float *wXx, /* I Weighted correlation vector */ + const silk_float wxx, /* I Weighted correlation value */ + const opus_int D /* I Dimension */ +); + +/* Processing of gains */ +void silk_process_gains_FLP( + silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ + silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ + opus_int condCoding /* I The type of conditional coding to use */ +); + +/******************/ +/* Linear Algebra */ +/******************/ +/* Calculates correlation matrix X'*X */ +void silk_corrMatrix_FLP( + const silk_float *x, /* I x vector [ L+order-1 ] used to create X */ + const opus_int L, /* I Length of vectors */ + const opus_int Order, /* I Max lag for correlation */ + silk_float *XX /* O X'*X correlation matrix [order x order] */ +); + +/* Calculates correlation vector X'*t */ +void silk_corrVector_FLP( + const silk_float *x, /* I x vector [L+order-1] used to create X */ + const silk_float *t, /* I Target vector [L] */ + const opus_int L, /* I Length of vecors */ + const opus_int Order, /* I Max lag for correlation */ + silk_float *Xt /* O X'*t correlation vector [order] */ +); + +/* Add noise to matrix diagonal */ +void silk_regularize_correlations_FLP( + silk_float *XX, /* I/O Correlation matrices */ + silk_float *xx, /* I/O Correlation values */ + const silk_float noise, /* I Noise energy to add */ + const opus_int D /* I Dimension of XX */ +); + +/* Function to solve linear equation Ax = b, where A is an MxM symmetric matrix */ +void silk_solve_LDL_FLP( + silk_float *A, /* I/O Symmetric square matrix, out: reg. */ + const opus_int M, /* I Size of matrix */ + const silk_float *b, /* I Pointer to b vector */ + silk_float *x /* O Pointer to x solution vector */ +); + +/* Apply sine window to signal vector. */ +/* Window types: */ +/* 1 -> sine window from 0 to pi/2 */ +/* 2 -> sine window from pi/2 to pi */ +void silk_apply_sine_window_FLP( + silk_float px_win[], /* O Pointer to windowed signal */ + const silk_float px[], /* I Pointer to input signal */ + const opus_int win_type, /* I Selects a window type */ + const opus_int length /* I Window length, multiple of 4 */ +); + +/* Wrapper functions. Call flp / fix code */ + +/* Convert AR filter coefficients to NLSF parameters */ +void silk_A2NLSF_FLP( + opus_int16 *NLSF_Q15, /* O NLSF vector [ LPC_order ] */ + const silk_float *pAR, /* I LPC coefficients [ LPC_order ] */ + const opus_int LPC_order /* I LPC order */ +); + +/* Convert NLSF parameters to AR prediction filter coefficients */ +void silk_NLSF2A_FLP( + silk_float *pAR, /* O LPC coefficients [ LPC_order ] */ + const opus_int16 *NLSF_Q15, /* I NLSF vector [ LPC_order ] */ + const opus_int LPC_order /* I LPC order */ +); + +/* Limit, stabilize, and quantize NLSFs */ +void silk_process_NLSFs_FLP( + silk_encoder_state *psEncC, /* I/O Encoder state */ + silk_float PredCoef[ 2 ][ MAX_LPC_ORDER ], /* O Prediction coefficients */ + opus_int16 NLSF_Q15[ MAX_LPC_ORDER ], /* I/O Normalized LSFs (quant out) (0 - (2^15-1)) */ + const opus_int16 prev_NLSF_Q15[ MAX_LPC_ORDER ] /* I Previous Normalized LSFs (0 - (2^15-1)) */ +); + +/* Floating-point Silk NSQ wrapper */ +void silk_NSQ_wrapper_FLP( + silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ + silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ + SideInfoIndices *psIndices, /* I/O Quantization indices */ + silk_nsq_state *psNSQ, /* I/O Noise Shaping Quantzation state */ + opus_int8 pulses[], /* O Quantized pulse signal */ + const silk_float x[] /* I Prefiltered input signal */ +); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/opus-1.1/silk/float/noise_shape_analysis_FLP.c b/src/opus-1.1/silk/float/noise_shape_analysis_FLP.c new file mode 100644 index 00000000..65f6ea58 --- /dev/null +++ b/src/opus-1.1/silk/float/noise_shape_analysis_FLP.c @@ -0,0 +1,365 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main_FLP.h" +#include "tuning_parameters.h" + +/* Compute gain to make warped filter coefficients have a zero mean log frequency response on a */ +/* non-warped frequency scale. (So that it can be implemented with a minimum-phase monic filter.) */ +/* Note: A monic filter is one with the first coefficient equal to 1.0. In Silk we omit the first */ +/* coefficient in an array of coefficients, for monic filters. */ +static OPUS_INLINE silk_float warped_gain( + const silk_float *coefs, + silk_float lambda, + opus_int order +) { + opus_int i; + silk_float gain; + + lambda = -lambda; + gain = coefs[ order - 1 ]; + for( i = order - 2; i >= 0; i-- ) { + gain = lambda * gain + coefs[ i ]; + } + return (silk_float)( 1.0f / ( 1.0f - lambda * gain ) ); +} + +/* Convert warped filter coefficients to monic pseudo-warped coefficients and limit maximum */ +/* amplitude of monic warped coefficients by using bandwidth expansion on the true coefficients */ +static OPUS_INLINE void warped_true2monic_coefs( + silk_float *coefs_syn, + silk_float *coefs_ana, + silk_float lambda, + silk_float limit, + opus_int order +) { + opus_int i, iter, ind = 0; + silk_float tmp, maxabs, chirp, gain_syn, gain_ana; + + /* Convert to monic coefficients */ + for( i = order - 1; i > 0; i-- ) { + coefs_syn[ i - 1 ] -= lambda * coefs_syn[ i ]; + coefs_ana[ i - 1 ] -= lambda * coefs_ana[ i ]; + } + gain_syn = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_syn[ 0 ] ); + gain_ana = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_ana[ 0 ] ); + for( i = 0; i < order; i++ ) { + coefs_syn[ i ] *= gain_syn; + coefs_ana[ i ] *= gain_ana; + } + + /* Limit */ + for( iter = 0; iter < 10; iter++ ) { + /* Find maximum absolute value */ + maxabs = -1.0f; + for( i = 0; i < order; i++ ) { + tmp = silk_max( silk_abs_float( coefs_syn[ i ] ), silk_abs_float( coefs_ana[ i ] ) ); + if( tmp > maxabs ) { + maxabs = tmp; + ind = i; + } + } + if( maxabs <= limit ) { + /* Coefficients are within range - done */ + return; + } + + /* Convert back to true warped coefficients */ + for( i = 1; i < order; i++ ) { + coefs_syn[ i - 1 ] += lambda * coefs_syn[ i ]; + coefs_ana[ i - 1 ] += lambda * coefs_ana[ i ]; + } + gain_syn = 1.0f / gain_syn; + gain_ana = 1.0f / gain_ana; + for( i = 0; i < order; i++ ) { + coefs_syn[ i ] *= gain_syn; + coefs_ana[ i ] *= gain_ana; + } + + /* Apply bandwidth expansion */ + chirp = 0.99f - ( 0.8f + 0.1f * iter ) * ( maxabs - limit ) / ( maxabs * ( ind + 1 ) ); + silk_bwexpander_FLP( coefs_syn, order, chirp ); + silk_bwexpander_FLP( coefs_ana, order, chirp ); + + /* Convert to monic warped coefficients */ + for( i = order - 1; i > 0; i-- ) { + coefs_syn[ i - 1 ] -= lambda * coefs_syn[ i ]; + coefs_ana[ i - 1 ] -= lambda * coefs_ana[ i ]; + } + gain_syn = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_syn[ 0 ] ); + gain_ana = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_ana[ 0 ] ); + for( i = 0; i < order; i++ ) { + coefs_syn[ i ] *= gain_syn; + coefs_ana[ i ] *= gain_ana; + } + } + silk_assert( 0 ); +} + +/* Compute noise shaping coefficients and initial gain values */ +void silk_noise_shape_analysis_FLP( + silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ + silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ + const silk_float *pitch_res, /* I LPC residual from pitch analysis */ + const silk_float *x /* I Input signal [frame_length + la_shape] */ +) +{ + silk_shape_state_FLP *psShapeSt = &psEnc->sShape; + opus_int k, nSamples; + silk_float SNR_adj_dB, HarmBoost, HarmShapeGain, Tilt; + silk_float nrg, pre_nrg, log_energy, log_energy_prev, energy_variation; + silk_float delta, BWExp1, BWExp2, gain_mult, gain_add, strength, b, warping; + silk_float x_windowed[ SHAPE_LPC_WIN_MAX ]; + silk_float auto_corr[ MAX_SHAPE_LPC_ORDER + 1 ]; + const silk_float *x_ptr, *pitch_res_ptr; + + /* Point to start of first LPC analysis block */ + x_ptr = x - psEnc->sCmn.la_shape; + + /****************/ + /* GAIN CONTROL */ + /****************/ + SNR_adj_dB = psEnc->sCmn.SNR_dB_Q7 * ( 1 / 128.0f ); + + /* Input quality is the average of the quality in the lowest two VAD bands */ + psEncCtrl->input_quality = 0.5f * ( psEnc->sCmn.input_quality_bands_Q15[ 0 ] + psEnc->sCmn.input_quality_bands_Q15[ 1 ] ) * ( 1.0f / 32768.0f ); + + /* Coding quality level, between 0.0 and 1.0 */ + psEncCtrl->coding_quality = silk_sigmoid( 0.25f * ( SNR_adj_dB - 20.0f ) ); + + if( psEnc->sCmn.useCBR == 0 ) { + /* Reduce coding SNR during low speech activity */ + b = 1.0f - psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f ); + SNR_adj_dB -= BG_SNR_DECR_dB * psEncCtrl->coding_quality * ( 0.5f + 0.5f * psEncCtrl->input_quality ) * b * b; + } + + if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { + /* Reduce gains for periodic signals */ + SNR_adj_dB += HARM_SNR_INCR_dB * psEnc->LTPCorr; + } else { + /* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */ + SNR_adj_dB += ( -0.4f * psEnc->sCmn.SNR_dB_Q7 * ( 1 / 128.0f ) + 6.0f ) * ( 1.0f - psEncCtrl->input_quality ); + } + + /*************************/ + /* SPARSENESS PROCESSING */ + /*************************/ + /* Set quantizer offset */ + if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { + /* Initially set to 0; may be overruled in process_gains(..) */ + psEnc->sCmn.indices.quantOffsetType = 0; + psEncCtrl->sparseness = 0.0f; + } else { + /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */ + nSamples = 2 * psEnc->sCmn.fs_kHz; + energy_variation = 0.0f; + log_energy_prev = 0.0f; + pitch_res_ptr = pitch_res; + for( k = 0; k < silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2; k++ ) { + nrg = ( silk_float )nSamples + ( silk_float )silk_energy_FLP( pitch_res_ptr, nSamples ); + log_energy = silk_log2( nrg ); + if( k > 0 ) { + energy_variation += silk_abs_float( log_energy - log_energy_prev ); + } + log_energy_prev = log_energy; + pitch_res_ptr += nSamples; + } + psEncCtrl->sparseness = silk_sigmoid( 0.4f * ( energy_variation - 5.0f ) ); + + /* Set quantization offset depending on sparseness measure */ + if( psEncCtrl->sparseness > SPARSENESS_THRESHOLD_QNT_OFFSET ) { + psEnc->sCmn.indices.quantOffsetType = 0; + } else { + psEnc->sCmn.indices.quantOffsetType = 1; + } + + /* Increase coding SNR for sparse signals */ + SNR_adj_dB += SPARSE_SNR_INCR_dB * ( psEncCtrl->sparseness - 0.5f ); + } + + /*******************************/ + /* Control bandwidth expansion */ + /*******************************/ + /* More BWE for signals with high prediction gain */ + strength = FIND_PITCH_WHITE_NOISE_FRACTION * psEncCtrl->predGain; /* between 0.0 and 1.0 */ + BWExp1 = BWExp2 = BANDWIDTH_EXPANSION / ( 1.0f + strength * strength ); + delta = LOW_RATE_BANDWIDTH_EXPANSION_DELTA * ( 1.0f - 0.75f * psEncCtrl->coding_quality ); + BWExp1 -= delta; + BWExp2 += delta; + /* BWExp1 will be applied after BWExp2, so make it relative */ + BWExp1 /= BWExp2; + + if( psEnc->sCmn.warping_Q16 > 0 ) { + /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */ + warping = (silk_float)psEnc->sCmn.warping_Q16 / 65536.0f + 0.01f * psEncCtrl->coding_quality; + } else { + warping = 0.0f; + } + + /********************************************/ + /* Compute noise shaping AR coefs and gains */ + /********************************************/ + for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { + /* Apply window: sine slope followed by flat part followed by cosine slope */ + opus_int shift, slope_part, flat_part; + flat_part = psEnc->sCmn.fs_kHz * 3; + slope_part = ( psEnc->sCmn.shapeWinLength - flat_part ) / 2; + + silk_apply_sine_window_FLP( x_windowed, x_ptr, 1, slope_part ); + shift = slope_part; + silk_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(silk_float) ); + shift += flat_part; + silk_apply_sine_window_FLP( x_windowed + shift, x_ptr + shift, 2, slope_part ); + + /* Update pointer: next LPC analysis block */ + x_ptr += psEnc->sCmn.subfr_length; + + if( psEnc->sCmn.warping_Q16 > 0 ) { + /* Calculate warped auto correlation */ + silk_warped_autocorrelation_FLP( auto_corr, x_windowed, warping, + psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder ); + } else { + /* Calculate regular auto correlation */ + silk_autocorrelation_FLP( auto_corr, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1 ); + } + + /* Add white noise, as a fraction of energy */ + auto_corr[ 0 ] += auto_corr[ 0 ] * SHAPE_WHITE_NOISE_FRACTION; + + /* Convert correlations to prediction coefficients, and compute residual energy */ + nrg = silk_levinsondurbin_FLP( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], auto_corr, psEnc->sCmn.shapingLPCOrder ); + psEncCtrl->Gains[ k ] = ( silk_float )sqrt( nrg ); + + if( psEnc->sCmn.warping_Q16 > 0 ) { + /* Adjust gain for warping */ + psEncCtrl->Gains[ k ] *= warped_gain( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], warping, psEnc->sCmn.shapingLPCOrder ); + } + + /* Bandwidth expansion for synthesis filter shaping */ + silk_bwexpander_FLP( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder, BWExp2 ); + + /* Compute noise shaping filter coefficients */ + silk_memcpy( + &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ], + &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], + psEnc->sCmn.shapingLPCOrder * sizeof( silk_float ) ); + + /* Bandwidth expansion for analysis filter shaping */ + silk_bwexpander_FLP( &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder, BWExp1 ); + + /* Ratio of prediction gains, in energy domain */ + pre_nrg = silk_LPC_inverse_pred_gain_FLP( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder ); + nrg = silk_LPC_inverse_pred_gain_FLP( &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder ); + psEncCtrl->GainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg ); + + /* Convert to monic warped prediction coefficients and limit absolute values */ + warped_true2monic_coefs( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ], + warping, 3.999f, psEnc->sCmn.shapingLPCOrder ); + } + + /*****************/ + /* Gain tweaking */ + /*****************/ + /* Increase gains during low speech activity */ + gain_mult = (silk_float)pow( 2.0f, -0.16f * SNR_adj_dB ); + gain_add = (silk_float)pow( 2.0f, 0.16f * MIN_QGAIN_DB ); + for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { + psEncCtrl->Gains[ k ] *= gain_mult; + psEncCtrl->Gains[ k ] += gain_add; + } + + gain_mult = 1.0f + INPUT_TILT + psEncCtrl->coding_quality * HIGH_RATE_INPUT_TILT; + for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { + psEncCtrl->GainsPre[ k ] *= gain_mult; + } + + /************************************************/ + /* Control low-frequency shaping and noise tilt */ + /************************************************/ + /* Less low frequency shaping for noisy inputs */ + strength = LOW_FREQ_SHAPING * ( 1.0f + LOW_QUALITY_LOW_FREQ_SHAPING_DECR * ( psEnc->sCmn.input_quality_bands_Q15[ 0 ] * ( 1.0f / 32768.0f ) - 1.0f ) ); + strength *= psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f ); + if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { + /* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */ + /*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/ + for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { + b = 0.2f / psEnc->sCmn.fs_kHz + 3.0f / psEncCtrl->pitchL[ k ]; + psEncCtrl->LF_MA_shp[ k ] = -1.0f + b; + psEncCtrl->LF_AR_shp[ k ] = 1.0f - b - b * strength; + } + Tilt = - HP_NOISE_COEF - + (1 - HP_NOISE_COEF) * HARM_HP_NOISE_COEF * psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f ); + } else { + b = 1.3f / psEnc->sCmn.fs_kHz; + psEncCtrl->LF_MA_shp[ 0 ] = -1.0f + b; + psEncCtrl->LF_AR_shp[ 0 ] = 1.0f - b - b * strength * 0.6f; + for( k = 1; k < psEnc->sCmn.nb_subfr; k++ ) { + psEncCtrl->LF_MA_shp[ k ] = psEncCtrl->LF_MA_shp[ 0 ]; + psEncCtrl->LF_AR_shp[ k ] = psEncCtrl->LF_AR_shp[ 0 ]; + } + Tilt = -HP_NOISE_COEF; + } + + /****************************/ + /* HARMONIC SHAPING CONTROL */ + /****************************/ + /* Control boosting of harmonic frequencies */ + HarmBoost = LOW_RATE_HARMONIC_BOOST * ( 1.0f - psEncCtrl->coding_quality ) * psEnc->LTPCorr; + + /* More harmonic boost for noisy input signals */ + HarmBoost += LOW_INPUT_QUALITY_HARMONIC_BOOST * ( 1.0f - psEncCtrl->input_quality ); + + if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) { + /* Harmonic noise shaping */ + HarmShapeGain = HARMONIC_SHAPING; + + /* More harmonic noise shaping for high bitrates or noisy input */ + HarmShapeGain += HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING * + ( 1.0f - ( 1.0f - psEncCtrl->coding_quality ) * psEncCtrl->input_quality ); + + /* Less harmonic noise shaping for less periodic signals */ + HarmShapeGain *= ( silk_float )sqrt( psEnc->LTPCorr ); + } else { + HarmShapeGain = 0.0f; + } + + /*************************/ + /* Smooth over subframes */ + /*************************/ + for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { + psShapeSt->HarmBoost_smth += SUBFR_SMTH_COEF * ( HarmBoost - psShapeSt->HarmBoost_smth ); + psEncCtrl->HarmBoost[ k ] = psShapeSt->HarmBoost_smth; + psShapeSt->HarmShapeGain_smth += SUBFR_SMTH_COEF * ( HarmShapeGain - psShapeSt->HarmShapeGain_smth ); + psEncCtrl->HarmShapeGain[ k ] = psShapeSt->HarmShapeGain_smth; + psShapeSt->Tilt_smth += SUBFR_SMTH_COEF * ( Tilt - psShapeSt->Tilt_smth ); + psEncCtrl->Tilt[ k ] = psShapeSt->Tilt_smth; + } +} diff --git a/src/opus-1.1/silk/float/pitch_analysis_core_FLP.c b/src/opus-1.1/silk/float/pitch_analysis_core_FLP.c new file mode 100644 index 00000000..e58f041b --- /dev/null +++ b/src/opus-1.1/silk/float/pitch_analysis_core_FLP.c @@ -0,0 +1,630 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/***************************************************************************** +* Pitch analyser function +******************************************************************************/ +#include "SigProc_FLP.h" +#include "SigProc_FIX.h" +#include "pitch_est_defines.h" +#include "pitch.h" + +#define SCRATCH_SIZE 22 + +/************************************************************/ +/* Internally used functions */ +/************************************************************/ +static void silk_P_Ana_calc_corr_st3( + silk_float cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */ + const silk_float frame[], /* I vector to correlate */ + opus_int start_lag, /* I start lag */ + opus_int sf_length, /* I sub frame length */ + opus_int nb_subfr, /* I number of subframes */ + opus_int complexity, /* I Complexity setting */ + int arch /* I Run-time architecture */ +); + +static void silk_P_Ana_calc_energy_st3( + silk_float energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */ + const silk_float frame[], /* I vector to correlate */ + opus_int start_lag, /* I start lag */ + opus_int sf_length, /* I sub frame length */ + opus_int nb_subfr, /* I number of subframes */ + opus_int complexity /* I Complexity setting */ +); + +/************************************************************/ +/* CORE PITCH ANALYSIS FUNCTION */ +/************************************************************/ +opus_int silk_pitch_analysis_core_FLP( /* O Voicing estimate: 0 voiced, 1 unvoiced */ + const silk_float *frame, /* I Signal of length PE_FRAME_LENGTH_MS*Fs_kHz */ + opus_int *pitch_out, /* O Pitch lag values [nb_subfr] */ + opus_int16 *lagIndex, /* O Lag Index */ + opus_int8 *contourIndex, /* O Pitch contour Index */ + silk_float *LTPCorr, /* I/O Normalized correlation; input: value from previous frame */ + opus_int prevLag, /* I Last lag of previous frame; set to zero is unvoiced */ + const silk_float search_thres1, /* I First stage threshold for lag candidates 0 - 1 */ + const silk_float search_thres2, /* I Final threshold for lag candidates 0 - 1 */ + const opus_int Fs_kHz, /* I sample frequency (kHz) */ + const opus_int complexity, /* I Complexity setting, 0-2, where 2 is highest */ + const opus_int nb_subfr, /* I Number of 5 ms subframes */ + int arch /* I Run-time architecture */ +) +{ + opus_int i, k, d, j; + silk_float frame_8kHz[ PE_MAX_FRAME_LENGTH_MS * 8 ]; + silk_float frame_4kHz[ PE_MAX_FRAME_LENGTH_MS * 4 ]; + opus_int16 frame_8_FIX[ PE_MAX_FRAME_LENGTH_MS * 8 ]; + opus_int16 frame_4_FIX[ PE_MAX_FRAME_LENGTH_MS * 4 ]; + opus_int32 filt_state[ 6 ]; + silk_float threshold, contour_bias; + silk_float C[ PE_MAX_NB_SUBFR][ (PE_MAX_LAG >> 1) + 5 ]; + opus_val32 xcorr[ PE_MAX_LAG_MS * 4 - PE_MIN_LAG_MS * 4 + 1 ]; + silk_float CC[ PE_NB_CBKS_STAGE2_EXT ]; + const silk_float *target_ptr, *basis_ptr; + double cross_corr, normalizer, energy, energy_tmp; + opus_int d_srch[ PE_D_SRCH_LENGTH ]; + opus_int16 d_comp[ (PE_MAX_LAG >> 1) + 5 ]; + opus_int length_d_srch, length_d_comp; + silk_float Cmax, CCmax, CCmax_b, CCmax_new_b, CCmax_new; + opus_int CBimax, CBimax_new, lag, start_lag, end_lag, lag_new; + opus_int cbk_size; + silk_float lag_log2, prevLag_log2, delta_lag_log2_sqr; + silk_float energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ]; + silk_float cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ]; + opus_int lag_counter; + opus_int frame_length, frame_length_8kHz, frame_length_4kHz; + opus_int sf_length, sf_length_8kHz, sf_length_4kHz; + opus_int min_lag, min_lag_8kHz, min_lag_4kHz; + opus_int max_lag, max_lag_8kHz, max_lag_4kHz; + opus_int nb_cbk_search; + const opus_int8 *Lag_CB_ptr; + + /* Check for valid sampling frequency */ + silk_assert( Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16 ); + + /* Check for valid complexity setting */ + silk_assert( complexity >= SILK_PE_MIN_COMPLEX ); + silk_assert( complexity <= SILK_PE_MAX_COMPLEX ); + + silk_assert( search_thres1 >= 0.0f && search_thres1 <= 1.0f ); + silk_assert( search_thres2 >= 0.0f && search_thres2 <= 1.0f ); + + /* Set up frame lengths max / min lag for the sampling frequency */ + frame_length = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * Fs_kHz; + frame_length_4kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 4; + frame_length_8kHz = ( PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS ) * 8; + sf_length = PE_SUBFR_LENGTH_MS * Fs_kHz; + sf_length_4kHz = PE_SUBFR_LENGTH_MS * 4; + sf_length_8kHz = PE_SUBFR_LENGTH_MS * 8; + min_lag = PE_MIN_LAG_MS * Fs_kHz; + min_lag_4kHz = PE_MIN_LAG_MS * 4; + min_lag_8kHz = PE_MIN_LAG_MS * 8; + max_lag = PE_MAX_LAG_MS * Fs_kHz - 1; + max_lag_4kHz = PE_MAX_LAG_MS * 4; + max_lag_8kHz = PE_MAX_LAG_MS * 8 - 1; + + /* Resample from input sampled at Fs_kHz to 8 kHz */ + if( Fs_kHz == 16 ) { + /* Resample to 16 -> 8 khz */ + opus_int16 frame_16_FIX[ 16 * PE_MAX_FRAME_LENGTH_MS ]; + silk_float2short_array( frame_16_FIX, frame, frame_length ); + silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) ); + silk_resampler_down2( filt_state, frame_8_FIX, frame_16_FIX, frame_length ); + silk_short2float_array( frame_8kHz, frame_8_FIX, frame_length_8kHz ); + } else if( Fs_kHz == 12 ) { + /* Resample to 12 -> 8 khz */ + opus_int16 frame_12_FIX[ 12 * PE_MAX_FRAME_LENGTH_MS ]; + silk_float2short_array( frame_12_FIX, frame, frame_length ); + silk_memset( filt_state, 0, 6 * sizeof( opus_int32 ) ); + silk_resampler_down2_3( filt_state, frame_8_FIX, frame_12_FIX, frame_length ); + silk_short2float_array( frame_8kHz, frame_8_FIX, frame_length_8kHz ); + } else { + silk_assert( Fs_kHz == 8 ); + silk_float2short_array( frame_8_FIX, frame, frame_length_8kHz ); + } + + /* Decimate again to 4 kHz */ + silk_memset( filt_state, 0, 2 * sizeof( opus_int32 ) ); + silk_resampler_down2( filt_state, frame_4_FIX, frame_8_FIX, frame_length_8kHz ); + silk_short2float_array( frame_4kHz, frame_4_FIX, frame_length_4kHz ); + + /* Low-pass filter */ + for( i = frame_length_4kHz - 1; i > 0; i-- ) { + frame_4kHz[ i ] += frame_4kHz[ i - 1 ]; + } + + /****************************************************************************** + * FIRST STAGE, operating in 4 khz + ******************************************************************************/ + silk_memset(C, 0, sizeof(silk_float) * nb_subfr * ((PE_MAX_LAG >> 1) + 5)); + target_ptr = &frame_4kHz[ silk_LSHIFT( sf_length_4kHz, 2 ) ]; + for( k = 0; k < nb_subfr >> 1; k++ ) { + /* Check that we are within range of the array */ + silk_assert( target_ptr >= frame_4kHz ); + silk_assert( target_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz ); + + basis_ptr = target_ptr - min_lag_4kHz; + + /* Check that we are within range of the array */ + silk_assert( basis_ptr >= frame_4kHz ); + silk_assert( basis_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz ); + + celt_pitch_xcorr( target_ptr, target_ptr-max_lag_4kHz, xcorr, sf_length_8kHz, max_lag_4kHz - min_lag_4kHz + 1, arch ); + + /* Calculate first vector products before loop */ + cross_corr = xcorr[ max_lag_4kHz - min_lag_4kHz ]; + normalizer = silk_energy_FLP( target_ptr, sf_length_8kHz ) + + silk_energy_FLP( basis_ptr, sf_length_8kHz ) + + sf_length_8kHz * 4000.0f; + + C[ 0 ][ min_lag_4kHz ] += (silk_float)( 2 * cross_corr / normalizer ); + + /* From now on normalizer is computed recursively */ + for( d = min_lag_4kHz + 1; d <= max_lag_4kHz; d++ ) { + basis_ptr--; + + /* Check that we are within range of the array */ + silk_assert( basis_ptr >= frame_4kHz ); + silk_assert( basis_ptr + sf_length_8kHz <= frame_4kHz + frame_length_4kHz ); + + cross_corr = xcorr[ max_lag_4kHz - d ]; + + /* Add contribution of new sample and remove contribution from oldest sample */ + normalizer += + basis_ptr[ 0 ] * (double)basis_ptr[ 0 ] - + basis_ptr[ sf_length_8kHz ] * (double)basis_ptr[ sf_length_8kHz ]; + C[ 0 ][ d ] += (silk_float)( 2 * cross_corr / normalizer ); + } + /* Update target pointer */ + target_ptr += sf_length_8kHz; + } + + /* Apply short-lag bias */ + for( i = max_lag_4kHz; i >= min_lag_4kHz; i-- ) { + C[ 0 ][ i ] -= C[ 0 ][ i ] * i / 4096.0f; + } + + /* Sort */ + length_d_srch = 4 + 2 * complexity; + silk_assert( 3 * length_d_srch <= PE_D_SRCH_LENGTH ); + silk_insertion_sort_decreasing_FLP( &C[ 0 ][ min_lag_4kHz ], d_srch, max_lag_4kHz - min_lag_4kHz + 1, length_d_srch ); + + /* Escape if correlation is very low already here */ + Cmax = C[ 0 ][ min_lag_4kHz ]; + if( Cmax < 0.2f ) { + silk_memset( pitch_out, 0, nb_subfr * sizeof( opus_int ) ); + *LTPCorr = 0.0f; + *lagIndex = 0; + *contourIndex = 0; + return 1; + } + + threshold = search_thres1 * Cmax; + for( i = 0; i < length_d_srch; i++ ) { + /* Convert to 8 kHz indices for the sorted correlation that exceeds the threshold */ + if( C[ 0 ][ min_lag_4kHz + i ] > threshold ) { + d_srch[ i ] = silk_LSHIFT( d_srch[ i ] + min_lag_4kHz, 1 ); + } else { + length_d_srch = i; + break; + } + } + silk_assert( length_d_srch > 0 ); + + for( i = min_lag_8kHz - 5; i < max_lag_8kHz + 5; i++ ) { + d_comp[ i ] = 0; + } + for( i = 0; i < length_d_srch; i++ ) { + d_comp[ d_srch[ i ] ] = 1; + } + + /* Convolution */ + for( i = max_lag_8kHz + 3; i >= min_lag_8kHz; i-- ) { + d_comp[ i ] += d_comp[ i - 1 ] + d_comp[ i - 2 ]; + } + + length_d_srch = 0; + for( i = min_lag_8kHz; i < max_lag_8kHz + 1; i++ ) { + if( d_comp[ i + 1 ] > 0 ) { + d_srch[ length_d_srch ] = i; + length_d_srch++; + } + } + + /* Convolution */ + for( i = max_lag_8kHz + 3; i >= min_lag_8kHz; i-- ) { + d_comp[ i ] += d_comp[ i - 1 ] + d_comp[ i - 2 ] + d_comp[ i - 3 ]; + } + + length_d_comp = 0; + for( i = min_lag_8kHz; i < max_lag_8kHz + 4; i++ ) { + if( d_comp[ i ] > 0 ) { + d_comp[ length_d_comp ] = (opus_int16)( i - 2 ); + length_d_comp++; + } + } + + /********************************************************************************** + ** SECOND STAGE, operating at 8 kHz, on lag sections with high correlation + *************************************************************************************/ + /********************************************************************************* + * Find energy of each subframe projected onto its history, for a range of delays + *********************************************************************************/ + silk_memset( C, 0, PE_MAX_NB_SUBFR*((PE_MAX_LAG >> 1) + 5) * sizeof(silk_float)); + + if( Fs_kHz == 8 ) { + target_ptr = &frame[ PE_LTP_MEM_LENGTH_MS * 8 ]; + } else { + target_ptr = &frame_8kHz[ PE_LTP_MEM_LENGTH_MS * 8 ]; + } + for( k = 0; k < nb_subfr; k++ ) { + energy_tmp = silk_energy_FLP( target_ptr, sf_length_8kHz ) + 1.0; + for( j = 0; j < length_d_comp; j++ ) { + d = d_comp[ j ]; + basis_ptr = target_ptr - d; + cross_corr = silk_inner_product_FLP( basis_ptr, target_ptr, sf_length_8kHz ); + if( cross_corr > 0.0f ) { + energy = silk_energy_FLP( basis_ptr, sf_length_8kHz ); + C[ k ][ d ] = (silk_float)( 2 * cross_corr / ( energy + energy_tmp ) ); + } else { + C[ k ][ d ] = 0.0f; + } + } + target_ptr += sf_length_8kHz; + } + + /* search over lag range and lags codebook */ + /* scale factor for lag codebook, as a function of center lag */ + + CCmax = 0.0f; /* This value doesn't matter */ + CCmax_b = -1000.0f; + + CBimax = 0; /* To avoid returning undefined lag values */ + lag = -1; /* To check if lag with strong enough correlation has been found */ + + if( prevLag > 0 ) { + if( Fs_kHz == 12 ) { + prevLag = silk_LSHIFT( prevLag, 1 ) / 3; + } else if( Fs_kHz == 16 ) { + prevLag = silk_RSHIFT( prevLag, 1 ); + } + prevLag_log2 = silk_log2( (silk_float)prevLag ); + } else { + prevLag_log2 = 0; + } + + /* Set up stage 2 codebook based on number of subframes */ + if( nb_subfr == PE_MAX_NB_SUBFR ) { + cbk_size = PE_NB_CBKS_STAGE2_EXT; + Lag_CB_ptr = &silk_CB_lags_stage2[ 0 ][ 0 ]; + if( Fs_kHz == 8 && complexity > SILK_PE_MIN_COMPLEX ) { + /* If input is 8 khz use a larger codebook here because it is last stage */ + nb_cbk_search = PE_NB_CBKS_STAGE2_EXT; + } else { + nb_cbk_search = PE_NB_CBKS_STAGE2; + } + } else { + cbk_size = PE_NB_CBKS_STAGE2_10MS; + Lag_CB_ptr = &silk_CB_lags_stage2_10_ms[ 0 ][ 0 ]; + nb_cbk_search = PE_NB_CBKS_STAGE2_10MS; + } + + for( k = 0; k < length_d_srch; k++ ) { + d = d_srch[ k ]; + for( j = 0; j < nb_cbk_search; j++ ) { + CC[j] = 0.0f; + for( i = 0; i < nb_subfr; i++ ) { + /* Try all codebooks */ + CC[ j ] += C[ i ][ d + matrix_ptr( Lag_CB_ptr, i, j, cbk_size )]; + } + } + /* Find best codebook */ + CCmax_new = -1000.0f; + CBimax_new = 0; + for( i = 0; i < nb_cbk_search; i++ ) { + if( CC[ i ] > CCmax_new ) { + CCmax_new = CC[ i ]; + CBimax_new = i; + } + } + + /* Bias towards shorter lags */ + lag_log2 = silk_log2( (silk_float)d ); + CCmax_new_b = CCmax_new - PE_SHORTLAG_BIAS * nb_subfr * lag_log2; + + /* Bias towards previous lag */ + if( prevLag > 0 ) { + delta_lag_log2_sqr = lag_log2 - prevLag_log2; + delta_lag_log2_sqr *= delta_lag_log2_sqr; + CCmax_new_b -= PE_PREVLAG_BIAS * nb_subfr * (*LTPCorr) * delta_lag_log2_sqr / ( delta_lag_log2_sqr + 0.5f ); + } + + if( CCmax_new_b > CCmax_b && /* Find maximum biased correlation */ + CCmax_new > nb_subfr * search_thres2 /* Correlation needs to be high enough to be voiced */ + ) { + CCmax_b = CCmax_new_b; + CCmax = CCmax_new; + lag = d; + CBimax = CBimax_new; + } + } + + if( lag == -1 ) { + /* No suitable candidate found */ + silk_memset( pitch_out, 0, PE_MAX_NB_SUBFR * sizeof(opus_int) ); + *LTPCorr = 0.0f; + *lagIndex = 0; + *contourIndex = 0; + return 1; + } + + /* Output normalized correlation */ + *LTPCorr = (silk_float)( CCmax / nb_subfr ); + silk_assert( *LTPCorr >= 0.0f ); + + if( Fs_kHz > 8 ) { + /* Search in original signal */ + + /* Compensate for decimation */ + silk_assert( lag == silk_SAT16( lag ) ); + if( Fs_kHz == 12 ) { + lag = silk_RSHIFT_ROUND( silk_SMULBB( lag, 3 ), 1 ); + } else { /* Fs_kHz == 16 */ + lag = silk_LSHIFT( lag, 1 ); + } + + lag = silk_LIMIT_int( lag, min_lag, max_lag ); + start_lag = silk_max_int( lag - 2, min_lag ); + end_lag = silk_min_int( lag + 2, max_lag ); + lag_new = lag; /* to avoid undefined lag */ + CBimax = 0; /* to avoid undefined lag */ + + CCmax = -1000.0f; + + /* Calculate the correlations and energies needed in stage 3 */ + silk_P_Ana_calc_corr_st3( cross_corr_st3, frame, start_lag, sf_length, nb_subfr, complexity, arch ); + silk_P_Ana_calc_energy_st3( energies_st3, frame, start_lag, sf_length, nb_subfr, complexity ); + + lag_counter = 0; + silk_assert( lag == silk_SAT16( lag ) ); + contour_bias = PE_FLATCONTOUR_BIAS / lag; + + /* Set up cbk parameters according to complexity setting and frame length */ + if( nb_subfr == PE_MAX_NB_SUBFR ) { + nb_cbk_search = (opus_int)silk_nb_cbk_searchs_stage3[ complexity ]; + cbk_size = PE_NB_CBKS_STAGE3_MAX; + Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ]; + } else { + nb_cbk_search = PE_NB_CBKS_STAGE3_10MS; + cbk_size = PE_NB_CBKS_STAGE3_10MS; + Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ]; + } + + target_ptr = &frame[ PE_LTP_MEM_LENGTH_MS * Fs_kHz ]; + energy_tmp = silk_energy_FLP( target_ptr, nb_subfr * sf_length ) + 1.0; + for( d = start_lag; d <= end_lag; d++ ) { + for( j = 0; j < nb_cbk_search; j++ ) { + cross_corr = 0.0; + energy = energy_tmp; + for( k = 0; k < nb_subfr; k++ ) { + cross_corr += cross_corr_st3[ k ][ j ][ lag_counter ]; + energy += energies_st3[ k ][ j ][ lag_counter ]; + } + if( cross_corr > 0.0 ) { + CCmax_new = (silk_float)( 2 * cross_corr / energy ); + /* Reduce depending on flatness of contour */ + CCmax_new *= 1.0f - contour_bias * j; + } else { + CCmax_new = 0.0f; + } + + if( CCmax_new > CCmax && ( d + (opus_int)silk_CB_lags_stage3[ 0 ][ j ] ) <= max_lag ) { + CCmax = CCmax_new; + lag_new = d; + CBimax = j; + } + } + lag_counter++; + } + + for( k = 0; k < nb_subfr; k++ ) { + pitch_out[ k ] = lag_new + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size ); + pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], min_lag, PE_MAX_LAG_MS * Fs_kHz ); + } + *lagIndex = (opus_int16)( lag_new - min_lag ); + *contourIndex = (opus_int8)CBimax; + } else { /* Fs_kHz == 8 */ + /* Save Lags */ + for( k = 0; k < nb_subfr; k++ ) { + pitch_out[ k ] = lag + matrix_ptr( Lag_CB_ptr, k, CBimax, cbk_size ); + pitch_out[ k ] = silk_LIMIT( pitch_out[ k ], min_lag_8kHz, PE_MAX_LAG_MS * 8 ); + } + *lagIndex = (opus_int16)( lag - min_lag_8kHz ); + *contourIndex = (opus_int8)CBimax; + } + silk_assert( *lagIndex >= 0 ); + /* return as voiced */ + return 0; +} + +/*********************************************************************** + * Calculates the correlations used in stage 3 search. In order to cover + * the whole lag codebook for all the searched offset lags (lag +- 2), + * the following correlations are needed in each sub frame: + * + * sf1: lag range [-8,...,7] total 16 correlations + * sf2: lag range [-4,...,4] total 9 correlations + * sf3: lag range [-3,....4] total 8 correltions + * sf4: lag range [-6,....8] total 15 correlations + * + * In total 48 correlations. The direct implementation computed in worst + * case 4*12*5 = 240 correlations, but more likely around 120. + ***********************************************************************/ +static void silk_P_Ana_calc_corr_st3( + silk_float cross_corr_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */ + const silk_float frame[], /* I vector to correlate */ + opus_int start_lag, /* I start lag */ + opus_int sf_length, /* I sub frame length */ + opus_int nb_subfr, /* I number of subframes */ + opus_int complexity, /* I Complexity setting */ + int arch /* I Run-time architecture */ +) +{ + const silk_float *target_ptr; + opus_int i, j, k, lag_counter, lag_low, lag_high; + opus_int nb_cbk_search, delta, idx, cbk_size; + silk_float scratch_mem[ SCRATCH_SIZE ]; + opus_val32 xcorr[ SCRATCH_SIZE ]; + const opus_int8 *Lag_range_ptr, *Lag_CB_ptr; + + silk_assert( complexity >= SILK_PE_MIN_COMPLEX ); + silk_assert( complexity <= SILK_PE_MAX_COMPLEX ); + + if( nb_subfr == PE_MAX_NB_SUBFR ) { + Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ]; + Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ]; + nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ]; + cbk_size = PE_NB_CBKS_STAGE3_MAX; + } else { + silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1); + Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ]; + Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ]; + nb_cbk_search = PE_NB_CBKS_STAGE3_10MS; + cbk_size = PE_NB_CBKS_STAGE3_10MS; + } + + target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ]; /* Pointer to middle of frame */ + for( k = 0; k < nb_subfr; k++ ) { + lag_counter = 0; + + /* Calculate the correlations for each subframe */ + lag_low = matrix_ptr( Lag_range_ptr, k, 0, 2 ); + lag_high = matrix_ptr( Lag_range_ptr, k, 1, 2 ); + silk_assert(lag_high-lag_low+1 <= SCRATCH_SIZE); + celt_pitch_xcorr( target_ptr, target_ptr - start_lag - lag_high, xcorr, sf_length, lag_high - lag_low + 1, arch ); + for( j = lag_low; j <= lag_high; j++ ) { + silk_assert( lag_counter < SCRATCH_SIZE ); + scratch_mem[ lag_counter ] = xcorr[ lag_high - j ]; + lag_counter++; + } + + delta = matrix_ptr( Lag_range_ptr, k, 0, 2 ); + for( i = 0; i < nb_cbk_search; i++ ) { + /* Fill out the 3 dim array that stores the correlations for */ + /* each code_book vector for each start lag */ + idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta; + for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) { + silk_assert( idx + j < SCRATCH_SIZE ); + silk_assert( idx + j < lag_counter ); + cross_corr_st3[ k ][ i ][ j ] = scratch_mem[ idx + j ]; + } + } + target_ptr += sf_length; + } +} + +/********************************************************************/ +/* Calculate the energies for first two subframes. The energies are */ +/* calculated recursively. */ +/********************************************************************/ +static void silk_P_Ana_calc_energy_st3( + silk_float energies_st3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ][ PE_NB_STAGE3_LAGS ], /* O 3 DIM correlation array */ + const silk_float frame[], /* I vector to correlate */ + opus_int start_lag, /* I start lag */ + opus_int sf_length, /* I sub frame length */ + opus_int nb_subfr, /* I number of subframes */ + opus_int complexity /* I Complexity setting */ +) +{ + const silk_float *target_ptr, *basis_ptr; + double energy; + opus_int k, i, j, lag_counter; + opus_int nb_cbk_search, delta, idx, cbk_size, lag_diff; + silk_float scratch_mem[ SCRATCH_SIZE ]; + const opus_int8 *Lag_range_ptr, *Lag_CB_ptr; + + silk_assert( complexity >= SILK_PE_MIN_COMPLEX ); + silk_assert( complexity <= SILK_PE_MAX_COMPLEX ); + + if( nb_subfr == PE_MAX_NB_SUBFR ) { + Lag_range_ptr = &silk_Lag_range_stage3[ complexity ][ 0 ][ 0 ]; + Lag_CB_ptr = &silk_CB_lags_stage3[ 0 ][ 0 ]; + nb_cbk_search = silk_nb_cbk_searchs_stage3[ complexity ]; + cbk_size = PE_NB_CBKS_STAGE3_MAX; + } else { + silk_assert( nb_subfr == PE_MAX_NB_SUBFR >> 1); + Lag_range_ptr = &silk_Lag_range_stage3_10_ms[ 0 ][ 0 ]; + Lag_CB_ptr = &silk_CB_lags_stage3_10_ms[ 0 ][ 0 ]; + nb_cbk_search = PE_NB_CBKS_STAGE3_10MS; + cbk_size = PE_NB_CBKS_STAGE3_10MS; + } + + target_ptr = &frame[ silk_LSHIFT( sf_length, 2 ) ]; + for( k = 0; k < nb_subfr; k++ ) { + lag_counter = 0; + + /* Calculate the energy for first lag */ + basis_ptr = target_ptr - ( start_lag + matrix_ptr( Lag_range_ptr, k, 0, 2 ) ); + energy = silk_energy_FLP( basis_ptr, sf_length ) + 1e-3; + silk_assert( energy >= 0.0 ); + scratch_mem[lag_counter] = (silk_float)energy; + lag_counter++; + + lag_diff = ( matrix_ptr( Lag_range_ptr, k, 1, 2 ) - matrix_ptr( Lag_range_ptr, k, 0, 2 ) + 1 ); + for( i = 1; i < lag_diff; i++ ) { + /* remove part outside new window */ + energy -= basis_ptr[sf_length - i] * (double)basis_ptr[sf_length - i]; + silk_assert( energy >= 0.0 ); + + /* add part that comes into window */ + energy += basis_ptr[ -i ] * (double)basis_ptr[ -i ]; + silk_assert( energy >= 0.0 ); + silk_assert( lag_counter < SCRATCH_SIZE ); + scratch_mem[lag_counter] = (silk_float)energy; + lag_counter++; + } + + delta = matrix_ptr( Lag_range_ptr, k, 0, 2 ); + for( i = 0; i < nb_cbk_search; i++ ) { + /* Fill out the 3 dim array that stores the correlations for */ + /* each code_book vector for each start lag */ + idx = matrix_ptr( Lag_CB_ptr, k, i, cbk_size ) - delta; + for( j = 0; j < PE_NB_STAGE3_LAGS; j++ ) { + silk_assert( idx + j < SCRATCH_SIZE ); + silk_assert( idx + j < lag_counter ); + energies_st3[ k ][ i ][ j ] = scratch_mem[ idx + j ]; + silk_assert( energies_st3[ k ][ i ][ j ] >= 0.0f ); + } + } + target_ptr += sf_length; + } +} diff --git a/src/opus-1.1/silk/float/prefilter_FLP.c b/src/opus-1.1/silk/float/prefilter_FLP.c new file mode 100644 index 00000000..8bc32fb4 --- /dev/null +++ b/src/opus-1.1/silk/float/prefilter_FLP.c @@ -0,0 +1,206 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main_FLP.h" +#include "tuning_parameters.h" + +/* +* Prefilter for finding Quantizer input signal +*/ +static OPUS_INLINE void silk_prefilt_FLP( + silk_prefilter_state_FLP *P, /* I/O state */ + silk_float st_res[], /* I */ + silk_float xw[], /* O */ + silk_float *HarmShapeFIR, /* I */ + silk_float Tilt, /* I */ + silk_float LF_MA_shp, /* I */ + silk_float LF_AR_shp, /* I */ + opus_int lag, /* I */ + opus_int length /* I */ +); + +static void silk_warped_LPC_analysis_filter_FLP( + silk_float state[], /* I/O State [order + 1] */ + silk_float res[], /* O Residual signal [length] */ + const silk_float coef[], /* I Coefficients [order] */ + const silk_float input[], /* I Input signal [length] */ + const silk_float lambda, /* I Warping factor */ + const opus_int length, /* I Length of input signal */ + const opus_int order /* I Filter order (even) */ +) +{ + opus_int n, i; + silk_float acc, tmp1, tmp2; + + /* Order must be even */ + silk_assert( ( order & 1 ) == 0 ); + + for( n = 0; n < length; n++ ) { + /* Output of lowpass section */ + tmp2 = state[ 0 ] + lambda * state[ 1 ]; + state[ 0 ] = input[ n ]; + /* Output of allpass section */ + tmp1 = state[ 1 ] + lambda * ( state[ 2 ] - tmp2 ); + state[ 1 ] = tmp2; + acc = coef[ 0 ] * tmp2; + /* Loop over allpass sections */ + for( i = 2; i < order; i += 2 ) { + /* Output of allpass section */ + tmp2 = state[ i ] + lambda * ( state[ i + 1 ] - tmp1 ); + state[ i ] = tmp1; + acc += coef[ i - 1 ] * tmp1; + /* Output of allpass section */ + tmp1 = state[ i + 1 ] + lambda * ( state[ i + 2 ] - tmp2 ); + state[ i + 1 ] = tmp2; + acc += coef[ i ] * tmp2; + } + state[ order ] = tmp1; + acc += coef[ order - 1 ] * tmp1; + res[ n ] = input[ n ] - acc; + } +} + +/* +* silk_prefilter. Main prefilter function +*/ +void silk_prefilter_FLP( + silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ + const silk_encoder_control_FLP *psEncCtrl, /* I Encoder control FLP */ + silk_float xw[], /* O Weighted signal */ + const silk_float x[] /* I Speech signal */ +) +{ + silk_prefilter_state_FLP *P = &psEnc->sPrefilt; + opus_int j, k, lag; + silk_float HarmShapeGain, Tilt, LF_MA_shp, LF_AR_shp; + silk_float B[ 2 ]; + const silk_float *AR1_shp; + const silk_float *px; + silk_float *pxw; + silk_float HarmShapeFIR[ 3 ]; + silk_float st_res[ MAX_SUB_FRAME_LENGTH + MAX_LPC_ORDER ]; + + /* Set up pointers */ + px = x; + pxw = xw; + lag = P->lagPrev; + for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { + /* Update Variables that change per sub frame */ + if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { + lag = psEncCtrl->pitchL[ k ]; + } + + /* Noise shape parameters */ + HarmShapeGain = psEncCtrl->HarmShapeGain[ k ] * ( 1.0f - psEncCtrl->HarmBoost[ k ] ); + HarmShapeFIR[ 0 ] = 0.25f * HarmShapeGain; + HarmShapeFIR[ 1 ] = 32767.0f / 65536.0f * HarmShapeGain; + HarmShapeFIR[ 2 ] = 0.25f * HarmShapeGain; + Tilt = psEncCtrl->Tilt[ k ]; + LF_MA_shp = psEncCtrl->LF_MA_shp[ k ]; + LF_AR_shp = psEncCtrl->LF_AR_shp[ k ]; + AR1_shp = &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ]; + + /* Short term FIR filtering */ + silk_warped_LPC_analysis_filter_FLP( P->sAR_shp, st_res, AR1_shp, px, + (silk_float)psEnc->sCmn.warping_Q16 / 65536.0f, psEnc->sCmn.subfr_length, psEnc->sCmn.shapingLPCOrder ); + + /* Reduce (mainly) low frequencies during harmonic emphasis */ + B[ 0 ] = psEncCtrl->GainsPre[ k ]; + B[ 1 ] = -psEncCtrl->GainsPre[ k ] * + ( psEncCtrl->HarmBoost[ k ] * HarmShapeGain + INPUT_TILT + psEncCtrl->coding_quality * HIGH_RATE_INPUT_TILT ); + pxw[ 0 ] = B[ 0 ] * st_res[ 0 ] + B[ 1 ] * P->sHarmHP; + for( j = 1; j < psEnc->sCmn.subfr_length; j++ ) { + pxw[ j ] = B[ 0 ] * st_res[ j ] + B[ 1 ] * st_res[ j - 1 ]; + } + P->sHarmHP = st_res[ psEnc->sCmn.subfr_length - 1 ]; + + silk_prefilt_FLP( P, pxw, pxw, HarmShapeFIR, Tilt, LF_MA_shp, LF_AR_shp, lag, psEnc->sCmn.subfr_length ); + + px += psEnc->sCmn.subfr_length; + pxw += psEnc->sCmn.subfr_length; + } + P->lagPrev = psEncCtrl->pitchL[ psEnc->sCmn.nb_subfr - 1 ]; +} + +/* +* Prefilter for finding Quantizer input signal +*/ +static OPUS_INLINE void silk_prefilt_FLP( + silk_prefilter_state_FLP *P, /* I/O state */ + silk_float st_res[], /* I */ + silk_float xw[], /* O */ + silk_float *HarmShapeFIR, /* I */ + silk_float Tilt, /* I */ + silk_float LF_MA_shp, /* I */ + silk_float LF_AR_shp, /* I */ + opus_int lag, /* I */ + opus_int length /* I */ +) +{ + opus_int i; + opus_int idx, LTP_shp_buf_idx; + silk_float n_Tilt, n_LF, n_LTP; + silk_float sLF_AR_shp, sLF_MA_shp; + silk_float *LTP_shp_buf; + + /* To speed up use temp variables instead of using the struct */ + LTP_shp_buf = P->sLTP_shp; + LTP_shp_buf_idx = P->sLTP_shp_buf_idx; + sLF_AR_shp = P->sLF_AR_shp; + sLF_MA_shp = P->sLF_MA_shp; + + for( i = 0; i < length; i++ ) { + if( lag > 0 ) { + silk_assert( HARM_SHAPE_FIR_TAPS == 3 ); + idx = lag + LTP_shp_buf_idx; + n_LTP = LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 - 1) & LTP_MASK ] * HarmShapeFIR[ 0 ]; + n_LTP += LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 ) & LTP_MASK ] * HarmShapeFIR[ 1 ]; + n_LTP += LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 + 1) & LTP_MASK ] * HarmShapeFIR[ 2 ]; + } else { + n_LTP = 0; + } + + n_Tilt = sLF_AR_shp * Tilt; + n_LF = sLF_AR_shp * LF_AR_shp + sLF_MA_shp * LF_MA_shp; + + sLF_AR_shp = st_res[ i ] - n_Tilt; + sLF_MA_shp = sLF_AR_shp - n_LF; + + LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK; + LTP_shp_buf[ LTP_shp_buf_idx ] = sLF_MA_shp; + + xw[ i ] = sLF_MA_shp - n_LTP; + } + /* Copy temp variable back to state */ + P->sLF_AR_shp = sLF_AR_shp; + P->sLF_MA_shp = sLF_MA_shp; + P->sLTP_shp_buf_idx = LTP_shp_buf_idx; +} diff --git a/src/opus-1.1/silk/float/process_gains_FLP.c b/src/opus-1.1/silk/float/process_gains_FLP.c new file mode 100644 index 00000000..c0da0dae --- /dev/null +++ b/src/opus-1.1/silk/float/process_gains_FLP.c @@ -0,0 +1,103 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main_FLP.h" +#include "tuning_parameters.h" + +/* Processing of gains */ +void silk_process_gains_FLP( + silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ + silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ + opus_int condCoding /* I The type of conditional coding to use */ +) +{ + silk_shape_state_FLP *psShapeSt = &psEnc->sShape; + opus_int k; + opus_int32 pGains_Q16[ MAX_NB_SUBFR ]; + silk_float s, InvMaxSqrVal, gain, quant_offset; + + /* Gain reduction when LTP coding gain is high */ + if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { + s = 1.0f - 0.5f * silk_sigmoid( 0.25f * ( psEncCtrl->LTPredCodGain - 12.0f ) ); + for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { + psEncCtrl->Gains[ k ] *= s; + } + } + + /* Limit the quantized signal */ + InvMaxSqrVal = ( silk_float )( pow( 2.0f, 0.33f * ( 21.0f - psEnc->sCmn.SNR_dB_Q7 * ( 1 / 128.0f ) ) ) / psEnc->sCmn.subfr_length ); + + for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { + /* Soft limit on ratio residual energy and squared gains */ + gain = psEncCtrl->Gains[ k ]; + gain = ( silk_float )sqrt( gain * gain + psEncCtrl->ResNrg[ k ] * InvMaxSqrVal ); + psEncCtrl->Gains[ k ] = silk_min_float( gain, 32767.0f ); + } + + /* Prepare gains for noise shaping quantization */ + for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { + pGains_Q16[ k ] = (opus_int32)( psEncCtrl->Gains[ k ] * 65536.0f ); + } + + /* Save unquantized gains and gain Index */ + silk_memcpy( psEncCtrl->GainsUnq_Q16, pGains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) ); + psEncCtrl->lastGainIndexPrev = psShapeSt->LastGainIndex; + + /* Quantize gains */ + silk_gains_quant( psEnc->sCmn.indices.GainsIndices, pGains_Q16, + &psShapeSt->LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); + + /* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */ + for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { + psEncCtrl->Gains[ k ] = pGains_Q16[ k ] / 65536.0f; + } + + /* Set quantizer offset for voiced signals. Larger offset when LTP coding gain is low or tilt is high (ie low-pass) */ + if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { + if( psEncCtrl->LTPredCodGain + psEnc->sCmn.input_tilt_Q15 * ( 1.0f / 32768.0f ) > 1.0f ) { + psEnc->sCmn.indices.quantOffsetType = 0; + } else { + psEnc->sCmn.indices.quantOffsetType = 1; + } + } + + /* Quantizer boundary adjustment */ + quant_offset = silk_Quantization_Offsets_Q10[ psEnc->sCmn.indices.signalType >> 1 ][ psEnc->sCmn.indices.quantOffsetType ] / 1024.0f; + psEncCtrl->Lambda = LAMBDA_OFFSET + + LAMBDA_DELAYED_DECISIONS * psEnc->sCmn.nStatesDelayedDecision + + LAMBDA_SPEECH_ACT * psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f ) + + LAMBDA_INPUT_QUALITY * psEncCtrl->input_quality + + LAMBDA_CODING_QUALITY * psEncCtrl->coding_quality + + LAMBDA_QUANT_OFFSET * quant_offset; + + silk_assert( psEncCtrl->Lambda > 0.0f ); + silk_assert( psEncCtrl->Lambda < 2.0f ); +} diff --git a/src/opus-1.1/silk/float/regularize_correlations_FLP.c b/src/opus-1.1/silk/float/regularize_correlations_FLP.c new file mode 100644 index 00000000..df461260 --- /dev/null +++ b/src/opus-1.1/silk/float/regularize_correlations_FLP.c @@ -0,0 +1,48 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main_FLP.h" + +/* Add noise to matrix diagonal */ +void silk_regularize_correlations_FLP( + silk_float *XX, /* I/O Correlation matrices */ + silk_float *xx, /* I/O Correlation values */ + const silk_float noise, /* I Noise energy to add */ + const opus_int D /* I Dimension of XX */ +) +{ + opus_int i; + + for( i = 0; i < D; i++ ) { + matrix_ptr( &XX[ 0 ], i, i, D ) += noise; + } + xx[ 0 ] += noise; +} diff --git a/src/opus-1.1/silk/float/residual_energy_FLP.c b/src/opus-1.1/silk/float/residual_energy_FLP.c new file mode 100644 index 00000000..b2e03a86 --- /dev/null +++ b/src/opus-1.1/silk/float/residual_energy_FLP.c @@ -0,0 +1,117 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main_FLP.h" + +#define MAX_ITERATIONS_RESIDUAL_NRG 10 +#define REGULARIZATION_FACTOR 1e-8f + +/* Residual energy: nrg = wxx - 2 * wXx * c + c' * wXX * c */ +silk_float silk_residual_energy_covar_FLP( /* O Weighted residual energy */ + const silk_float *c, /* I Filter coefficients */ + silk_float *wXX, /* I/O Weighted correlation matrix, reg. out */ + const silk_float *wXx, /* I Weighted correlation vector */ + const silk_float wxx, /* I Weighted correlation value */ + const opus_int D /* I Dimension */ +) +{ + opus_int i, j, k; + silk_float tmp, nrg = 0.0f, regularization; + + /* Safety checks */ + silk_assert( D >= 0 ); + + regularization = REGULARIZATION_FACTOR * ( wXX[ 0 ] + wXX[ D * D - 1 ] ); + for( k = 0; k < MAX_ITERATIONS_RESIDUAL_NRG; k++ ) { + nrg = wxx; + + tmp = 0.0f; + for( i = 0; i < D; i++ ) { + tmp += wXx[ i ] * c[ i ]; + } + nrg -= 2.0f * tmp; + + /* compute c' * wXX * c, assuming wXX is symmetric */ + for( i = 0; i < D; i++ ) { + tmp = 0.0f; + for( j = i + 1; j < D; j++ ) { + tmp += matrix_c_ptr( wXX, i, j, D ) * c[ j ]; + } + nrg += c[ i ] * ( 2.0f * tmp + matrix_c_ptr( wXX, i, i, D ) * c[ i ] ); + } + if( nrg > 0 ) { + break; + } else { + /* Add white noise */ + for( i = 0; i < D; i++ ) { + matrix_c_ptr( wXX, i, i, D ) += regularization; + } + /* Increase noise for next run */ + regularization *= 2.0f; + } + } + if( k == MAX_ITERATIONS_RESIDUAL_NRG ) { + silk_assert( nrg == 0 ); + nrg = 1.0f; + } + + return nrg; +} + +/* Calculates residual energies of input subframes where all subframes have LPC_order */ +/* of preceding samples */ +void silk_residual_energy_FLP( + silk_float nrgs[ MAX_NB_SUBFR ], /* O Residual energy per subframe */ + const silk_float x[], /* I Input signal */ + silk_float a[ 2 ][ MAX_LPC_ORDER ], /* I AR coefs for each frame half */ + const silk_float gains[], /* I Quantization gains */ + const opus_int subfr_length, /* I Subframe length */ + const opus_int nb_subfr, /* I number of subframes */ + const opus_int LPC_order /* I LPC order */ +) +{ + opus_int shift; + silk_float *LPC_res_ptr, LPC_res[ ( MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ) / 2 ]; + + LPC_res_ptr = LPC_res + LPC_order; + shift = LPC_order + subfr_length; + + /* Filter input to create the LPC residual for each frame half, and measure subframe energies */ + silk_LPC_analysis_filter_FLP( LPC_res, a[ 0 ], x + 0 * shift, 2 * shift, LPC_order ); + nrgs[ 0 ] = ( silk_float )( gains[ 0 ] * gains[ 0 ] * silk_energy_FLP( LPC_res_ptr + 0 * shift, subfr_length ) ); + nrgs[ 1 ] = ( silk_float )( gains[ 1 ] * gains[ 1 ] * silk_energy_FLP( LPC_res_ptr + 1 * shift, subfr_length ) ); + + if( nb_subfr == MAX_NB_SUBFR ) { + silk_LPC_analysis_filter_FLP( LPC_res, a[ 1 ], x + 2 * shift, 2 * shift, LPC_order ); + nrgs[ 2 ] = ( silk_float )( gains[ 2 ] * gains[ 2 ] * silk_energy_FLP( LPC_res_ptr + 0 * shift, subfr_length ) ); + nrgs[ 3 ] = ( silk_float )( gains[ 3 ] * gains[ 3 ] * silk_energy_FLP( LPC_res_ptr + 1 * shift, subfr_length ) ); + } +} diff --git a/src/opus-1.1/silk/float/scale_copy_vector_FLP.c b/src/opus-1.1/silk/float/scale_copy_vector_FLP.c new file mode 100644 index 00000000..20db32b3 --- /dev/null +++ b/src/opus-1.1/silk/float/scale_copy_vector_FLP.c @@ -0,0 +1,57 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SigProc_FLP.h" + +/* copy and multiply a vector by a constant */ +void silk_scale_copy_vector_FLP( + silk_float *data_out, + const silk_float *data_in, + silk_float gain, + opus_int dataSize +) +{ + opus_int i, dataSize4; + + /* 4x unrolled loop */ + dataSize4 = dataSize & 0xFFFC; + for( i = 0; i < dataSize4; i += 4 ) { + data_out[ i + 0 ] = gain * data_in[ i + 0 ]; + data_out[ i + 1 ] = gain * data_in[ i + 1 ]; + data_out[ i + 2 ] = gain * data_in[ i + 2 ]; + data_out[ i + 3 ] = gain * data_in[ i + 3 ]; + } + + /* any remaining elements */ + for( ; i < dataSize; i++ ) { + data_out[ i ] = gain * data_in[ i ]; + } +} diff --git a/src/opus-1.1/silk/float/scale_vector_FLP.c b/src/opus-1.1/silk/float/scale_vector_FLP.c new file mode 100644 index 00000000..108fdcbe --- /dev/null +++ b/src/opus-1.1/silk/float/scale_vector_FLP.c @@ -0,0 +1,56 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SigProc_FLP.h" + +/* multiply a vector by a constant */ +void silk_scale_vector_FLP( + silk_float *data1, + silk_float gain, + opus_int dataSize +) +{ + opus_int i, dataSize4; + + /* 4x unrolled loop */ + dataSize4 = dataSize & 0xFFFC; + for( i = 0; i < dataSize4; i += 4 ) { + data1[ i + 0 ] *= gain; + data1[ i + 1 ] *= gain; + data1[ i + 2 ] *= gain; + data1[ i + 3 ] *= gain; + } + + /* any remaining elements */ + for( ; i < dataSize; i++ ) { + data1[ i ] *= gain; + } +} diff --git a/src/opus-1.1/silk/float/schur_FLP.c b/src/opus-1.1/silk/float/schur_FLP.c new file mode 100644 index 00000000..ee436f83 --- /dev/null +++ b/src/opus-1.1/silk/float/schur_FLP.c @@ -0,0 +1,70 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SigProc_FLP.h" + +silk_float silk_schur_FLP( /* O returns residual energy */ + silk_float refl_coef[], /* O reflection coefficients (length order) */ + const silk_float auto_corr[], /* I autocorrelation sequence (length order+1) */ + opus_int order /* I order */ +) +{ + opus_int k, n; + silk_float C[ SILK_MAX_ORDER_LPC + 1 ][ 2 ]; + silk_float Ctmp1, Ctmp2, rc_tmp; + + silk_assert( order==6||order==8||order==10||order==12||order==14||order==16 ); + + /* Copy correlations */ + for( k = 0; k < order+1; k++ ) { + C[ k ][ 0 ] = C[ k ][ 1 ] = auto_corr[ k ]; + } + + for( k = 0; k < order; k++ ) { + /* Get reflection coefficient */ + rc_tmp = -C[ k + 1 ][ 0 ] / silk_max_float( C[ 0 ][ 1 ], 1e-9f ); + + /* Save the output */ + refl_coef[ k ] = rc_tmp; + + /* Update correlations */ + for( n = 0; n < order - k; n++ ) { + Ctmp1 = C[ n + k + 1 ][ 0 ]; + Ctmp2 = C[ n ][ 1 ]; + C[ n + k + 1 ][ 0 ] = Ctmp1 + Ctmp2 * rc_tmp; + C[ n ][ 1 ] = Ctmp2 + Ctmp1 * rc_tmp; + } + } + + /* Return residual energy */ + return C[ 0 ][ 1 ]; +} + diff --git a/src/opus-1.1/silk/float/solve_LS_FLP.c b/src/opus-1.1/silk/float/solve_LS_FLP.c new file mode 100644 index 00000000..7c90d665 --- /dev/null +++ b/src/opus-1.1/silk/float/solve_LS_FLP.c @@ -0,0 +1,207 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main_FLP.h" +#include "tuning_parameters.h" + +/********************************************************************** + * LDL Factorisation. Finds the upper triangular matrix L and the diagonal + * Matrix D (only the diagonal elements returned in a vector)such that + * the symmetric matric A is given by A = L*D*L'. + **********************************************************************/ +static OPUS_INLINE void silk_LDL_FLP( + silk_float *A, /* I/O Pointer to Symetric Square Matrix */ + opus_int M, /* I Size of Matrix */ + silk_float *L, /* I/O Pointer to Square Upper triangular Matrix */ + silk_float *Dinv /* I/O Pointer to vector holding the inverse diagonal elements of D */ +); + +/********************************************************************** + * Function to solve linear equation Ax = b, when A is a MxM lower + * triangular matrix, with ones on the diagonal. + **********************************************************************/ +static OPUS_INLINE void silk_SolveWithLowerTriangularWdiagOnes_FLP( + const silk_float *L, /* I Pointer to Lower Triangular Matrix */ + opus_int M, /* I Dim of Matrix equation */ + const silk_float *b, /* I b Vector */ + silk_float *x /* O x Vector */ +); + +/********************************************************************** + * Function to solve linear equation (A^T)x = b, when A is a MxM lower + * triangular, with ones on the diagonal. (ie then A^T is upper triangular) + **********************************************************************/ +static OPUS_INLINE void silk_SolveWithUpperTriangularFromLowerWdiagOnes_FLP( + const silk_float *L, /* I Pointer to Lower Triangular Matrix */ + opus_int M, /* I Dim of Matrix equation */ + const silk_float *b, /* I b Vector */ + silk_float *x /* O x Vector */ +); + +/********************************************************************** + * Function to solve linear equation Ax = b, when A is a MxM + * symmetric square matrix - using LDL factorisation + **********************************************************************/ +void silk_solve_LDL_FLP( + silk_float *A, /* I/O Symmetric square matrix, out: reg. */ + const opus_int M, /* I Size of matrix */ + const silk_float *b, /* I Pointer to b vector */ + silk_float *x /* O Pointer to x solution vector */ +) +{ + opus_int i; + silk_float L[ MAX_MATRIX_SIZE ][ MAX_MATRIX_SIZE ]; + silk_float T[ MAX_MATRIX_SIZE ]; + silk_float Dinv[ MAX_MATRIX_SIZE ]; /* inverse diagonal elements of D*/ + + silk_assert( M <= MAX_MATRIX_SIZE ); + + /*************************************************** + Factorize A by LDL such that A = L*D*(L^T), + where L is lower triangular with ones on diagonal + ****************************************************/ + silk_LDL_FLP( A, M, &L[ 0 ][ 0 ], Dinv ); + + /**************************************************** + * substitute D*(L^T) = T. ie: + L*D*(L^T)*x = b => L*T = b <=> T = inv(L)*b + ******************************************************/ + silk_SolveWithLowerTriangularWdiagOnes_FLP( &L[ 0 ][ 0 ], M, b, T ); + + /**************************************************** + D*(L^T)*x = T <=> (L^T)*x = inv(D)*T, because D is + diagonal just multiply with 1/d_i + ****************************************************/ + for( i = 0; i < M; i++ ) { + T[ i ] = T[ i ] * Dinv[ i ]; + } + /**************************************************** + x = inv(L') * inv(D) * T + *****************************************************/ + silk_SolveWithUpperTriangularFromLowerWdiagOnes_FLP( &L[ 0 ][ 0 ], M, T, x ); +} + +static OPUS_INLINE void silk_SolveWithUpperTriangularFromLowerWdiagOnes_FLP( + const silk_float *L, /* I Pointer to Lower Triangular Matrix */ + opus_int M, /* I Dim of Matrix equation */ + const silk_float *b, /* I b Vector */ + silk_float *x /* O x Vector */ +) +{ + opus_int i, j; + silk_float temp; + const silk_float *ptr1; + + for( i = M - 1; i >= 0; i-- ) { + ptr1 = matrix_adr( L, 0, i, M ); + temp = 0; + for( j = M - 1; j > i ; j-- ) { + temp += ptr1[ j * M ] * x[ j ]; + } + temp = b[ i ] - temp; + x[ i ] = temp; + } +} + +static OPUS_INLINE void silk_SolveWithLowerTriangularWdiagOnes_FLP( + const silk_float *L, /* I Pointer to Lower Triangular Matrix */ + opus_int M, /* I Dim of Matrix equation */ + const silk_float *b, /* I b Vector */ + silk_float *x /* O x Vector */ +) +{ + opus_int i, j; + silk_float temp; + const silk_float *ptr1; + + for( i = 0; i < M; i++ ) { + ptr1 = matrix_adr( L, i, 0, M ); + temp = 0; + for( j = 0; j < i; j++ ) { + temp += ptr1[ j ] * x[ j ]; + } + temp = b[ i ] - temp; + x[ i ] = temp; + } +} + +static OPUS_INLINE void silk_LDL_FLP( + silk_float *A, /* I/O Pointer to Symetric Square Matrix */ + opus_int M, /* I Size of Matrix */ + silk_float *L, /* I/O Pointer to Square Upper triangular Matrix */ + silk_float *Dinv /* I/O Pointer to vector holding the inverse diagonal elements of D */ +) +{ + opus_int i, j, k, loop_count, err = 1; + silk_float *ptr1, *ptr2; + double temp, diag_min_value; + silk_float v[ MAX_MATRIX_SIZE ], D[ MAX_MATRIX_SIZE ]; /* temp arrays*/ + + silk_assert( M <= MAX_MATRIX_SIZE ); + + diag_min_value = FIND_LTP_COND_FAC * 0.5f * ( A[ 0 ] + A[ M * M - 1 ] ); + for( loop_count = 0; loop_count < M && err == 1; loop_count++ ) { + err = 0; + for( j = 0; j < M; j++ ) { + ptr1 = matrix_adr( L, j, 0, M ); + temp = matrix_ptr( A, j, j, M ); /* element in row j column j*/ + for( i = 0; i < j; i++ ) { + v[ i ] = ptr1[ i ] * D[ i ]; + temp -= ptr1[ i ] * v[ i ]; + } + if( temp < diag_min_value ) { + /* Badly conditioned matrix: add white noise and run again */ + temp = ( loop_count + 1 ) * diag_min_value - temp; + for( i = 0; i < M; i++ ) { + matrix_ptr( A, i, i, M ) += ( silk_float )temp; + } + err = 1; + break; + } + D[ j ] = ( silk_float )temp; + Dinv[ j ] = ( silk_float )( 1.0f / temp ); + matrix_ptr( L, j, j, M ) = 1.0f; + + ptr1 = matrix_adr( A, j, 0, M ); + ptr2 = matrix_adr( L, j + 1, 0, M); + for( i = j + 1; i < M; i++ ) { + temp = 0.0; + for( k = 0; k < j; k++ ) { + temp += ptr2[ k ] * v[ k ]; + } + matrix_ptr( L, i, j, M ) = ( silk_float )( ( ptr1[ i ] - temp ) * Dinv[ j ] ); + ptr2 += M; /* go to next column*/ + } + } + } + silk_assert( err == 0 ); +} + diff --git a/src/opus-1.1/silk/float/sort_FLP.c b/src/opus-1.1/silk/float/sort_FLP.c new file mode 100644 index 00000000..f08d7592 --- /dev/null +++ b/src/opus-1.1/silk/float/sort_FLP.c @@ -0,0 +1,83 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* Insertion sort (fast for already almost sorted arrays): */ +/* Best case: O(n) for an already sorted array */ +/* Worst case: O(n^2) for an inversely sorted array */ + +#include "typedef.h" +#include "SigProc_FLP.h" + +void silk_insertion_sort_decreasing_FLP( + silk_float *a, /* I/O Unsorted / Sorted vector */ + opus_int *idx, /* O Index vector for the sorted elements */ + const opus_int L, /* I Vector length */ + const opus_int K /* I Number of correctly sorted positions */ +) +{ + silk_float value; + opus_int i, j; + + /* Safety checks */ + silk_assert( K > 0 ); + silk_assert( L > 0 ); + silk_assert( L >= K ); + + /* Write start indices in index vector */ + for( i = 0; i < K; i++ ) { + idx[ i ] = i; + } + + /* Sort vector elements by value, decreasing order */ + for( i = 1; i < K; i++ ) { + value = a[ i ]; + for( j = i - 1; ( j >= 0 ) && ( value > a[ j ] ); j-- ) { + a[ j + 1 ] = a[ j ]; /* Shift value */ + idx[ j + 1 ] = idx[ j ]; /* Shift index */ + } + a[ j + 1 ] = value; /* Write value */ + idx[ j + 1 ] = i; /* Write index */ + } + + /* If less than L values are asked check the remaining values, */ + /* but only spend CPU to ensure that the K first values are correct */ + for( i = K; i < L; i++ ) { + value = a[ i ]; + if( value > a[ K - 1 ] ) { + for( j = K - 2; ( j >= 0 ) && ( value > a[ j ] ); j-- ) { + a[ j + 1 ] = a[ j ]; /* Shift value */ + idx[ j + 1 ] = idx[ j ]; /* Shift index */ + } + a[ j + 1 ] = value; /* Write value */ + idx[ j + 1 ] = i; /* Write index */ + } + } +} diff --git a/src/opus-1.1/silk/float/structs_FLP.h b/src/opus-1.1/silk/float/structs_FLP.h new file mode 100644 index 00000000..bb529e71 --- /dev/null +++ b/src/opus-1.1/silk/float/structs_FLP.h @@ -0,0 +1,131 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifndef SILK_STRUCTS_FLP_H +#define SILK_STRUCTS_FLP_H + +#include "typedef.h" +#include "main.h" +#include "structs.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/********************************/ +/* Noise shaping analysis state */ +/********************************/ +typedef struct { + opus_int8 LastGainIndex; + silk_float HarmBoost_smth; + silk_float HarmShapeGain_smth; + silk_float Tilt_smth; +} silk_shape_state_FLP; + +/********************************/ +/* Prefilter state */ +/********************************/ +typedef struct { + silk_float sLTP_shp[ LTP_BUF_LENGTH ]; + silk_float sAR_shp[ MAX_SHAPE_LPC_ORDER + 1 ]; + opus_int sLTP_shp_buf_idx; + silk_float sLF_AR_shp; + silk_float sLF_MA_shp; + silk_float sHarmHP; + opus_int32 rand_seed; + opus_int lagPrev; +} silk_prefilter_state_FLP; + +/********************************/ +/* Encoder state FLP */ +/********************************/ +typedef struct { + silk_encoder_state sCmn; /* Common struct, shared with fixed-point code */ + silk_shape_state_FLP sShape; /* Noise shaping state */ + silk_prefilter_state_FLP sPrefilt; /* Prefilter State */ + + /* Buffer for find pitch and noise shape analysis */ + silk_float x_buf[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ];/* Buffer for find pitch and noise shape analysis */ + silk_float LTPCorr; /* Normalized correlation from pitch lag estimator */ +} silk_encoder_state_FLP; + +/************************/ +/* Encoder control FLP */ +/************************/ +typedef struct { + /* Prediction and coding parameters */ + silk_float Gains[ MAX_NB_SUBFR ]; + silk_float PredCoef[ 2 ][ MAX_LPC_ORDER ]; /* holds interpolated and final coefficients */ + silk_float LTPCoef[LTP_ORDER * MAX_NB_SUBFR]; + silk_float LTP_scale; + opus_int pitchL[ MAX_NB_SUBFR ]; + + /* Noise shaping parameters */ + silk_float AR1[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ]; + silk_float AR2[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ]; + silk_float LF_MA_shp[ MAX_NB_SUBFR ]; + silk_float LF_AR_shp[ MAX_NB_SUBFR ]; + silk_float GainsPre[ MAX_NB_SUBFR ]; + silk_float HarmBoost[ MAX_NB_SUBFR ]; + silk_float Tilt[ MAX_NB_SUBFR ]; + silk_float HarmShapeGain[ MAX_NB_SUBFR ]; + silk_float Lambda; + silk_float input_quality; + silk_float coding_quality; + + /* Measures */ + silk_float sparseness; + silk_float predGain; + silk_float LTPredCodGain; + silk_float ResNrg[ MAX_NB_SUBFR ]; /* Residual energy per subframe */ + + /* Parameters for CBR mode */ + opus_int32 GainsUnq_Q16[ MAX_NB_SUBFR ]; + opus_int8 lastGainIndexPrev; +} silk_encoder_control_FLP; + +/************************/ +/* Encoder Super Struct */ +/************************/ +typedef struct { + silk_encoder_state_FLP state_Fxx[ ENCODER_NUM_CHANNELS ]; + stereo_enc_state sStereo; + opus_int32 nBitsExceeded; + opus_int nChannelsAPI; + opus_int nChannelsInternal; + opus_int nPrevChannelsInternal; + opus_int timeSinceSwitchAllowed_ms; + opus_int allowBandwidthSwitch; + opus_int prev_decode_only_middle; +} silk_encoder; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/opus-1.1/silk/float/warped_autocorrelation_FLP.c b/src/opus-1.1/silk/float/warped_autocorrelation_FLP.c new file mode 100644 index 00000000..542414f4 --- /dev/null +++ b/src/opus-1.1/silk/float/warped_autocorrelation_FLP.c @@ -0,0 +1,73 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main_FLP.h" + +/* Autocorrelations for a warped frequency axis */ +void silk_warped_autocorrelation_FLP( + silk_float *corr, /* O Result [order + 1] */ + const silk_float *input, /* I Input data to correlate */ + const silk_float warping, /* I Warping coefficient */ + const opus_int length, /* I Length of input */ + const opus_int order /* I Correlation order (even) */ +) +{ + opus_int n, i; + double tmp1, tmp2; + double state[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; + double C[ MAX_SHAPE_LPC_ORDER + 1 ] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }; + + /* Order must be even */ + silk_assert( ( order & 1 ) == 0 ); + + /* Loop over samples */ + for( n = 0; n < length; n++ ) { + tmp1 = input[ n ]; + /* Loop over allpass sections */ + for( i = 0; i < order; i += 2 ) { + /* Output of allpass section */ + tmp2 = state[ i ] + warping * ( state[ i + 1 ] - tmp1 ); + state[ i ] = tmp1; + C[ i ] += state[ 0 ] * tmp1; + /* Output of allpass section */ + tmp1 = state[ i + 1 ] + warping * ( state[ i + 2 ] - tmp2 ); + state[ i + 1 ] = tmp2; + C[ i + 1 ] += state[ 0 ] * tmp2; + } + state[ order ] = tmp1; + C[ order ] += state[ 0 ] * tmp1; + } + + /* Copy correlations in silk_float output format */ + for( i = 0; i < order + 1; i++ ) { + corr[ i ] = ( silk_float )C[ i ]; + } +} diff --git a/src/opus-1.1/silk/float/wrappers_FLP.c b/src/opus-1.1/silk/float/wrappers_FLP.c new file mode 100644 index 00000000..350599b2 --- /dev/null +++ b/src/opus-1.1/silk/float/wrappers_FLP.c @@ -0,0 +1,201 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main_FLP.h" + +/* Wrappers. Calls flp / fix code */ + +/* Convert AR filter coefficients to NLSF parameters */ +void silk_A2NLSF_FLP( + opus_int16 *NLSF_Q15, /* O NLSF vector [ LPC_order ] */ + const silk_float *pAR, /* I LPC coefficients [ LPC_order ] */ + const opus_int LPC_order /* I LPC order */ +) +{ + opus_int i; + opus_int32 a_fix_Q16[ MAX_LPC_ORDER ]; + + for( i = 0; i < LPC_order; i++ ) { + a_fix_Q16[ i ] = silk_float2int( pAR[ i ] * 65536.0f ); + } + + silk_A2NLSF( NLSF_Q15, a_fix_Q16, LPC_order ); +} + +/* Convert LSF parameters to AR prediction filter coefficients */ +void silk_NLSF2A_FLP( + silk_float *pAR, /* O LPC coefficients [ LPC_order ] */ + const opus_int16 *NLSF_Q15, /* I NLSF vector [ LPC_order ] */ + const opus_int LPC_order /* I LPC order */ +) +{ + opus_int i; + opus_int16 a_fix_Q12[ MAX_LPC_ORDER ]; + + silk_NLSF2A( a_fix_Q12, NLSF_Q15, LPC_order ); + + for( i = 0; i < LPC_order; i++ ) { + pAR[ i ] = ( silk_float )a_fix_Q12[ i ] * ( 1.0f / 4096.0f ); + } +} + +/******************************************/ +/* Floating-point NLSF processing wrapper */ +/******************************************/ +void silk_process_NLSFs_FLP( + silk_encoder_state *psEncC, /* I/O Encoder state */ + silk_float PredCoef[ 2 ][ MAX_LPC_ORDER ], /* O Prediction coefficients */ + opus_int16 NLSF_Q15[ MAX_LPC_ORDER ], /* I/O Normalized LSFs (quant out) (0 - (2^15-1)) */ + const opus_int16 prev_NLSF_Q15[ MAX_LPC_ORDER ] /* I Previous Normalized LSFs (0 - (2^15-1)) */ +) +{ + opus_int i, j; + opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ]; + + silk_process_NLSFs( psEncC, PredCoef_Q12, NLSF_Q15, prev_NLSF_Q15); + + for( j = 0; j < 2; j++ ) { + for( i = 0; i < psEncC->predictLPCOrder; i++ ) { + PredCoef[ j ][ i ] = ( silk_float )PredCoef_Q12[ j ][ i ] * ( 1.0f / 4096.0f ); + } + } +} + +/****************************************/ +/* Floating-point Silk NSQ wrapper */ +/****************************************/ +void silk_NSQ_wrapper_FLP( + silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ + silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ + SideInfoIndices *psIndices, /* I/O Quantization indices */ + silk_nsq_state *psNSQ, /* I/O Noise Shaping Quantzation state */ + opus_int8 pulses[], /* O Quantized pulse signal */ + const silk_float x[] /* I Prefiltered input signal */ +) +{ + opus_int i, j; + opus_int32 x_Q3[ MAX_FRAME_LENGTH ]; + opus_int32 Gains_Q16[ MAX_NB_SUBFR ]; + silk_DWORD_ALIGN opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ]; + opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ]; + opus_int LTP_scale_Q14; + + /* Noise shaping parameters */ + opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ]; + opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ]; /* Packs two int16 coefficients per int32 value */ + opus_int Lambda_Q10; + opus_int Tilt_Q14[ MAX_NB_SUBFR ]; + opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ]; + + /* Convert control struct to fix control struct */ + /* Noise shape parameters */ + for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { + for( j = 0; j < psEnc->sCmn.shapingLPCOrder; j++ ) { + AR2_Q13[ i * MAX_SHAPE_LPC_ORDER + j ] = silk_float2int( psEncCtrl->AR2[ i * MAX_SHAPE_LPC_ORDER + j ] * 8192.0f ); + } + } + + for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { + LF_shp_Q14[ i ] = silk_LSHIFT32( silk_float2int( psEncCtrl->LF_AR_shp[ i ] * 16384.0f ), 16 ) | + (opus_uint16)silk_float2int( psEncCtrl->LF_MA_shp[ i ] * 16384.0f ); + Tilt_Q14[ i ] = (opus_int)silk_float2int( psEncCtrl->Tilt[ i ] * 16384.0f ); + HarmShapeGain_Q14[ i ] = (opus_int)silk_float2int( psEncCtrl->HarmShapeGain[ i ] * 16384.0f ); + } + Lambda_Q10 = ( opus_int )silk_float2int( psEncCtrl->Lambda * 1024.0f ); + + /* prediction and coding parameters */ + for( i = 0; i < psEnc->sCmn.nb_subfr * LTP_ORDER; i++ ) { + LTPCoef_Q14[ i ] = (opus_int16)silk_float2int( psEncCtrl->LTPCoef[ i ] * 16384.0f ); + } + + for( j = 0; j < 2; j++ ) { + for( i = 0; i < psEnc->sCmn.predictLPCOrder; i++ ) { + PredCoef_Q12[ j ][ i ] = (opus_int16)silk_float2int( psEncCtrl->PredCoef[ j ][ i ] * 4096.0f ); + } + } + + for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { + Gains_Q16[ i ] = silk_float2int( psEncCtrl->Gains[ i ] * 65536.0f ); + silk_assert( Gains_Q16[ i ] > 0 ); + } + + if( psIndices->signalType == TYPE_VOICED ) { + LTP_scale_Q14 = silk_LTPScales_table_Q14[ psIndices->LTP_scaleIndex ]; + } else { + LTP_scale_Q14 = 0; + } + + /* Convert input to fix */ + for( i = 0; i < psEnc->sCmn.frame_length; i++ ) { + x_Q3[ i ] = silk_float2int( 8.0f * x[ i ] ); + } + + /* Call NSQ */ + if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) { + silk_NSQ_del_dec( &psEnc->sCmn, psNSQ, psIndices, x_Q3, pulses, PredCoef_Q12[ 0 ], LTPCoef_Q14, + AR2_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, psEncCtrl->pitchL, Lambda_Q10, LTP_scale_Q14 ); + } else { + silk_NSQ( &psEnc->sCmn, psNSQ, psIndices, x_Q3, pulses, PredCoef_Q12[ 0 ], LTPCoef_Q14, + AR2_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, psEncCtrl->pitchL, Lambda_Q10, LTP_scale_Q14 ); + } +} + +/***********************************************/ +/* Floating-point Silk LTP quantiation wrapper */ +/***********************************************/ +void silk_quant_LTP_gains_FLP( + silk_float B[ MAX_NB_SUBFR * LTP_ORDER ], /* I/O (Un-)quantized LTP gains */ + opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook index */ + opus_int8 *periodicity_index, /* O Periodicity index */ + opus_int32 *sum_log_gain_Q7, /* I/O Cumulative max prediction gain */ + const silk_float W[ MAX_NB_SUBFR * LTP_ORDER * LTP_ORDER ], /* I Error weights */ + const opus_int mu_Q10, /* I Mu value (R/D tradeoff) */ + const opus_int lowComplexity, /* I Flag for low complexity */ + const opus_int nb_subfr /* I number of subframes */ +) +{ + opus_int i; + opus_int16 B_Q14[ MAX_NB_SUBFR * LTP_ORDER ]; + opus_int32 W_Q18[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ]; + + for( i = 0; i < nb_subfr * LTP_ORDER; i++ ) { + B_Q14[ i ] = (opus_int16)silk_float2int( B[ i ] * 16384.0f ); + } + for( i = 0; i < nb_subfr * LTP_ORDER * LTP_ORDER; i++ ) { + W_Q18[ i ] = (opus_int32)silk_float2int( W[ i ] * 262144.0f ); + } + + silk_quant_LTP_gains( B_Q14, cbk_index, periodicity_index, sum_log_gain_Q7, W_Q18, mu_Q10, lowComplexity, nb_subfr ); + + for( i = 0; i < nb_subfr * LTP_ORDER; i++ ) { + B[ i ] = (silk_float)B_Q14[ i ] * ( 1.0f / 16384.0f ); + } +} diff --git a/src/opus-1.1/silk/gain_quant.c b/src/opus-1.1/silk/gain_quant.c new file mode 100644 index 00000000..64ccd061 --- /dev/null +++ b/src/opus-1.1/silk/gain_quant.c @@ -0,0 +1,141 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main.h" + +#define OFFSET ( ( MIN_QGAIN_DB * 128 ) / 6 + 16 * 128 ) +#define SCALE_Q16 ( ( 65536 * ( N_LEVELS_QGAIN - 1 ) ) / ( ( ( MAX_QGAIN_DB - MIN_QGAIN_DB ) * 128 ) / 6 ) ) +#define INV_SCALE_Q16 ( ( 65536 * ( ( ( MAX_QGAIN_DB - MIN_QGAIN_DB ) * 128 ) / 6 ) ) / ( N_LEVELS_QGAIN - 1 ) ) + +/* Gain scalar quantization with hysteresis, uniform on log scale */ +void silk_gains_quant( + opus_int8 ind[ MAX_NB_SUBFR ], /* O gain indices */ + opus_int32 gain_Q16[ MAX_NB_SUBFR ], /* I/O gains (quantized out) */ + opus_int8 *prev_ind, /* I/O last index in previous frame */ + const opus_int conditional, /* I first gain is delta coded if 1 */ + const opus_int nb_subfr /* I number of subframes */ +) +{ + opus_int k, double_step_size_threshold; + + for( k = 0; k < nb_subfr; k++ ) { + /* Convert to log scale, scale, floor() */ + ind[ k ] = silk_SMULWB( SCALE_Q16, silk_lin2log( gain_Q16[ k ] ) - OFFSET ); + + /* Round towards previous quantized gain (hysteresis) */ + if( ind[ k ] < *prev_ind ) { + ind[ k ]++; + } + ind[ k ] = silk_LIMIT_int( ind[ k ], 0, N_LEVELS_QGAIN - 1 ); + + /* Compute delta indices and limit */ + if( k == 0 && conditional == 0 ) { + /* Full index */ + ind[ k ] = silk_LIMIT_int( ind[ k ], *prev_ind + MIN_DELTA_GAIN_QUANT, N_LEVELS_QGAIN - 1 ); + *prev_ind = ind[ k ]; + } else { + /* Delta index */ + ind[ k ] = ind[ k ] - *prev_ind; + + /* Double the quantization step size for large gain increases, so that the max gain level can be reached */ + double_step_size_threshold = 2 * MAX_DELTA_GAIN_QUANT - N_LEVELS_QGAIN + *prev_ind; + if( ind[ k ] > double_step_size_threshold ) { + ind[ k ] = double_step_size_threshold + silk_RSHIFT( ind[ k ] - double_step_size_threshold + 1, 1 ); + } + + ind[ k ] = silk_LIMIT_int( ind[ k ], MIN_DELTA_GAIN_QUANT, MAX_DELTA_GAIN_QUANT ); + + /* Accumulate deltas */ + if( ind[ k ] > double_step_size_threshold ) { + *prev_ind += silk_LSHIFT( ind[ k ], 1 ) - double_step_size_threshold; + } else { + *prev_ind += ind[ k ]; + } + + /* Shift to make non-negative */ + ind[ k ] -= MIN_DELTA_GAIN_QUANT; + } + + /* Scale and convert to linear scale */ + gain_Q16[ k ] = silk_log2lin( silk_min_32( silk_SMULWB( INV_SCALE_Q16, *prev_ind ) + OFFSET, 3967 ) ); /* 3967 = 31 in Q7 */ + } +} + +/* Gains scalar dequantization, uniform on log scale */ +void silk_gains_dequant( + opus_int32 gain_Q16[ MAX_NB_SUBFR ], /* O quantized gains */ + const opus_int8 ind[ MAX_NB_SUBFR ], /* I gain indices */ + opus_int8 *prev_ind, /* I/O last index in previous frame */ + const opus_int conditional, /* I first gain is delta coded if 1 */ + const opus_int nb_subfr /* I number of subframes */ +) +{ + opus_int k, ind_tmp, double_step_size_threshold; + + for( k = 0; k < nb_subfr; k++ ) { + if( k == 0 && conditional == 0 ) { + /* Gain index is not allowed to go down more than 16 steps (~21.8 dB) */ + *prev_ind = silk_max_int( ind[ k ], *prev_ind - 16 ); + } else { + /* Delta index */ + ind_tmp = ind[ k ] + MIN_DELTA_GAIN_QUANT; + + /* Accumulate deltas */ + double_step_size_threshold = 2 * MAX_DELTA_GAIN_QUANT - N_LEVELS_QGAIN + *prev_ind; + if( ind_tmp > double_step_size_threshold ) { + *prev_ind += silk_LSHIFT( ind_tmp, 1 ) - double_step_size_threshold; + } else { + *prev_ind += ind_tmp; + } + } + *prev_ind = silk_LIMIT_int( *prev_ind, 0, N_LEVELS_QGAIN - 1 ); + + /* Scale and convert to linear scale */ + gain_Q16[ k ] = silk_log2lin( silk_min_32( silk_SMULWB( INV_SCALE_Q16, *prev_ind ) + OFFSET, 3967 ) ); /* 3967 = 31 in Q7 */ + } +} + +/* Compute unique identifier of gain indices vector */ +opus_int32 silk_gains_ID( /* O returns unique identifier of gains */ + const opus_int8 ind[ MAX_NB_SUBFR ], /* I gain indices */ + const opus_int nb_subfr /* I number of subframes */ +) +{ + opus_int k; + opus_int32 gainsID; + + gainsID = 0; + for( k = 0; k < nb_subfr; k++ ) { + gainsID = silk_ADD_LSHIFT32( ind[ k ], gainsID, 8 ); + } + + return gainsID; +} diff --git a/src/opus-1.1/silk/init_decoder.c b/src/opus-1.1/silk/init_decoder.c new file mode 100644 index 00000000..f887c678 --- /dev/null +++ b/src/opus-1.1/silk/init_decoder.c @@ -0,0 +1,56 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main.h" + +/************************/ +/* Init Decoder State */ +/************************/ +opus_int silk_init_decoder( + silk_decoder_state *psDec /* I/O Decoder state pointer */ +) +{ + /* Clear the entire encoder state, except anything copied */ + silk_memset( psDec, 0, sizeof( silk_decoder_state ) ); + + /* Used to deactivate LSF interpolation */ + psDec->first_frame_after_reset = 1; + psDec->prev_gain_Q16 = 65536; + + /* Reset CNG state */ + silk_CNG_Reset( psDec ); + + /* Reset PLC state */ + silk_PLC_Reset( psDec ); + + return(0); +} + diff --git a/src/opus-1.1/silk/init_encoder.c b/src/opus-1.1/silk/init_encoder.c new file mode 100644 index 00000000..65995c33 --- /dev/null +++ b/src/opus-1.1/silk/init_encoder.c @@ -0,0 +1,64 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#ifdef FIXED_POINT +#include "main_FIX.h" +#else +#include "main_FLP.h" +#endif +#include "tuning_parameters.h" +#include "cpu_support.h" + +/*********************************/ +/* Initialize Silk Encoder state */ +/*********************************/ +opus_int silk_init_encoder( + silk_encoder_state_Fxx *psEnc, /* I/O Pointer to Silk FIX encoder state */ + int arch /* I Run-time architecture */ +) +{ + opus_int ret = 0; + + /* Clear the entire encoder state */ + silk_memset( psEnc, 0, sizeof( silk_encoder_state_Fxx ) ); + + psEnc->sCmn.arch = arch; + + psEnc->sCmn.variable_HP_smth1_Q15 = silk_LSHIFT( silk_lin2log( SILK_FIX_CONST( VARIABLE_HP_MIN_CUTOFF_HZ, 16 ) ) - ( 16 << 7 ), 8 ); + psEnc->sCmn.variable_HP_smth2_Q15 = psEnc->sCmn.variable_HP_smth1_Q15; + + /* Used to deactivate LSF interpolation, pitch prediction */ + psEnc->sCmn.first_frame_after_reset = 1; + + /* Initialize Silk VAD */ + ret += silk_VAD_Init( &psEnc->sCmn.sVAD ); + + return ret; +} diff --git a/src/opus-1.1/silk/inner_prod_aligned.c b/src/opus-1.1/silk/inner_prod_aligned.c new file mode 100644 index 00000000..257ae9e0 --- /dev/null +++ b/src/opus-1.1/silk/inner_prod_aligned.c @@ -0,0 +1,47 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SigProc_FIX.h" + +opus_int32 silk_inner_prod_aligned_scale( + const opus_int16 *const inVec1, /* I input vector 1 */ + const opus_int16 *const inVec2, /* I input vector 2 */ + const opus_int scale, /* I number of bits to shift */ + const opus_int len /* I vector lengths */ +) +{ + opus_int i; + opus_int32 sum = 0; + for( i = 0; i < len; i++ ) { + sum = silk_ADD_RSHIFT32( sum, silk_SMULBB( inVec1[ i ], inVec2[ i ] ), scale ); + } + return sum; +} diff --git a/src/opus-1.1/silk/interpolate.c b/src/opus-1.1/silk/interpolate.c new file mode 100644 index 00000000..1bd8ca4d --- /dev/null +++ b/src/opus-1.1/silk/interpolate.c @@ -0,0 +1,51 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main.h" + +/* Interpolate two vectors */ +void silk_interpolate( + opus_int16 xi[ MAX_LPC_ORDER ], /* O interpolated vector */ + const opus_int16 x0[ MAX_LPC_ORDER ], /* I first vector */ + const opus_int16 x1[ MAX_LPC_ORDER ], /* I second vector */ + const opus_int ifact_Q2, /* I interp. factor, weight on 2nd vector */ + const opus_int d /* I number of parameters */ +) +{ + opus_int i; + + silk_assert( ifact_Q2 >= 0 ); + silk_assert( ifact_Q2 <= 4 ); + + for( i = 0; i < d; i++ ) { + xi[ i ] = (opus_int16)silk_ADD_RSHIFT( x0[ i ], silk_SMULBB( x1[ i ] - x0[ i ], ifact_Q2 ), 2 ); + } +} diff --git a/src/opus-1.1/silk/lin2log.c b/src/opus-1.1/silk/lin2log.c new file mode 100644 index 00000000..d4fe5153 --- /dev/null +++ b/src/opus-1.1/silk/lin2log.c @@ -0,0 +1,46 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SigProc_FIX.h" +/* Approximation of 128 * log2() (very close inverse of silk_log2lin()) */ +/* Convert input to a log scale */ +opus_int32 silk_lin2log( + const opus_int32 inLin /* I input in linear scale */ +) +{ + opus_int32 lz, frac_Q7; + + silk_CLZ_FRAC( inLin, &lz, &frac_Q7 ); + + /* Piece-wise parabolic approximation */ + return silk_LSHIFT( 31 - lz, 7 ) + silk_SMLAWB( frac_Q7, silk_MUL( frac_Q7, 128 - frac_Q7 ), 179 ); +} + diff --git a/src/opus-1.1/silk/log2lin.c b/src/opus-1.1/silk/log2lin.c new file mode 100644 index 00000000..a692e009 --- /dev/null +++ b/src/opus-1.1/silk/log2lin.c @@ -0,0 +1,58 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SigProc_FIX.h" + +/* Approximation of 2^() (very close inverse of silk_lin2log()) */ +/* Convert input to a linear scale */ +opus_int32 silk_log2lin( + const opus_int32 inLog_Q7 /* I input on log scale */ +) +{ + opus_int32 out, frac_Q7; + + if( inLog_Q7 < 0 ) { + return 0; + } else if ( inLog_Q7 >= 3967 ) { + return silk_int32_MAX; + } + + out = silk_LSHIFT( 1, silk_RSHIFT( inLog_Q7, 7 ) ); + frac_Q7 = inLog_Q7 & 0x7F; + if( inLog_Q7 < 2048 ) { + /* Piece-wise parabolic approximation */ + out = silk_ADD_RSHIFT32( out, silk_MUL( out, silk_SMLAWB( frac_Q7, silk_SMULBB( frac_Q7, 128 - frac_Q7 ), -174 ) ), 7 ); + } else { + /* Piece-wise parabolic approximation */ + out = silk_MLA( out, silk_RSHIFT( out, 7 ), silk_SMLAWB( frac_Q7, silk_SMULBB( frac_Q7, 128 - frac_Q7 ), -174 ) ); + } + return out; +} diff --git a/src/opus-1.1/silk/macros.h b/src/opus-1.1/silk/macros.h new file mode 100644 index 00000000..a84e5a5d --- /dev/null +++ b/src/opus-1.1/silk/macros.h @@ -0,0 +1,115 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifndef SILK_MACROS_H +#define SILK_MACROS_H + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "opus_types.h" +#include "opus_defines.h" + +/* This is an OPUS_INLINE header file for general platform. */ + +/* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */ +#define silk_SMULWB(a32, b32) ((((a32) >> 16) * (opus_int32)((opus_int16)(b32))) + ((((a32) & 0x0000FFFF) * (opus_int32)((opus_int16)(b32))) >> 16)) + +/* a32 + (b32 * (opus_int32)((opus_int16)(c32))) >> 16 output have to be 32bit int */ +#define silk_SMLAWB(a32, b32, c32) ((a32) + ((((b32) >> 16) * (opus_int32)((opus_int16)(c32))) + ((((b32) & 0x0000FFFF) * (opus_int32)((opus_int16)(c32))) >> 16))) + +/* (a32 * (b32 >> 16)) >> 16 */ +#define silk_SMULWT(a32, b32) (((a32) >> 16) * ((b32) >> 16) + ((((a32) & 0x0000FFFF) * ((b32) >> 16)) >> 16)) + +/* a32 + (b32 * (c32 >> 16)) >> 16 */ +#define silk_SMLAWT(a32, b32, c32) ((a32) + (((b32) >> 16) * ((c32) >> 16)) + ((((b32) & 0x0000FFFF) * ((c32) >> 16)) >> 16)) + +/* (opus_int32)((opus_int16)(a3))) * (opus_int32)((opus_int16)(b32)) output have to be 32bit int */ +#define silk_SMULBB(a32, b32) ((opus_int32)((opus_int16)(a32)) * (opus_int32)((opus_int16)(b32))) + +/* a32 + (opus_int32)((opus_int16)(b32)) * (opus_int32)((opus_int16)(c32)) output have to be 32bit int */ +#define silk_SMLABB(a32, b32, c32) ((a32) + ((opus_int32)((opus_int16)(b32))) * (opus_int32)((opus_int16)(c32))) + +/* (opus_int32)((opus_int16)(a32)) * (b32 >> 16) */ +#define silk_SMULBT(a32, b32) ((opus_int32)((opus_int16)(a32)) * ((b32) >> 16)) + +/* a32 + (opus_int32)((opus_int16)(b32)) * (c32 >> 16) */ +#define silk_SMLABT(a32, b32, c32) ((a32) + ((opus_int32)((opus_int16)(b32))) * ((c32) >> 16)) + +/* a64 + (b32 * c32) */ +#define silk_SMLAL(a64, b32, c32) (silk_ADD64((a64), ((opus_int64)(b32) * (opus_int64)(c32)))) + +/* (a32 * b32) >> 16 */ +#define silk_SMULWW(a32, b32) silk_MLA(silk_SMULWB((a32), (b32)), (a32), silk_RSHIFT_ROUND((b32), 16)) + +/* a32 + ((b32 * c32) >> 16) */ +#define silk_SMLAWW(a32, b32, c32) silk_MLA(silk_SMLAWB((a32), (b32), (c32)), (b32), silk_RSHIFT_ROUND((c32), 16)) + +/* add/subtract with output saturated */ +#define silk_ADD_SAT32(a, b) ((((opus_uint32)(a) + (opus_uint32)(b)) & 0x80000000) == 0 ? \ + ((((a) & (b)) & 0x80000000) != 0 ? silk_int32_MIN : (a)+(b)) : \ + ((((a) | (b)) & 0x80000000) == 0 ? silk_int32_MAX : (a)+(b)) ) + +#define silk_SUB_SAT32(a, b) ((((opus_uint32)(a)-(opus_uint32)(b)) & 0x80000000) == 0 ? \ + (( (a) & ((b)^0x80000000) & 0x80000000) ? silk_int32_MIN : (a)-(b)) : \ + ((((a)^0x80000000) & (b) & 0x80000000) ? silk_int32_MAX : (a)-(b)) ) + +#include "ecintrin.h" + +static OPUS_INLINE opus_int32 silk_CLZ16(opus_int16 in16) +{ + return 32 - EC_ILOG(in16<<16|0x8000); +} + +static OPUS_INLINE opus_int32 silk_CLZ32(opus_int32 in32) +{ + return in32 ? 32 - EC_ILOG(in32) : 32; +} + +/* Row based */ +#define matrix_ptr(Matrix_base_adr, row, column, N) \ + (*((Matrix_base_adr) + ((row)*(N)+(column)))) +#define matrix_adr(Matrix_base_adr, row, column, N) \ + ((Matrix_base_adr) + ((row)*(N)+(column))) + +/* Column based */ +#ifndef matrix_c_ptr +# define matrix_c_ptr(Matrix_base_adr, row, column, M) \ + (*((Matrix_base_adr) + ((row)+(M)*(column)))) +#endif + +#ifdef OPUS_ARM_INLINE_ASM +#include "arm/macros_armv4.h" +#endif + +#ifdef OPUS_ARM_INLINE_EDSP +#include "arm/macros_armv5e.h" +#endif + +#endif /* SILK_MACROS_H */ + diff --git a/src/opus-1.1/silk/main.h b/src/opus-1.1/silk/main.h new file mode 100644 index 00000000..2bdf8978 --- /dev/null +++ b/src/opus-1.1/silk/main.h @@ -0,0 +1,438 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifndef SILK_MAIN_H +#define SILK_MAIN_H + +#include "SigProc_FIX.h" +#include "define.h" +#include "structs.h" +#include "tables.h" +#include "PLC.h" +#include "control.h" +#include "debug.h" +#include "entenc.h" +#include "entdec.h" + +/* Convert Left/Right stereo signal to adaptive Mid/Side representation */ +void silk_stereo_LR_to_MS( + stereo_enc_state *state, /* I/O State */ + opus_int16 x1[], /* I/O Left input signal, becomes mid signal */ + opus_int16 x2[], /* I/O Right input signal, becomes side signal */ + opus_int8 ix[ 2 ][ 3 ], /* O Quantization indices */ + opus_int8 *mid_only_flag, /* O Flag: only mid signal coded */ + opus_int32 mid_side_rates_bps[], /* O Bitrates for mid and side signals */ + opus_int32 total_rate_bps, /* I Total bitrate */ + opus_int prev_speech_act_Q8, /* I Speech activity level in previous frame */ + opus_int toMono, /* I Last frame before a stereo->mono transition */ + opus_int fs_kHz, /* I Sample rate (kHz) */ + opus_int frame_length /* I Number of samples */ +); + +/* Convert adaptive Mid/Side representation to Left/Right stereo signal */ +void silk_stereo_MS_to_LR( + stereo_dec_state *state, /* I/O State */ + opus_int16 x1[], /* I/O Left input signal, becomes mid signal */ + opus_int16 x2[], /* I/O Right input signal, becomes side signal */ + const opus_int32 pred_Q13[], /* I Predictors */ + opus_int fs_kHz, /* I Samples rate (kHz) */ + opus_int frame_length /* I Number of samples */ +); + +/* Find least-squares prediction gain for one signal based on another and quantize it */ +opus_int32 silk_stereo_find_predictor( /* O Returns predictor in Q13 */ + opus_int32 *ratio_Q14, /* O Ratio of residual and mid energies */ + const opus_int16 x[], /* I Basis signal */ + const opus_int16 y[], /* I Target signal */ + opus_int32 mid_res_amp_Q0[], /* I/O Smoothed mid, residual norms */ + opus_int length, /* I Number of samples */ + opus_int smooth_coef_Q16 /* I Smoothing coefficient */ +); + +/* Quantize mid/side predictors */ +void silk_stereo_quant_pred( + opus_int32 pred_Q13[], /* I/O Predictors (out: quantized) */ + opus_int8 ix[ 2 ][ 3 ] /* O Quantization indices */ +); + +/* Entropy code the mid/side quantization indices */ +void silk_stereo_encode_pred( + ec_enc *psRangeEnc, /* I/O Compressor data structure */ + opus_int8 ix[ 2 ][ 3 ] /* I Quantization indices */ +); + +/* Entropy code the mid-only flag */ +void silk_stereo_encode_mid_only( + ec_enc *psRangeEnc, /* I/O Compressor data structure */ + opus_int8 mid_only_flag +); + +/* Decode mid/side predictors */ +void silk_stereo_decode_pred( + ec_dec *psRangeDec, /* I/O Compressor data structure */ + opus_int32 pred_Q13[] /* O Predictors */ +); + +/* Decode mid-only flag */ +void silk_stereo_decode_mid_only( + ec_dec *psRangeDec, /* I/O Compressor data structure */ + opus_int *decode_only_mid /* O Flag that only mid channel has been coded */ +); + +/* Encodes signs of excitation */ +void silk_encode_signs( + ec_enc *psRangeEnc, /* I/O Compressor data structure */ + const opus_int8 pulses[], /* I pulse signal */ + opus_int length, /* I length of input */ + const opus_int signalType, /* I Signal type */ + const opus_int quantOffsetType, /* I Quantization offset type */ + const opus_int sum_pulses[ MAX_NB_SHELL_BLOCKS ] /* I Sum of absolute pulses per block */ +); + +/* Decodes signs of excitation */ +void silk_decode_signs( + ec_dec *psRangeDec, /* I/O Compressor data structure */ + opus_int pulses[], /* I/O pulse signal */ + opus_int length, /* I length of input */ + const opus_int signalType, /* I Signal type */ + const opus_int quantOffsetType, /* I Quantization offset type */ + const opus_int sum_pulses[ MAX_NB_SHELL_BLOCKS ] /* I Sum of absolute pulses per block */ +); + +/* Check encoder control struct */ +opus_int check_control_input( + silk_EncControlStruct *encControl /* I Control structure */ +); + +/* Control internal sampling rate */ +opus_int silk_control_audio_bandwidth( + silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */ + silk_EncControlStruct *encControl /* I Control structure */ +); + +/* Control SNR of redidual quantizer */ +opus_int silk_control_SNR( + silk_encoder_state *psEncC, /* I/O Pointer to Silk encoder state */ + opus_int32 TargetRate_bps /* I Target max bitrate (bps) */ +); + +/***************/ +/* Shell coder */ +/***************/ + +/* Encode quantization indices of excitation */ +void silk_encode_pulses( + ec_enc *psRangeEnc, /* I/O compressor data structure */ + const opus_int signalType, /* I Signal type */ + const opus_int quantOffsetType, /* I quantOffsetType */ + opus_int8 pulses[], /* I quantization indices */ + const opus_int frame_length /* I Frame length */ +); + +/* Shell encoder, operates on one shell code frame of 16 pulses */ +void silk_shell_encoder( + ec_enc *psRangeEnc, /* I/O compressor data structure */ + const opus_int *pulses0 /* I data: nonnegative pulse amplitudes */ +); + +/* Shell decoder, operates on one shell code frame of 16 pulses */ +void silk_shell_decoder( + opus_int *pulses0, /* O data: nonnegative pulse amplitudes */ + ec_dec *psRangeDec, /* I/O Compressor data structure */ + const opus_int pulses4 /* I number of pulses per pulse-subframe */ +); + +/* Gain scalar quantization with hysteresis, uniform on log scale */ +void silk_gains_quant( + opus_int8 ind[ MAX_NB_SUBFR ], /* O gain indices */ + opus_int32 gain_Q16[ MAX_NB_SUBFR ], /* I/O gains (quantized out) */ + opus_int8 *prev_ind, /* I/O last index in previous frame */ + const opus_int conditional, /* I first gain is delta coded if 1 */ + const opus_int nb_subfr /* I number of subframes */ +); + +/* Gains scalar dequantization, uniform on log scale */ +void silk_gains_dequant( + opus_int32 gain_Q16[ MAX_NB_SUBFR ], /* O quantized gains */ + const opus_int8 ind[ MAX_NB_SUBFR ], /* I gain indices */ + opus_int8 *prev_ind, /* I/O last index in previous frame */ + const opus_int conditional, /* I first gain is delta coded if 1 */ + const opus_int nb_subfr /* I number of subframes */ +); + +/* Compute unique identifier of gain indices vector */ +opus_int32 silk_gains_ID( /* O returns unique identifier of gains */ + const opus_int8 ind[ MAX_NB_SUBFR ], /* I gain indices */ + const opus_int nb_subfr /* I number of subframes */ +); + +/* Interpolate two vectors */ +void silk_interpolate( + opus_int16 xi[ MAX_LPC_ORDER ], /* O interpolated vector */ + const opus_int16 x0[ MAX_LPC_ORDER ], /* I first vector */ + const opus_int16 x1[ MAX_LPC_ORDER ], /* I second vector */ + const opus_int ifact_Q2, /* I interp. factor, weight on 2nd vector */ + const opus_int d /* I number of parameters */ +); + +/* LTP tap quantizer */ +void silk_quant_LTP_gains( + opus_int16 B_Q14[ MAX_NB_SUBFR * LTP_ORDER ], /* I/O (un)quantized LTP gains */ + opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook Index */ + opus_int8 *periodicity_index, /* O Periodicity Index */ + opus_int32 *sum_gain_dB_Q7, /* I/O Cumulative max prediction gain */ + const opus_int32 W_Q18[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ], /* I Error Weights in Q18 */ + opus_int mu_Q9, /* I Mu value (R/D tradeoff) */ + opus_int lowComplexity, /* I Flag for low complexity */ + const opus_int nb_subfr /* I number of subframes */ +); + +/* Entropy constrained matrix-weighted VQ, for a single input data vector */ +void silk_VQ_WMat_EC( + opus_int8 *ind, /* O index of best codebook vector */ + opus_int32 *rate_dist_Q14, /* O best weighted quant error + mu * rate */ + opus_int *gain_Q7, /* O sum of absolute LTP coefficients */ + const opus_int16 *in_Q14, /* I input vector to be quantized */ + const opus_int32 *W_Q18, /* I weighting matrix */ + const opus_int8 *cb_Q7, /* I codebook */ + const opus_uint8 *cb_gain_Q7, /* I codebook effective gain */ + const opus_uint8 *cl_Q5, /* I code length for each codebook vector */ + const opus_int mu_Q9, /* I tradeoff betw. weighted error and rate */ + const opus_int32 max_gain_Q7, /* I maximum sum of absolute LTP coefficients */ + opus_int L /* I number of vectors in codebook */ +); + +/************************************/ +/* Noise shaping quantization (NSQ) */ +/************************************/ +void silk_NSQ( + const silk_encoder_state *psEncC, /* I/O Encoder State */ + silk_nsq_state *NSQ, /* I/O NSQ state */ + SideInfoIndices *psIndices, /* I/O Quantization Indices */ + const opus_int32 x_Q3[], /* I Prefiltered input signal */ + opus_int8 pulses[], /* O Quantized pulse signal */ + const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ + const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ + const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ + const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ + const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ + const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ + const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ + const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ + const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ + const opus_int LTP_scale_Q14 /* I LTP state scaling */ +); + +/* Noise shaping using delayed decision */ +void silk_NSQ_del_dec( + const silk_encoder_state *psEncC, /* I/O Encoder State */ + silk_nsq_state *NSQ, /* I/O NSQ state */ + SideInfoIndices *psIndices, /* I/O Quantization Indices */ + const opus_int32 x_Q3[], /* I Prefiltered input signal */ + opus_int8 pulses[], /* O Quantized pulse signal */ + const opus_int16 PredCoef_Q12[ 2 * MAX_LPC_ORDER ], /* I Short term prediction coefs */ + const opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ], /* I Long term prediction coefs */ + const opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ], /* I Noise shaping coefs */ + const opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ], /* I Long term shaping coefs */ + const opus_int Tilt_Q14[ MAX_NB_SUBFR ], /* I Spectral tilt */ + const opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ], /* I Low frequency shaping coefs */ + const opus_int32 Gains_Q16[ MAX_NB_SUBFR ], /* I Quantization step sizes */ + const opus_int pitchL[ MAX_NB_SUBFR ], /* I Pitch lags */ + const opus_int Lambda_Q10, /* I Rate/distortion tradeoff */ + const opus_int LTP_scale_Q14 /* I LTP state scaling */ +); + +/************/ +/* Silk VAD */ +/************/ +/* Initialize the Silk VAD */ +opus_int silk_VAD_Init( /* O Return value, 0 if success */ + silk_VAD_state *psSilk_VAD /* I/O Pointer to Silk VAD state */ +); + +/* Get speech activity level in Q8 */ +opus_int silk_VAD_GetSA_Q8( /* O Return value, 0 if success */ + silk_encoder_state *psEncC, /* I/O Encoder state */ + const opus_int16 pIn[] /* I PCM input */ +); + +/* Low-pass filter with variable cutoff frequency based on */ +/* piece-wise linear interpolation between elliptic filters */ +/* Start by setting transition_frame_no = 1; */ +void silk_LP_variable_cutoff( + silk_LP_state *psLP, /* I/O LP filter state */ + opus_int16 *frame, /* I/O Low-pass filtered output signal */ + const opus_int frame_length /* I Frame length */ +); + +/******************/ +/* NLSF Quantizer */ +/******************/ +/* Limit, stabilize, convert and quantize NLSFs */ +void silk_process_NLSFs( + silk_encoder_state *psEncC, /* I/O Encoder state */ + opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ], /* O Prediction coefficients */ + opus_int16 pNLSF_Q15[ MAX_LPC_ORDER ], /* I/O Normalized LSFs (quant out) (0 - (2^15-1)) */ + const opus_int16 prev_NLSFq_Q15[ MAX_LPC_ORDER ] /* I Previous Normalized LSFs (0 - (2^15-1)) */ +); + +opus_int32 silk_NLSF_encode( /* O Returns RD value in Q25 */ + opus_int8 *NLSFIndices, /* I Codebook path vector [ LPC_ORDER + 1 ] */ + opus_int16 *pNLSF_Q15, /* I/O Quantized NLSF vector [ LPC_ORDER ] */ + const silk_NLSF_CB_struct *psNLSF_CB, /* I Codebook object */ + const opus_int16 *pW_QW, /* I NLSF weight vector [ LPC_ORDER ] */ + const opus_int NLSF_mu_Q20, /* I Rate weight for the RD optimization */ + const opus_int nSurvivors, /* I Max survivors after first stage */ + const opus_int signalType /* I Signal type: 0/1/2 */ +); + +/* Compute quantization errors for an LPC_order element input vector for a VQ codebook */ +void silk_NLSF_VQ( + opus_int32 err_Q26[], /* O Quantization errors [K] */ + const opus_int16 in_Q15[], /* I Input vectors to be quantized [LPC_order] */ + const opus_uint8 pCB_Q8[], /* I Codebook vectors [K*LPC_order] */ + const opus_int K, /* I Number of codebook vectors */ + const opus_int LPC_order /* I Number of LPCs */ +); + +/* Delayed-decision quantizer for NLSF residuals */ +opus_int32 silk_NLSF_del_dec_quant( /* O Returns RD value in Q25 */ + opus_int8 indices[], /* O Quantization indices [ order ] */ + const opus_int16 x_Q10[], /* I Input [ order ] */ + const opus_int16 w_Q5[], /* I Weights [ order ] */ + const opus_uint8 pred_coef_Q8[], /* I Backward predictor coefs [ order ] */ + const opus_int16 ec_ix[], /* I Indices to entropy coding tables [ order ] */ + const opus_uint8 ec_rates_Q5[], /* I Rates [] */ + const opus_int quant_step_size_Q16, /* I Quantization step size */ + const opus_int16 inv_quant_step_size_Q6, /* I Inverse quantization step size */ + const opus_int32 mu_Q20, /* I R/D tradeoff */ + const opus_int16 order /* I Number of input values */ +); + +/* Unpack predictor values and indices for entropy coding tables */ +void silk_NLSF_unpack( + opus_int16 ec_ix[], /* O Indices to entropy tables [ LPC_ORDER ] */ + opus_uint8 pred_Q8[], /* O LSF predictor [ LPC_ORDER ] */ + const silk_NLSF_CB_struct *psNLSF_CB, /* I Codebook object */ + const opus_int CB1_index /* I Index of vector in first LSF codebook */ +); + +/***********************/ +/* NLSF vector decoder */ +/***********************/ +void silk_NLSF_decode( + opus_int16 *pNLSF_Q15, /* O Quantized NLSF vector [ LPC_ORDER ] */ + opus_int8 *NLSFIndices, /* I Codebook path vector [ LPC_ORDER + 1 ] */ + const silk_NLSF_CB_struct *psNLSF_CB /* I Codebook object */ +); + +/****************************************************/ +/* Decoder Functions */ +/****************************************************/ +opus_int silk_init_decoder( + silk_decoder_state *psDec /* I/O Decoder state pointer */ +); + +/* Set decoder sampling rate */ +opus_int silk_decoder_set_fs( + silk_decoder_state *psDec, /* I/O Decoder state pointer */ + opus_int fs_kHz, /* I Sampling frequency (kHz) */ + opus_int32 fs_API_Hz /* I API Sampling frequency (Hz) */ +); + +/****************/ +/* Decode frame */ +/****************/ +opus_int silk_decode_frame( + silk_decoder_state *psDec, /* I/O Pointer to Silk decoder state */ + ec_dec *psRangeDec, /* I/O Compressor data structure */ + opus_int16 pOut[], /* O Pointer to output speech frame */ + opus_int32 *pN, /* O Pointer to size of output frame */ + opus_int lostFlag, /* I 0: no loss, 1 loss, 2 decode fec */ + opus_int condCoding /* I The type of conditional coding to use */ +); + +/* Decode indices from bitstream */ +void silk_decode_indices( + silk_decoder_state *psDec, /* I/O State */ + ec_dec *psRangeDec, /* I/O Compressor data structure */ + opus_int FrameIndex, /* I Frame number */ + opus_int decode_LBRR, /* I Flag indicating LBRR data is being decoded */ + opus_int condCoding /* I The type of conditional coding to use */ +); + +/* Decode parameters from payload */ +void silk_decode_parameters( + silk_decoder_state *psDec, /* I/O State */ + silk_decoder_control *psDecCtrl, /* I/O Decoder control */ + opus_int condCoding /* I The type of conditional coding to use */ +); + +/* Core decoder. Performs inverse NSQ operation LTP + LPC */ +void silk_decode_core( + silk_decoder_state *psDec, /* I/O Decoder state */ + silk_decoder_control *psDecCtrl, /* I Decoder control */ + opus_int16 xq[], /* O Decoded speech */ + const opus_int pulses[ MAX_FRAME_LENGTH ] /* I Pulse signal */ +); + +/* Decode quantization indices of excitation (Shell coding) */ +void silk_decode_pulses( + ec_dec *psRangeDec, /* I/O Compressor data structure */ + opus_int pulses[], /* O Excitation signal */ + const opus_int signalType, /* I Sigtype */ + const opus_int quantOffsetType, /* I quantOffsetType */ + const opus_int frame_length /* I Frame length */ +); + +/******************/ +/* CNG */ +/******************/ + +/* Reset CNG */ +void silk_CNG_Reset( + silk_decoder_state *psDec /* I/O Decoder state */ +); + +/* Updates CNG estimate, and applies the CNG when packet was lost */ +void silk_CNG( + silk_decoder_state *psDec, /* I/O Decoder state */ + silk_decoder_control *psDecCtrl, /* I/O Decoder control */ + opus_int16 frame[], /* I/O Signal */ + opus_int length /* I Length of residual */ +); + +/* Encoding of various parameters */ +void silk_encode_indices( + silk_encoder_state *psEncC, /* I/O Encoder state */ + ec_enc *psRangeEnc, /* I/O Compressor data structure */ + opus_int FrameIndex, /* I Frame number */ + opus_int encode_LBRR, /* I Flag indicating LBRR data is being encoded */ + opus_int condCoding /* I The type of conditional coding to use */ +); + +#endif diff --git a/src/opus-1.1/silk/pitch_est_defines.h b/src/opus-1.1/silk/pitch_est_defines.h new file mode 100644 index 00000000..e1e4b5d7 --- /dev/null +++ b/src/opus-1.1/silk/pitch_est_defines.h @@ -0,0 +1,88 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifndef SILK_PE_DEFINES_H +#define SILK_PE_DEFINES_H + +#include "SigProc_FIX.h" + +/********************************************************/ +/* Definitions for pitch estimator */ +/********************************************************/ + +#define PE_MAX_FS_KHZ 16 /* Maximum sampling frequency used */ + +#define PE_MAX_NB_SUBFR 4 +#define PE_SUBFR_LENGTH_MS 5 /* 5 ms */ + +#define PE_LTP_MEM_LENGTH_MS ( 4 * PE_SUBFR_LENGTH_MS ) + +#define PE_MAX_FRAME_LENGTH_MS ( PE_LTP_MEM_LENGTH_MS + PE_MAX_NB_SUBFR * PE_SUBFR_LENGTH_MS ) +#define PE_MAX_FRAME_LENGTH ( PE_MAX_FRAME_LENGTH_MS * PE_MAX_FS_KHZ ) +#define PE_MAX_FRAME_LENGTH_ST_1 ( PE_MAX_FRAME_LENGTH >> 2 ) +#define PE_MAX_FRAME_LENGTH_ST_2 ( PE_MAX_FRAME_LENGTH >> 1 ) + +#define PE_MAX_LAG_MS 18 /* 18 ms -> 56 Hz */ +#define PE_MIN_LAG_MS 2 /* 2 ms -> 500 Hz */ +#define PE_MAX_LAG ( PE_MAX_LAG_MS * PE_MAX_FS_KHZ ) +#define PE_MIN_LAG ( PE_MIN_LAG_MS * PE_MAX_FS_KHZ ) + +#define PE_D_SRCH_LENGTH 24 + +#define PE_NB_STAGE3_LAGS 5 + +#define PE_NB_CBKS_STAGE2 3 +#define PE_NB_CBKS_STAGE2_EXT 11 + +#define PE_NB_CBKS_STAGE3_MAX 34 +#define PE_NB_CBKS_STAGE3_MID 24 +#define PE_NB_CBKS_STAGE3_MIN 16 + +#define PE_NB_CBKS_STAGE3_10MS 12 +#define PE_NB_CBKS_STAGE2_10MS 3 + +#define PE_SHORTLAG_BIAS 0.2f /* for logarithmic weighting */ +#define PE_PREVLAG_BIAS 0.2f /* for logarithmic weighting */ +#define PE_FLATCONTOUR_BIAS 0.05f + +#define SILK_PE_MIN_COMPLEX 0 +#define SILK_PE_MID_COMPLEX 1 +#define SILK_PE_MAX_COMPLEX 2 + +/* Tables for 20 ms frames */ +extern const opus_int8 silk_CB_lags_stage2[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE2_EXT ]; +extern const opus_int8 silk_CB_lags_stage3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ]; +extern const opus_int8 silk_Lag_range_stage3[ SILK_PE_MAX_COMPLEX + 1 ] [ PE_MAX_NB_SUBFR ][ 2 ]; +extern const opus_int8 silk_nb_cbk_searchs_stage3[ SILK_PE_MAX_COMPLEX + 1 ]; + +/* Tables for 10 ms frames */ +extern const opus_int8 silk_CB_lags_stage2_10_ms[ PE_MAX_NB_SUBFR >> 1][ 3 ]; +extern const opus_int8 silk_CB_lags_stage3_10_ms[ PE_MAX_NB_SUBFR >> 1 ][ 12 ]; +extern const opus_int8 silk_Lag_range_stage3_10_ms[ PE_MAX_NB_SUBFR >> 1 ][ 2 ]; + +#endif + diff --git a/src/opus-1.1/silk/pitch_est_tables.c b/src/opus-1.1/silk/pitch_est_tables.c new file mode 100644 index 00000000..81a8baca --- /dev/null +++ b/src/opus-1.1/silk/pitch_est_tables.c @@ -0,0 +1,99 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "typedef.h" +#include "pitch_est_defines.h" + +const opus_int8 silk_CB_lags_stage2_10_ms[ PE_MAX_NB_SUBFR >> 1][ PE_NB_CBKS_STAGE2_10MS ] = +{ + {0, 1, 0}, + {0, 0, 1} +}; + +const opus_int8 silk_CB_lags_stage3_10_ms[ PE_MAX_NB_SUBFR >> 1 ][ PE_NB_CBKS_STAGE3_10MS ] = +{ + { 0, 0, 1,-1, 1,-1, 2,-2, 2,-2, 3,-3}, + { 0, 1, 0, 1,-1, 2,-1, 2,-2, 3,-2, 3} +}; + +const opus_int8 silk_Lag_range_stage3_10_ms[ PE_MAX_NB_SUBFR >> 1 ][ 2 ] = +{ + {-3, 7}, + {-2, 7} +}; + +const opus_int8 silk_CB_lags_stage2[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE2_EXT ] = +{ + {0, 2,-1,-1,-1, 0, 0, 1, 1, 0, 1}, + {0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0}, + {0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0}, + {0,-1, 2, 1, 0, 1, 1, 0, 0,-1,-1} +}; + +const opus_int8 silk_CB_lags_stage3[ PE_MAX_NB_SUBFR ][ PE_NB_CBKS_STAGE3_MAX ] = +{ + {0, 0, 1,-1, 0, 1,-1, 0,-1, 1,-2, 2,-2,-2, 2,-3, 2, 3,-3,-4, 3,-4, 4, 4,-5, 5,-6,-5, 6,-7, 6, 5, 8,-9}, + {0, 0, 1, 0, 0, 0, 0, 0, 0, 0,-1, 1, 0, 0, 1,-1, 0, 1,-1,-1, 1,-1, 2, 1,-1, 2,-2,-2, 2,-2, 2, 2, 3,-3}, + {0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1,-1, 1, 0, 0, 2, 1,-1, 2,-1,-1, 2,-1, 2, 2,-1, 3,-2,-2,-2, 3}, + {0, 1, 0, 0, 1, 0, 1,-1, 2,-1, 2,-1, 2, 3,-2, 3,-2,-2, 4, 4,-3, 5,-3,-4, 6,-4, 6, 5,-5, 8,-6,-5,-7, 9} +}; + +const opus_int8 silk_Lag_range_stage3[ SILK_PE_MAX_COMPLEX + 1 ] [ PE_MAX_NB_SUBFR ][ 2 ] = +{ + /* Lags to search for low number of stage3 cbks */ + { + {-5,8}, + {-1,6}, + {-1,6}, + {-4,10} + }, + /* Lags to search for middle number of stage3 cbks */ + { + {-6,10}, + {-2,6}, + {-1,6}, + {-5,10} + }, + /* Lags to search for max number of stage3 cbks */ + { + {-9,12}, + {-3,7}, + {-2,7}, + {-7,13} + } +}; + +const opus_int8 silk_nb_cbk_searchs_stage3[ SILK_PE_MAX_COMPLEX + 1 ] = +{ + PE_NB_CBKS_STAGE3_MIN, + PE_NB_CBKS_STAGE3_MID, + PE_NB_CBKS_STAGE3_MAX +}; diff --git a/src/opus-1.1/silk/process_NLSFs.c b/src/opus-1.1/silk/process_NLSFs.c new file mode 100644 index 00000000..c27cf030 --- /dev/null +++ b/src/opus-1.1/silk/process_NLSFs.c @@ -0,0 +1,105 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main.h" + +/* Limit, stabilize, convert and quantize NLSFs */ +void silk_process_NLSFs( + silk_encoder_state *psEncC, /* I/O Encoder state */ + opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ], /* O Prediction coefficients */ + opus_int16 pNLSF_Q15[ MAX_LPC_ORDER ], /* I/O Normalized LSFs (quant out) (0 - (2^15-1)) */ + const opus_int16 prev_NLSFq_Q15[ MAX_LPC_ORDER ] /* I Previous Normalized LSFs (0 - (2^15-1)) */ +) +{ + opus_int i, doInterpolate; + opus_int NLSF_mu_Q20; + opus_int32 i_sqr_Q15; + opus_int16 pNLSF0_temp_Q15[ MAX_LPC_ORDER ]; + opus_int16 pNLSFW_QW[ MAX_LPC_ORDER ]; + opus_int16 pNLSFW0_temp_QW[ MAX_LPC_ORDER ]; + + silk_assert( psEncC->speech_activity_Q8 >= 0 ); + silk_assert( psEncC->speech_activity_Q8 <= SILK_FIX_CONST( 1.0, 8 ) ); + silk_assert( psEncC->useInterpolatedNLSFs == 1 || psEncC->indices.NLSFInterpCoef_Q2 == ( 1 << 2 ) ); + + /***********************/ + /* Calculate mu values */ + /***********************/ + /* NLSF_mu = 0.003 - 0.0015 * psEnc->speech_activity; */ + NLSF_mu_Q20 = silk_SMLAWB( SILK_FIX_CONST( 0.003, 20 ), SILK_FIX_CONST( -0.001, 28 ), psEncC->speech_activity_Q8 ); + if( psEncC->nb_subfr == 2 ) { + /* Multiply by 1.5 for 10 ms packets */ + NLSF_mu_Q20 = silk_ADD_RSHIFT( NLSF_mu_Q20, NLSF_mu_Q20, 1 ); + } + + silk_assert( NLSF_mu_Q20 > 0 ); + silk_assert( NLSF_mu_Q20 <= SILK_FIX_CONST( 0.005, 20 ) ); + + /* Calculate NLSF weights */ + silk_NLSF_VQ_weights_laroia( pNLSFW_QW, pNLSF_Q15, psEncC->predictLPCOrder ); + + /* Update NLSF weights for interpolated NLSFs */ + doInterpolate = ( psEncC->useInterpolatedNLSFs == 1 ) && ( psEncC->indices.NLSFInterpCoef_Q2 < 4 ); + if( doInterpolate ) { + /* Calculate the interpolated NLSF vector for the first half */ + silk_interpolate( pNLSF0_temp_Q15, prev_NLSFq_Q15, pNLSF_Q15, + psEncC->indices.NLSFInterpCoef_Q2, psEncC->predictLPCOrder ); + + /* Calculate first half NLSF weights for the interpolated NLSFs */ + silk_NLSF_VQ_weights_laroia( pNLSFW0_temp_QW, pNLSF0_temp_Q15, psEncC->predictLPCOrder ); + + /* Update NLSF weights with contribution from first half */ + i_sqr_Q15 = silk_LSHIFT( silk_SMULBB( psEncC->indices.NLSFInterpCoef_Q2, psEncC->indices.NLSFInterpCoef_Q2 ), 11 ); + for( i = 0; i < psEncC->predictLPCOrder; i++ ) { + pNLSFW_QW[ i ] = silk_SMLAWB( silk_RSHIFT( pNLSFW_QW[ i ], 1 ), (opus_int32)pNLSFW0_temp_QW[ i ], i_sqr_Q15 ); + silk_assert( pNLSFW_QW[ i ] >= 1 ); + } + } + + silk_NLSF_encode( psEncC->indices.NLSFIndices, pNLSF_Q15, psEncC->psNLSF_CB, pNLSFW_QW, + NLSF_mu_Q20, psEncC->NLSF_MSVQ_Survivors, psEncC->indices.signalType ); + + /* Convert quantized NLSFs back to LPC coefficients */ + silk_NLSF2A( PredCoef_Q12[ 1 ], pNLSF_Q15, psEncC->predictLPCOrder ); + + if( doInterpolate ) { + /* Calculate the interpolated, quantized LSF vector for the first half */ + silk_interpolate( pNLSF0_temp_Q15, prev_NLSFq_Q15, pNLSF_Q15, + psEncC->indices.NLSFInterpCoef_Q2, psEncC->predictLPCOrder ); + + /* Convert back to LPC coefficients */ + silk_NLSF2A( PredCoef_Q12[ 0 ], pNLSF0_temp_Q15, psEncC->predictLPCOrder ); + + } else { + /* Copy LPC coefficients for first half from second half */ + silk_memcpy( PredCoef_Q12[ 0 ], PredCoef_Q12[ 1 ], psEncC->predictLPCOrder * sizeof( opus_int16 ) ); + } +} diff --git a/src/opus-1.1/silk/quant_LTP_gains.c b/src/opus-1.1/silk/quant_LTP_gains.c new file mode 100644 index 00000000..fd0870da --- /dev/null +++ b/src/opus-1.1/silk/quant_LTP_gains.c @@ -0,0 +1,128 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main.h" +#include "tuning_parameters.h" + +void silk_quant_LTP_gains( + opus_int16 B_Q14[ MAX_NB_SUBFR * LTP_ORDER ], /* I/O (un)quantized LTP gains */ + opus_int8 cbk_index[ MAX_NB_SUBFR ], /* O Codebook Index */ + opus_int8 *periodicity_index, /* O Periodicity Index */ + opus_int32 *sum_log_gain_Q7, /* I/O Cumulative max prediction gain */ + const opus_int32 W_Q18[ MAX_NB_SUBFR*LTP_ORDER*LTP_ORDER ], /* I Error Weights in Q18 */ + opus_int mu_Q9, /* I Mu value (R/D tradeoff) */ + opus_int lowComplexity, /* I Flag for low complexity */ + const opus_int nb_subfr /* I number of subframes */ +) +{ + opus_int j, k, cbk_size; + opus_int8 temp_idx[ MAX_NB_SUBFR ]; + const opus_uint8 *cl_ptr_Q5; + const opus_int8 *cbk_ptr_Q7; + const opus_uint8 *cbk_gain_ptr_Q7; + const opus_int16 *b_Q14_ptr; + const opus_int32 *W_Q18_ptr; + opus_int32 rate_dist_Q14_subfr, rate_dist_Q14, min_rate_dist_Q14; + opus_int32 sum_log_gain_tmp_Q7, best_sum_log_gain_Q7, max_gain_Q7, gain_Q7; + + /***************************************************/ + /* iterate over different codebooks with different */ + /* rates/distortions, and choose best */ + /***************************************************/ + min_rate_dist_Q14 = silk_int32_MAX; + best_sum_log_gain_Q7 = 0; + for( k = 0; k < 3; k++ ) { + /* Safety margin for pitch gain control, to take into account factors + such as state rescaling/rewhitening. */ + opus_int32 gain_safety = SILK_FIX_CONST( 0.4, 7 ); + + cl_ptr_Q5 = silk_LTP_gain_BITS_Q5_ptrs[ k ]; + cbk_ptr_Q7 = silk_LTP_vq_ptrs_Q7[ k ]; + cbk_gain_ptr_Q7 = silk_LTP_vq_gain_ptrs_Q7[ k ]; + cbk_size = silk_LTP_vq_sizes[ k ]; + + /* Set up pointer to first subframe */ + W_Q18_ptr = W_Q18; + b_Q14_ptr = B_Q14; + + rate_dist_Q14 = 0; + sum_log_gain_tmp_Q7 = *sum_log_gain_Q7; + for( j = 0; j < nb_subfr; j++ ) { + max_gain_Q7 = silk_log2lin( ( SILK_FIX_CONST( MAX_SUM_LOG_GAIN_DB / 6.0, 7 ) - sum_log_gain_tmp_Q7 ) + + SILK_FIX_CONST( 7, 7 ) ) - gain_safety; + + silk_VQ_WMat_EC( + &temp_idx[ j ], /* O index of best codebook vector */ + &rate_dist_Q14_subfr, /* O best weighted quantization error + mu * rate */ + &gain_Q7, /* O sum of absolute LTP coefficients */ + b_Q14_ptr, /* I input vector to be quantized */ + W_Q18_ptr, /* I weighting matrix */ + cbk_ptr_Q7, /* I codebook */ + cbk_gain_ptr_Q7, /* I codebook effective gains */ + cl_ptr_Q5, /* I code length for each codebook vector */ + mu_Q9, /* I tradeoff between weighted error and rate */ + max_gain_Q7, /* I maximum sum of absolute LTP coefficients */ + cbk_size /* I number of vectors in codebook */ + ); + + rate_dist_Q14 = silk_ADD_POS_SAT32( rate_dist_Q14, rate_dist_Q14_subfr ); + sum_log_gain_tmp_Q7 = silk_max(0, sum_log_gain_tmp_Q7 + + silk_lin2log( gain_safety + gain_Q7 ) - SILK_FIX_CONST( 7, 7 )); + + b_Q14_ptr += LTP_ORDER; + W_Q18_ptr += LTP_ORDER * LTP_ORDER; + } + + /* Avoid never finding a codebook */ + rate_dist_Q14 = silk_min( silk_int32_MAX - 1, rate_dist_Q14 ); + + if( rate_dist_Q14 < min_rate_dist_Q14 ) { + min_rate_dist_Q14 = rate_dist_Q14; + *periodicity_index = (opus_int8)k; + silk_memcpy( cbk_index, temp_idx, nb_subfr * sizeof( opus_int8 ) ); + best_sum_log_gain_Q7 = sum_log_gain_tmp_Q7; + } + + /* Break early in low-complexity mode if rate distortion is below threshold */ + if( lowComplexity && ( rate_dist_Q14 < silk_LTP_gain_middle_avg_RD_Q14 ) ) { + break; + } + } + + cbk_ptr_Q7 = silk_LTP_vq_ptrs_Q7[ *periodicity_index ]; + for( j = 0; j < nb_subfr; j++ ) { + for( k = 0; k < LTP_ORDER; k++ ) { + B_Q14[ j * LTP_ORDER + k ] = silk_LSHIFT( cbk_ptr_Q7[ cbk_index[ j ] * LTP_ORDER + k ], 7 ); + } + } + *sum_log_gain_Q7 = best_sum_log_gain_Q7; +} + diff --git a/src/opus-1.1/silk/resampler.c b/src/opus-1.1/silk/resampler.c new file mode 100644 index 00000000..374fbb37 --- /dev/null +++ b/src/opus-1.1/silk/resampler.c @@ -0,0 +1,215 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* + * Matrix of resampling methods used: + * Fs_out (kHz) + * 8 12 16 24 48 + * + * 8 C UF U UF UF + * 12 AF C UF U UF + * Fs_in (kHz) 16 D AF C UF UF + * 24 AF D AF C U + * 48 AF AF AF D C + * + * C -> Copy (no resampling) + * D -> Allpass-based 2x downsampling + * U -> Allpass-based 2x upsampling + * UF -> Allpass-based 2x upsampling followed by FIR interpolation + * AF -> AR2 filter followed by FIR interpolation + */ + +#include "resampler_private.h" + +/* Tables with delay compensation values to equalize total delay for different modes */ +static const opus_int8 delay_matrix_enc[ 5 ][ 3 ] = { +/* in \ out 8 12 16 */ +/* 8 */ { 6, 0, 3 }, +/* 12 */ { 0, 7, 3 }, +/* 16 */ { 0, 1, 10 }, +/* 24 */ { 0, 2, 6 }, +/* 48 */ { 18, 10, 12 } +}; + +static const opus_int8 delay_matrix_dec[ 3 ][ 5 ] = { +/* in \ out 8 12 16 24 48 */ +/* 8 */ { 4, 0, 2, 0, 0 }, +/* 12 */ { 0, 9, 4, 7, 4 }, +/* 16 */ { 0, 3, 12, 7, 7 } +}; + +/* Simple way to make [8000, 12000, 16000, 24000, 48000] to [0, 1, 2, 3, 4] */ +#define rateID(R) ( ( ( ((R)>>12) - ((R)>16000) ) >> ((R)>24000) ) - 1 ) + +#define USE_silk_resampler_copy (0) +#define USE_silk_resampler_private_up2_HQ_wrapper (1) +#define USE_silk_resampler_private_IIR_FIR (2) +#define USE_silk_resampler_private_down_FIR (3) + +/* Initialize/reset the resampler state for a given pair of input/output sampling rates */ +opus_int silk_resampler_init( + silk_resampler_state_struct *S, /* I/O Resampler state */ + opus_int32 Fs_Hz_in, /* I Input sampling rate (Hz) */ + opus_int32 Fs_Hz_out, /* I Output sampling rate (Hz) */ + opus_int forEnc /* I If 1: encoder; if 0: decoder */ +) +{ + opus_int up2x; + + /* Clear state */ + silk_memset( S, 0, sizeof( silk_resampler_state_struct ) ); + + /* Input checking */ + if( forEnc ) { + if( ( Fs_Hz_in != 8000 && Fs_Hz_in != 12000 && Fs_Hz_in != 16000 && Fs_Hz_in != 24000 && Fs_Hz_in != 48000 ) || + ( Fs_Hz_out != 8000 && Fs_Hz_out != 12000 && Fs_Hz_out != 16000 ) ) { + silk_assert( 0 ); + return -1; + } + S->inputDelay = delay_matrix_enc[ rateID( Fs_Hz_in ) ][ rateID( Fs_Hz_out ) ]; + } else { + if( ( Fs_Hz_in != 8000 && Fs_Hz_in != 12000 && Fs_Hz_in != 16000 ) || + ( Fs_Hz_out != 8000 && Fs_Hz_out != 12000 && Fs_Hz_out != 16000 && Fs_Hz_out != 24000 && Fs_Hz_out != 48000 ) ) { + silk_assert( 0 ); + return -1; + } + S->inputDelay = delay_matrix_dec[ rateID( Fs_Hz_in ) ][ rateID( Fs_Hz_out ) ]; + } + + S->Fs_in_kHz = silk_DIV32_16( Fs_Hz_in, 1000 ); + S->Fs_out_kHz = silk_DIV32_16( Fs_Hz_out, 1000 ); + + /* Number of samples processed per batch */ + S->batchSize = S->Fs_in_kHz * RESAMPLER_MAX_BATCH_SIZE_MS; + + /* Find resampler with the right sampling ratio */ + up2x = 0; + if( Fs_Hz_out > Fs_Hz_in ) { + /* Upsample */ + if( Fs_Hz_out == silk_MUL( Fs_Hz_in, 2 ) ) { /* Fs_out : Fs_in = 2 : 1 */ + /* Special case: directly use 2x upsampler */ + S->resampler_function = USE_silk_resampler_private_up2_HQ_wrapper; + } else { + /* Default resampler */ + S->resampler_function = USE_silk_resampler_private_IIR_FIR; + up2x = 1; + } + } else if ( Fs_Hz_out < Fs_Hz_in ) { + /* Downsample */ + S->resampler_function = USE_silk_resampler_private_down_FIR; + if( silk_MUL( Fs_Hz_out, 4 ) == silk_MUL( Fs_Hz_in, 3 ) ) { /* Fs_out : Fs_in = 3 : 4 */ + S->FIR_Fracs = 3; + S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR0; + S->Coefs = silk_Resampler_3_4_COEFS; + } else if( silk_MUL( Fs_Hz_out, 3 ) == silk_MUL( Fs_Hz_in, 2 ) ) { /* Fs_out : Fs_in = 2 : 3 */ + S->FIR_Fracs = 2; + S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR0; + S->Coefs = silk_Resampler_2_3_COEFS; + } else if( silk_MUL( Fs_Hz_out, 2 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 2 */ + S->FIR_Fracs = 1; + S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR1; + S->Coefs = silk_Resampler_1_2_COEFS; + } else if( silk_MUL( Fs_Hz_out, 3 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 3 */ + S->FIR_Fracs = 1; + S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR2; + S->Coefs = silk_Resampler_1_3_COEFS; + } else if( silk_MUL( Fs_Hz_out, 4 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 4 */ + S->FIR_Fracs = 1; + S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR2; + S->Coefs = silk_Resampler_1_4_COEFS; + } else if( silk_MUL( Fs_Hz_out, 6 ) == Fs_Hz_in ) { /* Fs_out : Fs_in = 1 : 6 */ + S->FIR_Fracs = 1; + S->FIR_Order = RESAMPLER_DOWN_ORDER_FIR2; + S->Coefs = silk_Resampler_1_6_COEFS; + } else { + /* None available */ + silk_assert( 0 ); + return -1; + } + } else { + /* Input and output sampling rates are equal: copy */ + S->resampler_function = USE_silk_resampler_copy; + } + + /* Ratio of input/output samples */ + S->invRatio_Q16 = silk_LSHIFT32( silk_DIV32( silk_LSHIFT32( Fs_Hz_in, 14 + up2x ), Fs_Hz_out ), 2 ); + /* Make sure the ratio is rounded up */ + while( silk_SMULWW( S->invRatio_Q16, Fs_Hz_out ) < silk_LSHIFT32( Fs_Hz_in, up2x ) ) { + S->invRatio_Q16++; + } + + return 0; +} + +/* Resampler: convert from one sampling rate to another */ +/* Input and output sampling rate are at most 48000 Hz */ +opus_int silk_resampler( + silk_resampler_state_struct *S, /* I/O Resampler state */ + opus_int16 out[], /* O Output signal */ + const opus_int16 in[], /* I Input signal */ + opus_int32 inLen /* I Number of input samples */ +) +{ + opus_int nSamples; + + /* Need at least 1 ms of input data */ + silk_assert( inLen >= S->Fs_in_kHz ); + /* Delay can't exceed the 1 ms of buffering */ + silk_assert( S->inputDelay <= S->Fs_in_kHz ); + + nSamples = S->Fs_in_kHz - S->inputDelay; + + /* Copy to delay buffer */ + silk_memcpy( &S->delayBuf[ S->inputDelay ], in, nSamples * sizeof( opus_int16 ) ); + + switch( S->resampler_function ) { + case USE_silk_resampler_private_up2_HQ_wrapper: + silk_resampler_private_up2_HQ_wrapper( S, out, S->delayBuf, S->Fs_in_kHz ); + silk_resampler_private_up2_HQ_wrapper( S, &out[ S->Fs_out_kHz ], &in[ nSamples ], inLen - S->Fs_in_kHz ); + break; + case USE_silk_resampler_private_IIR_FIR: + silk_resampler_private_IIR_FIR( S, out, S->delayBuf, S->Fs_in_kHz ); + silk_resampler_private_IIR_FIR( S, &out[ S->Fs_out_kHz ], &in[ nSamples ], inLen - S->Fs_in_kHz ); + break; + case USE_silk_resampler_private_down_FIR: + silk_resampler_private_down_FIR( S, out, S->delayBuf, S->Fs_in_kHz ); + silk_resampler_private_down_FIR( S, &out[ S->Fs_out_kHz ], &in[ nSamples ], inLen - S->Fs_in_kHz ); + break; + default: + silk_memcpy( out, S->delayBuf, S->Fs_in_kHz * sizeof( opus_int16 ) ); + silk_memcpy( &out[ S->Fs_out_kHz ], &in[ nSamples ], ( inLen - S->Fs_in_kHz ) * sizeof( opus_int16 ) ); + } + + /* Copy to delay buffer */ + silk_memcpy( S->delayBuf, &in[ inLen - S->inputDelay ], S->inputDelay * sizeof( opus_int16 ) ); + + return 0; +} diff --git a/src/opus-1.1/silk/resampler_down2.c b/src/opus-1.1/silk/resampler_down2.c new file mode 100644 index 00000000..cec36346 --- /dev/null +++ b/src/opus-1.1/silk/resampler_down2.c @@ -0,0 +1,74 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SigProc_FIX.h" +#include "resampler_rom.h" + +/* Downsample by a factor 2 */ +void silk_resampler_down2( + opus_int32 *S, /* I/O State vector [ 2 ] */ + opus_int16 *out, /* O Output signal [ floor(len/2) ] */ + const opus_int16 *in, /* I Input signal [ len ] */ + opus_int32 inLen /* I Number of input samples */ +) +{ + opus_int32 k, len2 = silk_RSHIFT32( inLen, 1 ); + opus_int32 in32, out32, Y, X; + + silk_assert( silk_resampler_down2_0 > 0 ); + silk_assert( silk_resampler_down2_1 < 0 ); + + /* Internal variables and state are in Q10 format */ + for( k = 0; k < len2; k++ ) { + /* Convert to Q10 */ + in32 = silk_LSHIFT( (opus_int32)in[ 2 * k ], 10 ); + + /* All-pass section for even input sample */ + Y = silk_SUB32( in32, S[ 0 ] ); + X = silk_SMLAWB( Y, Y, silk_resampler_down2_1 ); + out32 = silk_ADD32( S[ 0 ], X ); + S[ 0 ] = silk_ADD32( in32, X ); + + /* Convert to Q10 */ + in32 = silk_LSHIFT( (opus_int32)in[ 2 * k + 1 ], 10 ); + + /* All-pass section for odd input sample, and add to output of previous section */ + Y = silk_SUB32( in32, S[ 1 ] ); + X = silk_SMULWB( Y, silk_resampler_down2_0 ); + out32 = silk_ADD32( out32, S[ 1 ] ); + out32 = silk_ADD32( out32, X ); + S[ 1 ] = silk_ADD32( in32, X ); + + /* Add, convert back to int16 and store to output */ + out[ k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( out32, 11 ) ); + } +} + diff --git a/src/opus-1.1/silk/resampler_down2_3.c b/src/opus-1.1/silk/resampler_down2_3.c new file mode 100644 index 00000000..4342614d --- /dev/null +++ b/src/opus-1.1/silk/resampler_down2_3.c @@ -0,0 +1,103 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SigProc_FIX.h" +#include "resampler_private.h" +#include "stack_alloc.h" + +#define ORDER_FIR 4 + +/* Downsample by a factor 2/3, low quality */ +void silk_resampler_down2_3( + opus_int32 *S, /* I/O State vector [ 6 ] */ + opus_int16 *out, /* O Output signal [ floor(2*inLen/3) ] */ + const opus_int16 *in, /* I Input signal [ inLen ] */ + opus_int32 inLen /* I Number of input samples */ +) +{ + opus_int32 nSamplesIn, counter, res_Q6; + VARDECL( opus_int32, buf ); + opus_int32 *buf_ptr; + SAVE_STACK; + + ALLOC( buf, RESAMPLER_MAX_BATCH_SIZE_IN + ORDER_FIR, opus_int32 ); + + /* Copy buffered samples to start of buffer */ + silk_memcpy( buf, S, ORDER_FIR * sizeof( opus_int32 ) ); + + /* Iterate over blocks of frameSizeIn input samples */ + while( 1 ) { + nSamplesIn = silk_min( inLen, RESAMPLER_MAX_BATCH_SIZE_IN ); + + /* Second-order AR filter (output in Q8) */ + silk_resampler_private_AR2( &S[ ORDER_FIR ], &buf[ ORDER_FIR ], in, + silk_Resampler_2_3_COEFS_LQ, nSamplesIn ); + + /* Interpolate filtered signal */ + buf_ptr = buf; + counter = nSamplesIn; + while( counter > 2 ) { + /* Inner product */ + res_Q6 = silk_SMULWB( buf_ptr[ 0 ], silk_Resampler_2_3_COEFS_LQ[ 2 ] ); + res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 1 ], silk_Resampler_2_3_COEFS_LQ[ 3 ] ); + res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 2 ], silk_Resampler_2_3_COEFS_LQ[ 5 ] ); + res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 3 ], silk_Resampler_2_3_COEFS_LQ[ 4 ] ); + + /* Scale down, saturate and store in output array */ + *out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q6, 6 ) ); + + res_Q6 = silk_SMULWB( buf_ptr[ 1 ], silk_Resampler_2_3_COEFS_LQ[ 4 ] ); + res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 2 ], silk_Resampler_2_3_COEFS_LQ[ 5 ] ); + res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 3 ], silk_Resampler_2_3_COEFS_LQ[ 3 ] ); + res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 4 ], silk_Resampler_2_3_COEFS_LQ[ 2 ] ); + + /* Scale down, saturate and store in output array */ + *out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q6, 6 ) ); + + buf_ptr += 3; + counter -= 3; + } + + in += nSamplesIn; + inLen -= nSamplesIn; + + if( inLen > 0 ) { + /* More iterations to do; copy last part of filtered signal to beginning of buffer */ + silk_memcpy( buf, &buf[ nSamplesIn ], ORDER_FIR * sizeof( opus_int32 ) ); + } else { + break; + } + } + + /* Copy last part of filtered signal to the state for the next call */ + silk_memcpy( S, &buf[ nSamplesIn ], ORDER_FIR * sizeof( opus_int32 ) ); + RESTORE_STACK; +} diff --git a/src/opus-1.1/silk/resampler_private.h b/src/opus-1.1/silk/resampler_private.h new file mode 100644 index 00000000..422a7d9d --- /dev/null +++ b/src/opus-1.1/silk/resampler_private.h @@ -0,0 +1,88 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifndef SILK_RESAMPLER_PRIVATE_H +#define SILK_RESAMPLER_PRIVATE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "SigProc_FIX.h" +#include "resampler_structs.h" +#include "resampler_rom.h" + +/* Number of input samples to process in the inner loop */ +#define RESAMPLER_MAX_BATCH_SIZE_MS 10 +#define RESAMPLER_MAX_FS_KHZ 48 +#define RESAMPLER_MAX_BATCH_SIZE_IN ( RESAMPLER_MAX_BATCH_SIZE_MS * RESAMPLER_MAX_FS_KHZ ) + +/* Description: Hybrid IIR/FIR polyphase implementation of resampling */ +void silk_resampler_private_IIR_FIR( + void *SS, /* I/O Resampler state */ + opus_int16 out[], /* O Output signal */ + const opus_int16 in[], /* I Input signal */ + opus_int32 inLen /* I Number of input samples */ +); + +/* Description: Hybrid IIR/FIR polyphase implementation of resampling */ +void silk_resampler_private_down_FIR( + void *SS, /* I/O Resampler state */ + opus_int16 out[], /* O Output signal */ + const opus_int16 in[], /* I Input signal */ + opus_int32 inLen /* I Number of input samples */ +); + +/* Upsample by a factor 2, high quality */ +void silk_resampler_private_up2_HQ_wrapper( + void *SS, /* I/O Resampler state (unused) */ + opus_int16 *out, /* O Output signal [ 2 * len ] */ + const opus_int16 *in, /* I Input signal [ len ] */ + opus_int32 len /* I Number of input samples */ +); + +/* Upsample by a factor 2, high quality */ +void silk_resampler_private_up2_HQ( + opus_int32 *S, /* I/O Resampler state [ 6 ] */ + opus_int16 *out, /* O Output signal [ 2 * len ] */ + const opus_int16 *in, /* I Input signal [ len ] */ + opus_int32 len /* I Number of input samples */ +); + +/* Second order AR filter */ +void silk_resampler_private_AR2( + opus_int32 S[], /* I/O State vector [ 2 ] */ + opus_int32 out_Q8[], /* O Output signal */ + const opus_int16 in[], /* I Input signal */ + const opus_int16 A_Q14[], /* I AR coefficients, Q14 */ + opus_int32 len /* I Signal length */ +); + +#ifdef __cplusplus +} +#endif +#endif /* SILK_RESAMPLER_PRIVATE_H */ diff --git a/src/opus-1.1/silk/resampler_private_AR2.c b/src/opus-1.1/silk/resampler_private_AR2.c new file mode 100644 index 00000000..5fff2371 --- /dev/null +++ b/src/opus-1.1/silk/resampler_private_AR2.c @@ -0,0 +1,55 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SigProc_FIX.h" +#include "resampler_private.h" + +/* Second order AR filter with single delay elements */ +void silk_resampler_private_AR2( + opus_int32 S[], /* I/O State vector [ 2 ] */ + opus_int32 out_Q8[], /* O Output signal */ + const opus_int16 in[], /* I Input signal */ + const opus_int16 A_Q14[], /* I AR coefficients, Q14 */ + opus_int32 len /* I Signal length */ +) +{ + opus_int32 k; + opus_int32 out32; + + for( k = 0; k < len; k++ ) { + out32 = silk_ADD_LSHIFT32( S[ 0 ], (opus_int32)in[ k ], 8 ); + out_Q8[ k ] = out32; + out32 = silk_LSHIFT( out32, 2 ); + S[ 0 ] = silk_SMLAWB( S[ 1 ], out32, A_Q14[ 0 ] ); + S[ 1 ] = silk_SMULWB( out32, A_Q14[ 1 ] ); + } +} + diff --git a/src/opus-1.1/silk/resampler_private_IIR_FIR.c b/src/opus-1.1/silk/resampler_private_IIR_FIR.c new file mode 100644 index 00000000..6b2b3a2e --- /dev/null +++ b/src/opus-1.1/silk/resampler_private_IIR_FIR.c @@ -0,0 +1,107 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SigProc_FIX.h" +#include "resampler_private.h" +#include "stack_alloc.h" + +static OPUS_INLINE opus_int16 *silk_resampler_private_IIR_FIR_INTERPOL( + opus_int16 *out, + opus_int16 *buf, + opus_int32 max_index_Q16, + opus_int32 index_increment_Q16 +) +{ + opus_int32 index_Q16, res_Q15; + opus_int16 *buf_ptr; + opus_int32 table_index; + + /* Interpolate upsampled signal and store in output array */ + for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) { + table_index = silk_SMULWB( index_Q16 & 0xFFFF, 12 ); + buf_ptr = &buf[ index_Q16 >> 16 ]; + + res_Q15 = silk_SMULBB( buf_ptr[ 0 ], silk_resampler_frac_FIR_12[ table_index ][ 0 ] ); + res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 1 ], silk_resampler_frac_FIR_12[ table_index ][ 1 ] ); + res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 2 ], silk_resampler_frac_FIR_12[ table_index ][ 2 ] ); + res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 3 ], silk_resampler_frac_FIR_12[ table_index ][ 3 ] ); + res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 4 ], silk_resampler_frac_FIR_12[ 11 - table_index ][ 3 ] ); + res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 5 ], silk_resampler_frac_FIR_12[ 11 - table_index ][ 2 ] ); + res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 6 ], silk_resampler_frac_FIR_12[ 11 - table_index ][ 1 ] ); + res_Q15 = silk_SMLABB( res_Q15, buf_ptr[ 7 ], silk_resampler_frac_FIR_12[ 11 - table_index ][ 0 ] ); + *out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q15, 15 ) ); + } + return out; +} +/* Upsample using a combination of allpass-based 2x upsampling and FIR interpolation */ +void silk_resampler_private_IIR_FIR( + void *SS, /* I/O Resampler state */ + opus_int16 out[], /* O Output signal */ + const opus_int16 in[], /* I Input signal */ + opus_int32 inLen /* I Number of input samples */ +) +{ + silk_resampler_state_struct *S = (silk_resampler_state_struct *)SS; + opus_int32 nSamplesIn; + opus_int32 max_index_Q16, index_increment_Q16; + VARDECL( opus_int16, buf ); + SAVE_STACK; + + ALLOC( buf, 2 * S->batchSize + RESAMPLER_ORDER_FIR_12, opus_int16 ); + + /* Copy buffered samples to start of buffer */ + silk_memcpy( buf, S->sFIR.i16, RESAMPLER_ORDER_FIR_12 * sizeof( opus_int16 ) ); + + /* Iterate over blocks of frameSizeIn input samples */ + index_increment_Q16 = S->invRatio_Q16; + while( 1 ) { + nSamplesIn = silk_min( inLen, S->batchSize ); + + /* Upsample 2x */ + silk_resampler_private_up2_HQ( S->sIIR, &buf[ RESAMPLER_ORDER_FIR_12 ], in, nSamplesIn ); + + max_index_Q16 = silk_LSHIFT32( nSamplesIn, 16 + 1 ); /* + 1 because 2x upsampling */ + out = silk_resampler_private_IIR_FIR_INTERPOL( out, buf, max_index_Q16, index_increment_Q16 ); + in += nSamplesIn; + inLen -= nSamplesIn; + + if( inLen > 0 ) { + /* More iterations to do; copy last part of filtered signal to beginning of buffer */ + silk_memcpy( buf, &buf[ nSamplesIn << 1 ], RESAMPLER_ORDER_FIR_12 * sizeof( opus_int16 ) ); + } else { + break; + } + } + + /* Copy last part of filtered signal to the state for the next call */ + silk_memcpy( S->sFIR.i16, &buf[ nSamplesIn << 1 ], RESAMPLER_ORDER_FIR_12 * sizeof( opus_int16 ) ); + RESTORE_STACK; +} diff --git a/src/opus-1.1/silk/resampler_private_down_FIR.c b/src/opus-1.1/silk/resampler_private_down_FIR.c new file mode 100644 index 00000000..783e42b3 --- /dev/null +++ b/src/opus-1.1/silk/resampler_private_down_FIR.c @@ -0,0 +1,194 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SigProc_FIX.h" +#include "resampler_private.h" +#include "stack_alloc.h" + +static OPUS_INLINE opus_int16 *silk_resampler_private_down_FIR_INTERPOL( + opus_int16 *out, + opus_int32 *buf, + const opus_int16 *FIR_Coefs, + opus_int FIR_Order, + opus_int FIR_Fracs, + opus_int32 max_index_Q16, + opus_int32 index_increment_Q16 +) +{ + opus_int32 index_Q16, res_Q6; + opus_int32 *buf_ptr; + opus_int32 interpol_ind; + const opus_int16 *interpol_ptr; + + switch( FIR_Order ) { + case RESAMPLER_DOWN_ORDER_FIR0: + for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) { + /* Integer part gives pointer to buffered input */ + buf_ptr = buf + silk_RSHIFT( index_Q16, 16 ); + + /* Fractional part gives interpolation coefficients */ + interpol_ind = silk_SMULWB( index_Q16 & 0xFFFF, FIR_Fracs ); + + /* Inner product */ + interpol_ptr = &FIR_Coefs[ RESAMPLER_DOWN_ORDER_FIR0 / 2 * interpol_ind ]; + res_Q6 = silk_SMULWB( buf_ptr[ 0 ], interpol_ptr[ 0 ] ); + res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 1 ], interpol_ptr[ 1 ] ); + res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 2 ], interpol_ptr[ 2 ] ); + res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 3 ], interpol_ptr[ 3 ] ); + res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 4 ], interpol_ptr[ 4 ] ); + res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 5 ], interpol_ptr[ 5 ] ); + res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 6 ], interpol_ptr[ 6 ] ); + res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 7 ], interpol_ptr[ 7 ] ); + res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 8 ], interpol_ptr[ 8 ] ); + interpol_ptr = &FIR_Coefs[ RESAMPLER_DOWN_ORDER_FIR0 / 2 * ( FIR_Fracs - 1 - interpol_ind ) ]; + res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 17 ], interpol_ptr[ 0 ] ); + res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 16 ], interpol_ptr[ 1 ] ); + res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 15 ], interpol_ptr[ 2 ] ); + res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 14 ], interpol_ptr[ 3 ] ); + res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 13 ], interpol_ptr[ 4 ] ); + res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 12 ], interpol_ptr[ 5 ] ); + res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 11 ], interpol_ptr[ 6 ] ); + res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 10 ], interpol_ptr[ 7 ] ); + res_Q6 = silk_SMLAWB( res_Q6, buf_ptr[ 9 ], interpol_ptr[ 8 ] ); + + /* Scale down, saturate and store in output array */ + *out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q6, 6 ) ); + } + break; + case RESAMPLER_DOWN_ORDER_FIR1: + for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) { + /* Integer part gives pointer to buffered input */ + buf_ptr = buf + silk_RSHIFT( index_Q16, 16 ); + + /* Inner product */ + res_Q6 = silk_SMULWB( silk_ADD32( buf_ptr[ 0 ], buf_ptr[ 23 ] ), FIR_Coefs[ 0 ] ); + res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 1 ], buf_ptr[ 22 ] ), FIR_Coefs[ 1 ] ); + res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 2 ], buf_ptr[ 21 ] ), FIR_Coefs[ 2 ] ); + res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 3 ], buf_ptr[ 20 ] ), FIR_Coefs[ 3 ] ); + res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 4 ], buf_ptr[ 19 ] ), FIR_Coefs[ 4 ] ); + res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 5 ], buf_ptr[ 18 ] ), FIR_Coefs[ 5 ] ); + res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 6 ], buf_ptr[ 17 ] ), FIR_Coefs[ 6 ] ); + res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 7 ], buf_ptr[ 16 ] ), FIR_Coefs[ 7 ] ); + res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 8 ], buf_ptr[ 15 ] ), FIR_Coefs[ 8 ] ); + res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 9 ], buf_ptr[ 14 ] ), FIR_Coefs[ 9 ] ); + res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 10 ], buf_ptr[ 13 ] ), FIR_Coefs[ 10 ] ); + res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 11 ], buf_ptr[ 12 ] ), FIR_Coefs[ 11 ] ); + + /* Scale down, saturate and store in output array */ + *out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q6, 6 ) ); + } + break; + case RESAMPLER_DOWN_ORDER_FIR2: + for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) { + /* Integer part gives pointer to buffered input */ + buf_ptr = buf + silk_RSHIFT( index_Q16, 16 ); + + /* Inner product */ + res_Q6 = silk_SMULWB( silk_ADD32( buf_ptr[ 0 ], buf_ptr[ 35 ] ), FIR_Coefs[ 0 ] ); + res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 1 ], buf_ptr[ 34 ] ), FIR_Coefs[ 1 ] ); + res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 2 ], buf_ptr[ 33 ] ), FIR_Coefs[ 2 ] ); + res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 3 ], buf_ptr[ 32 ] ), FIR_Coefs[ 3 ] ); + res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 4 ], buf_ptr[ 31 ] ), FIR_Coefs[ 4 ] ); + res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 5 ], buf_ptr[ 30 ] ), FIR_Coefs[ 5 ] ); + res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 6 ], buf_ptr[ 29 ] ), FIR_Coefs[ 6 ] ); + res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 7 ], buf_ptr[ 28 ] ), FIR_Coefs[ 7 ] ); + res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 8 ], buf_ptr[ 27 ] ), FIR_Coefs[ 8 ] ); + res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 9 ], buf_ptr[ 26 ] ), FIR_Coefs[ 9 ] ); + res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 10 ], buf_ptr[ 25 ] ), FIR_Coefs[ 10 ] ); + res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 11 ], buf_ptr[ 24 ] ), FIR_Coefs[ 11 ] ); + res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 12 ], buf_ptr[ 23 ] ), FIR_Coefs[ 12 ] ); + res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 13 ], buf_ptr[ 22 ] ), FIR_Coefs[ 13 ] ); + res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 14 ], buf_ptr[ 21 ] ), FIR_Coefs[ 14 ] ); + res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 15 ], buf_ptr[ 20 ] ), FIR_Coefs[ 15 ] ); + res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 16 ], buf_ptr[ 19 ] ), FIR_Coefs[ 16 ] ); + res_Q6 = silk_SMLAWB( res_Q6, silk_ADD32( buf_ptr[ 17 ], buf_ptr[ 18 ] ), FIR_Coefs[ 17 ] ); + + /* Scale down, saturate and store in output array */ + *out++ = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( res_Q6, 6 ) ); + } + break; + default: + silk_assert( 0 ); + } + return out; +} + +/* Resample with a 2nd order AR filter followed by FIR interpolation */ +void silk_resampler_private_down_FIR( + void *SS, /* I/O Resampler state */ + opus_int16 out[], /* O Output signal */ + const opus_int16 in[], /* I Input signal */ + opus_int32 inLen /* I Number of input samples */ +) +{ + silk_resampler_state_struct *S = (silk_resampler_state_struct *)SS; + opus_int32 nSamplesIn; + opus_int32 max_index_Q16, index_increment_Q16; + VARDECL( opus_int32, buf ); + const opus_int16 *FIR_Coefs; + SAVE_STACK; + + ALLOC( buf, S->batchSize + S->FIR_Order, opus_int32 ); + + /* Copy buffered samples to start of buffer */ + silk_memcpy( buf, S->sFIR.i32, S->FIR_Order * sizeof( opus_int32 ) ); + + FIR_Coefs = &S->Coefs[ 2 ]; + + /* Iterate over blocks of frameSizeIn input samples */ + index_increment_Q16 = S->invRatio_Q16; + while( 1 ) { + nSamplesIn = silk_min( inLen, S->batchSize ); + + /* Second-order AR filter (output in Q8) */ + silk_resampler_private_AR2( S->sIIR, &buf[ S->FIR_Order ], in, S->Coefs, nSamplesIn ); + + max_index_Q16 = silk_LSHIFT32( nSamplesIn, 16 ); + + /* Interpolate filtered signal */ + out = silk_resampler_private_down_FIR_INTERPOL( out, buf, FIR_Coefs, S->FIR_Order, + S->FIR_Fracs, max_index_Q16, index_increment_Q16 ); + + in += nSamplesIn; + inLen -= nSamplesIn; + + if( inLen > 1 ) { + /* More iterations to do; copy last part of filtered signal to beginning of buffer */ + silk_memcpy( buf, &buf[ nSamplesIn ], S->FIR_Order * sizeof( opus_int32 ) ); + } else { + break; + } + } + + /* Copy last part of filtered signal to the state for the next call */ + silk_memcpy( S->sFIR.i32, &buf[ nSamplesIn ], S->FIR_Order * sizeof( opus_int32 ) ); + RESTORE_STACK; +} diff --git a/src/opus-1.1/silk/resampler_private_up2_HQ.c b/src/opus-1.1/silk/resampler_private_up2_HQ.c new file mode 100644 index 00000000..c7ec8de3 --- /dev/null +++ b/src/opus-1.1/silk/resampler_private_up2_HQ.c @@ -0,0 +1,113 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SigProc_FIX.h" +#include "resampler_private.h" + +/* Upsample by a factor 2, high quality */ +/* Uses 2nd order allpass filters for the 2x upsampling, followed by a */ +/* notch filter just above Nyquist. */ +void silk_resampler_private_up2_HQ( + opus_int32 *S, /* I/O Resampler state [ 6 ] */ + opus_int16 *out, /* O Output signal [ 2 * len ] */ + const opus_int16 *in, /* I Input signal [ len ] */ + opus_int32 len /* I Number of input samples */ +) +{ + opus_int32 k; + opus_int32 in32, out32_1, out32_2, Y, X; + + silk_assert( silk_resampler_up2_hq_0[ 0 ] > 0 ); + silk_assert( silk_resampler_up2_hq_0[ 1 ] > 0 ); + silk_assert( silk_resampler_up2_hq_0[ 2 ] < 0 ); + silk_assert( silk_resampler_up2_hq_1[ 0 ] > 0 ); + silk_assert( silk_resampler_up2_hq_1[ 1 ] > 0 ); + silk_assert( silk_resampler_up2_hq_1[ 2 ] < 0 ); + + /* Internal variables and state are in Q10 format */ + for( k = 0; k < len; k++ ) { + /* Convert to Q10 */ + in32 = silk_LSHIFT( (opus_int32)in[ k ], 10 ); + + /* First all-pass section for even output sample */ + Y = silk_SUB32( in32, S[ 0 ] ); + X = silk_SMULWB( Y, silk_resampler_up2_hq_0[ 0 ] ); + out32_1 = silk_ADD32( S[ 0 ], X ); + S[ 0 ] = silk_ADD32( in32, X ); + + /* Second all-pass section for even output sample */ + Y = silk_SUB32( out32_1, S[ 1 ] ); + X = silk_SMULWB( Y, silk_resampler_up2_hq_0[ 1 ] ); + out32_2 = silk_ADD32( S[ 1 ], X ); + S[ 1 ] = silk_ADD32( out32_1, X ); + + /* Third all-pass section for even output sample */ + Y = silk_SUB32( out32_2, S[ 2 ] ); + X = silk_SMLAWB( Y, Y, silk_resampler_up2_hq_0[ 2 ] ); + out32_1 = silk_ADD32( S[ 2 ], X ); + S[ 2 ] = silk_ADD32( out32_2, X ); + + /* Apply gain in Q15, convert back to int16 and store to output */ + out[ 2 * k ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( out32_1, 10 ) ); + + /* First all-pass section for odd output sample */ + Y = silk_SUB32( in32, S[ 3 ] ); + X = silk_SMULWB( Y, silk_resampler_up2_hq_1[ 0 ] ); + out32_1 = silk_ADD32( S[ 3 ], X ); + S[ 3 ] = silk_ADD32( in32, X ); + + /* Second all-pass section for odd output sample */ + Y = silk_SUB32( out32_1, S[ 4 ] ); + X = silk_SMULWB( Y, silk_resampler_up2_hq_1[ 1 ] ); + out32_2 = silk_ADD32( S[ 4 ], X ); + S[ 4 ] = silk_ADD32( out32_1, X ); + + /* Third all-pass section for odd output sample */ + Y = silk_SUB32( out32_2, S[ 5 ] ); + X = silk_SMLAWB( Y, Y, silk_resampler_up2_hq_1[ 2 ] ); + out32_1 = silk_ADD32( S[ 5 ], X ); + S[ 5 ] = silk_ADD32( out32_2, X ); + + /* Apply gain in Q15, convert back to int16 and store to output */ + out[ 2 * k + 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( out32_1, 10 ) ); + } +} + +void silk_resampler_private_up2_HQ_wrapper( + void *SS, /* I/O Resampler state (unused) */ + opus_int16 *out, /* O Output signal [ 2 * len ] */ + const opus_int16 *in, /* I Input signal [ len ] */ + opus_int32 len /* I Number of input samples */ +) +{ + silk_resampler_state_struct *S = (silk_resampler_state_struct *)SS; + silk_resampler_private_up2_HQ( S->sIIR, out, in, len ); +} diff --git a/src/opus-1.1/silk/resampler_rom.c b/src/opus-1.1/silk/resampler_rom.c new file mode 100644 index 00000000..2d502706 --- /dev/null +++ b/src/opus-1.1/silk/resampler_rom.c @@ -0,0 +1,96 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* Filter coefficients for IIR/FIR polyphase resampling * + * Total size: 179 Words (358 Bytes) */ + +#include "resampler_private.h" + +/* Matlab code for the notch filter coefficients: */ +/* B = [1, 0.147, 1]; A = [1, 0.107, 0.89]; G = 0.93; freqz(G * B, A, 2^14, 16e3); axis([0, 8000, -10, 1]) */ +/* fprintf('\t%6d, %6d, %6d, %6d\n', round(B(2)*2^16), round(-A(2)*2^16), round((1-A(3))*2^16), round(G*2^15)) */ +/* const opus_int16 silk_resampler_up2_hq_notch[ 4 ] = { 9634, -7012, 7209, 30474 }; */ + +/* Tables with IIR and FIR coefficients for fractional downsamplers (123 Words) */ +silk_DWORD_ALIGN const opus_int16 silk_Resampler_3_4_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ] = { + -20694, -13867, + -49, 64, 17, -157, 353, -496, 163, 11047, 22205, + -39, 6, 91, -170, 186, 23, -896, 6336, 19928, + -19, -36, 102, -89, -24, 328, -951, 2568, 15909, +}; + +silk_DWORD_ALIGN const opus_int16 silk_Resampler_2_3_COEFS[ 2 + 2 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ] = { + -14457, -14019, + 64, 128, -122, 36, 310, -768, 584, 9267, 17733, + 12, 128, 18, -142, 288, -117, -865, 4123, 14459, +}; + +silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_2_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR1 / 2 ] = { + 616, -14323, + -10, 39, 58, -46, -84, 120, 184, -315, -541, 1284, 5380, 9024, +}; + +silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_3_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ] = { + 16102, -15162, + -13, 0, 20, 26, 5, -31, -43, -4, 65, 90, 7, -157, -248, -44, 593, 1583, 2612, 3271, +}; + +silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_4_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ] = { + 22500, -15099, + 3, -14, -20, -15, 2, 25, 37, 25, -16, -71, -107, -79, 50, 292, 623, 982, 1288, 1464, +}; + +silk_DWORD_ALIGN const opus_int16 silk_Resampler_1_6_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ] = { + 27540, -15257, + 17, 12, 8, 1, -10, -22, -30, -32, -22, 3, 44, 100, 168, 243, 317, 381, 429, 455, +}; + +silk_DWORD_ALIGN const opus_int16 silk_Resampler_2_3_COEFS_LQ[ 2 + 2 * 2 ] = { + -2797, -6507, + 4697, 10739, + 1567, 8276, +}; + +/* Table with interplation fractions of 1/24, 3/24, 5/24, ... , 23/24 : 23/24 (46 Words) */ +silk_DWORD_ALIGN const opus_int16 silk_resampler_frac_FIR_12[ 12 ][ RESAMPLER_ORDER_FIR_12 / 2 ] = { + { 189, -600, 617, 30567 }, + { 117, -159, -1070, 29704 }, + { 52, 221, -2392, 28276 }, + { -4, 529, -3350, 26341 }, + { -48, 758, -3956, 23973 }, + { -80, 905, -4235, 21254 }, + { -99, 972, -4222, 18278 }, + { -107, 967, -3957, 15143 }, + { -103, 896, -3487, 11950 }, + { -91, 773, -2865, 8798 }, + { -71, 611, -2143, 5784 }, + { -46, 425, -1375, 2996 }, +}; diff --git a/src/opus-1.1/silk/resampler_rom.h b/src/opus-1.1/silk/resampler_rom.h new file mode 100644 index 00000000..490b3388 --- /dev/null +++ b/src/opus-1.1/silk/resampler_rom.h @@ -0,0 +1,68 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifndef SILK_FIX_RESAMPLER_ROM_H +#define SILK_FIX_RESAMPLER_ROM_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "typedef.h" +#include "resampler_structs.h" + +#define RESAMPLER_DOWN_ORDER_FIR0 18 +#define RESAMPLER_DOWN_ORDER_FIR1 24 +#define RESAMPLER_DOWN_ORDER_FIR2 36 +#define RESAMPLER_ORDER_FIR_12 8 + +/* Tables for 2x downsampler */ +static const opus_int16 silk_resampler_down2_0 = 9872; +static const opus_int16 silk_resampler_down2_1 = 39809 - 65536; + +/* Tables for 2x upsampler, high quality */ +static const opus_int16 silk_resampler_up2_hq_0[ 3 ] = { 1746, 14986, 39083 - 65536 }; +static const opus_int16 silk_resampler_up2_hq_1[ 3 ] = { 6854, 25769, 55542 - 65536 }; + +/* Tables with IIR and FIR coefficients for fractional downsamplers */ +extern const opus_int16 silk_Resampler_3_4_COEFS[ 2 + 3 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ]; +extern const opus_int16 silk_Resampler_2_3_COEFS[ 2 + 2 * RESAMPLER_DOWN_ORDER_FIR0 / 2 ]; +extern const opus_int16 silk_Resampler_1_2_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR1 / 2 ]; +extern const opus_int16 silk_Resampler_1_3_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ]; +extern const opus_int16 silk_Resampler_1_4_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ]; +extern const opus_int16 silk_Resampler_1_6_COEFS[ 2 + RESAMPLER_DOWN_ORDER_FIR2 / 2 ]; +extern const opus_int16 silk_Resampler_2_3_COEFS_LQ[ 2 + 2 * 2 ]; + +/* Table with interplation fractions of 1/24, 3/24, ..., 23/24 */ +extern const opus_int16 silk_resampler_frac_FIR_12[ 12 ][ RESAMPLER_ORDER_FIR_12 / 2 ]; + +#ifdef __cplusplus +} +#endif + +#endif /* SILK_FIX_RESAMPLER_ROM_H */ diff --git a/src/opus-1.1/silk/resampler_structs.h b/src/opus-1.1/silk/resampler_structs.h new file mode 100644 index 00000000..9e9457d1 --- /dev/null +++ b/src/opus-1.1/silk/resampler_structs.h @@ -0,0 +1,60 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifndef SILK_RESAMPLER_STRUCTS_H +#define SILK_RESAMPLER_STRUCTS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define SILK_RESAMPLER_MAX_FIR_ORDER 36 +#define SILK_RESAMPLER_MAX_IIR_ORDER 6 + +typedef struct _silk_resampler_state_struct{ + opus_int32 sIIR[ SILK_RESAMPLER_MAX_IIR_ORDER ]; /* this must be the first element of this struct */ + union{ + opus_int32 i32[ SILK_RESAMPLER_MAX_FIR_ORDER ]; + opus_int16 i16[ SILK_RESAMPLER_MAX_FIR_ORDER ]; + } sFIR; + opus_int16 delayBuf[ 48 ]; + opus_int resampler_function; + opus_int batchSize; + opus_int32 invRatio_Q16; + opus_int FIR_Order; + opus_int FIR_Fracs; + opus_int Fs_in_kHz; + opus_int Fs_out_kHz; + opus_int inputDelay; + const opus_int16 *Coefs; +} silk_resampler_state_struct; + +#ifdef __cplusplus +} +#endif +#endif /* SILK_RESAMPLER_STRUCTS_H */ + diff --git a/src/opus-1.1/silk/shell_coder.c b/src/opus-1.1/silk/shell_coder.c new file mode 100644 index 00000000..796f57d6 --- /dev/null +++ b/src/opus-1.1/silk/shell_coder.c @@ -0,0 +1,151 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main.h" + +/* shell coder; pulse-subframe length is hardcoded */ + +static OPUS_INLINE void combine_pulses( + opus_int *out, /* O combined pulses vector [len] */ + const opus_int *in, /* I input vector [2 * len] */ + const opus_int len /* I number of OUTPUT samples */ +) +{ + opus_int k; + for( k = 0; k < len; k++ ) { + out[ k ] = in[ 2 * k ] + in[ 2 * k + 1 ]; + } +} + +static OPUS_INLINE void encode_split( + ec_enc *psRangeEnc, /* I/O compressor data structure */ + const opus_int p_child1, /* I pulse amplitude of first child subframe */ + const opus_int p, /* I pulse amplitude of current subframe */ + const opus_uint8 *shell_table /* I table of shell cdfs */ +) +{ + if( p > 0 ) { + ec_enc_icdf( psRangeEnc, p_child1, &shell_table[ silk_shell_code_table_offsets[ p ] ], 8 ); + } +} + +static OPUS_INLINE void decode_split( + opus_int *p_child1, /* O pulse amplitude of first child subframe */ + opus_int *p_child2, /* O pulse amplitude of second child subframe */ + ec_dec *psRangeDec, /* I/O Compressor data structure */ + const opus_int p, /* I pulse amplitude of current subframe */ + const opus_uint8 *shell_table /* I table of shell cdfs */ +) +{ + if( p > 0 ) { + p_child1[ 0 ] = ec_dec_icdf( psRangeDec, &shell_table[ silk_shell_code_table_offsets[ p ] ], 8 ); + p_child2[ 0 ] = p - p_child1[ 0 ]; + } else { + p_child1[ 0 ] = 0; + p_child2[ 0 ] = 0; + } +} + +/* Shell encoder, operates on one shell code frame of 16 pulses */ +void silk_shell_encoder( + ec_enc *psRangeEnc, /* I/O compressor data structure */ + const opus_int *pulses0 /* I data: nonnegative pulse amplitudes */ +) +{ + opus_int pulses1[ 8 ], pulses2[ 4 ], pulses3[ 2 ], pulses4[ 1 ]; + + /* this function operates on one shell code frame of 16 pulses */ + silk_assert( SHELL_CODEC_FRAME_LENGTH == 16 ); + + /* tree representation per pulse-subframe */ + combine_pulses( pulses1, pulses0, 8 ); + combine_pulses( pulses2, pulses1, 4 ); + combine_pulses( pulses3, pulses2, 2 ); + combine_pulses( pulses4, pulses3, 1 ); + + encode_split( psRangeEnc, pulses3[ 0 ], pulses4[ 0 ], silk_shell_code_table3 ); + + encode_split( psRangeEnc, pulses2[ 0 ], pulses3[ 0 ], silk_shell_code_table2 ); + + encode_split( psRangeEnc, pulses1[ 0 ], pulses2[ 0 ], silk_shell_code_table1 ); + encode_split( psRangeEnc, pulses0[ 0 ], pulses1[ 0 ], silk_shell_code_table0 ); + encode_split( psRangeEnc, pulses0[ 2 ], pulses1[ 1 ], silk_shell_code_table0 ); + + encode_split( psRangeEnc, pulses1[ 2 ], pulses2[ 1 ], silk_shell_code_table1 ); + encode_split( psRangeEnc, pulses0[ 4 ], pulses1[ 2 ], silk_shell_code_table0 ); + encode_split( psRangeEnc, pulses0[ 6 ], pulses1[ 3 ], silk_shell_code_table0 ); + + encode_split( psRangeEnc, pulses2[ 2 ], pulses3[ 1 ], silk_shell_code_table2 ); + + encode_split( psRangeEnc, pulses1[ 4 ], pulses2[ 2 ], silk_shell_code_table1 ); + encode_split( psRangeEnc, pulses0[ 8 ], pulses1[ 4 ], silk_shell_code_table0 ); + encode_split( psRangeEnc, pulses0[ 10 ], pulses1[ 5 ], silk_shell_code_table0 ); + + encode_split( psRangeEnc, pulses1[ 6 ], pulses2[ 3 ], silk_shell_code_table1 ); + encode_split( psRangeEnc, pulses0[ 12 ], pulses1[ 6 ], silk_shell_code_table0 ); + encode_split( psRangeEnc, pulses0[ 14 ], pulses1[ 7 ], silk_shell_code_table0 ); +} + + +/* Shell decoder, operates on one shell code frame of 16 pulses */ +void silk_shell_decoder( + opus_int *pulses0, /* O data: nonnegative pulse amplitudes */ + ec_dec *psRangeDec, /* I/O Compressor data structure */ + const opus_int pulses4 /* I number of pulses per pulse-subframe */ +) +{ + opus_int pulses3[ 2 ], pulses2[ 4 ], pulses1[ 8 ]; + + /* this function operates on one shell code frame of 16 pulses */ + silk_assert( SHELL_CODEC_FRAME_LENGTH == 16 ); + + decode_split( &pulses3[ 0 ], &pulses3[ 1 ], psRangeDec, pulses4, silk_shell_code_table3 ); + + decode_split( &pulses2[ 0 ], &pulses2[ 1 ], psRangeDec, pulses3[ 0 ], silk_shell_code_table2 ); + + decode_split( &pulses1[ 0 ], &pulses1[ 1 ], psRangeDec, pulses2[ 0 ], silk_shell_code_table1 ); + decode_split( &pulses0[ 0 ], &pulses0[ 1 ], psRangeDec, pulses1[ 0 ], silk_shell_code_table0 ); + decode_split( &pulses0[ 2 ], &pulses0[ 3 ], psRangeDec, pulses1[ 1 ], silk_shell_code_table0 ); + + decode_split( &pulses1[ 2 ], &pulses1[ 3 ], psRangeDec, pulses2[ 1 ], silk_shell_code_table1 ); + decode_split( &pulses0[ 4 ], &pulses0[ 5 ], psRangeDec, pulses1[ 2 ], silk_shell_code_table0 ); + decode_split( &pulses0[ 6 ], &pulses0[ 7 ], psRangeDec, pulses1[ 3 ], silk_shell_code_table0 ); + + decode_split( &pulses2[ 2 ], &pulses2[ 3 ], psRangeDec, pulses3[ 1 ], silk_shell_code_table2 ); + + decode_split( &pulses1[ 4 ], &pulses1[ 5 ], psRangeDec, pulses2[ 2 ], silk_shell_code_table1 ); + decode_split( &pulses0[ 8 ], &pulses0[ 9 ], psRangeDec, pulses1[ 4 ], silk_shell_code_table0 ); + decode_split( &pulses0[ 10 ], &pulses0[ 11 ], psRangeDec, pulses1[ 5 ], silk_shell_code_table0 ); + + decode_split( &pulses1[ 6 ], &pulses1[ 7 ], psRangeDec, pulses2[ 3 ], silk_shell_code_table1 ); + decode_split( &pulses0[ 12 ], &pulses0[ 13 ], psRangeDec, pulses1[ 6 ], silk_shell_code_table0 ); + decode_split( &pulses0[ 14 ], &pulses0[ 15 ], psRangeDec, pulses1[ 7 ], silk_shell_code_table0 ); +} diff --git a/src/opus-1.1/silk/sigm_Q15.c b/src/opus-1.1/silk/sigm_Q15.c new file mode 100644 index 00000000..3c507d25 --- /dev/null +++ b/src/opus-1.1/silk/sigm_Q15.c @@ -0,0 +1,76 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* Approximate sigmoid function */ + +#include "SigProc_FIX.h" + +/* fprintf(1, '%d, ', round(1024 * ([1 ./ (1 + exp(-(1:5))), 1] - 1 ./ (1 + exp(-(0:5)))))); */ +static const opus_int32 sigm_LUT_slope_Q10[ 6 ] = { + 237, 153, 73, 30, 12, 7 +}; +/* fprintf(1, '%d, ', round(32767 * 1 ./ (1 + exp(-(0:5))))); */ +static const opus_int32 sigm_LUT_pos_Q15[ 6 ] = { + 16384, 23955, 28861, 31213, 32178, 32548 +}; +/* fprintf(1, '%d, ', round(32767 * 1 ./ (1 + exp((0:5))))); */ +static const opus_int32 sigm_LUT_neg_Q15[ 6 ] = { + 16384, 8812, 3906, 1554, 589, 219 +}; + +opus_int silk_sigm_Q15( + opus_int in_Q5 /* I */ +) +{ + opus_int ind; + + if( in_Q5 < 0 ) { + /* Negative input */ + in_Q5 = -in_Q5; + if( in_Q5 >= 6 * 32 ) { + return 0; /* Clip */ + } else { + /* Linear interpolation of look up table */ + ind = silk_RSHIFT( in_Q5, 5 ); + return( sigm_LUT_neg_Q15[ ind ] - silk_SMULBB( sigm_LUT_slope_Q10[ ind ], in_Q5 & 0x1F ) ); + } + } else { + /* Positive input */ + if( in_Q5 >= 6 * 32 ) { + return 32767; /* clip */ + } else { + /* Linear interpolation of look up table */ + ind = silk_RSHIFT( in_Q5, 5 ); + return( sigm_LUT_pos_Q15[ ind ] + silk_SMULBB( sigm_LUT_slope_Q10[ ind ], in_Q5 & 0x1F ) ); + } + } +} + diff --git a/src/opus-1.1/silk/sort.c b/src/opus-1.1/silk/sort.c new file mode 100644 index 00000000..8670dbdd --- /dev/null +++ b/src/opus-1.1/silk/sort.c @@ -0,0 +1,154 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +/* Insertion sort (fast for already almost sorted arrays): */ +/* Best case: O(n) for an already sorted array */ +/* Worst case: O(n^2) for an inversely sorted array */ +/* */ +/* Shell short: http://en.wikipedia.org/wiki/Shell_sort */ + +#include "SigProc_FIX.h" + +void silk_insertion_sort_increasing( + opus_int32 *a, /* I/O Unsorted / Sorted vector */ + opus_int *idx, /* O Index vector for the sorted elements */ + const opus_int L, /* I Vector length */ + const opus_int K /* I Number of correctly sorted positions */ +) +{ + opus_int32 value; + opus_int i, j; + + /* Safety checks */ + silk_assert( K > 0 ); + silk_assert( L > 0 ); + silk_assert( L >= K ); + + /* Write start indices in index vector */ + for( i = 0; i < K; i++ ) { + idx[ i ] = i; + } + + /* Sort vector elements by value, increasing order */ + for( i = 1; i < K; i++ ) { + value = a[ i ]; + for( j = i - 1; ( j >= 0 ) && ( value < a[ j ] ); j-- ) { + a[ j + 1 ] = a[ j ]; /* Shift value */ + idx[ j + 1 ] = idx[ j ]; /* Shift index */ + } + a[ j + 1 ] = value; /* Write value */ + idx[ j + 1 ] = i; /* Write index */ + } + + /* If less than L values are asked for, check the remaining values, */ + /* but only spend CPU to ensure that the K first values are correct */ + for( i = K; i < L; i++ ) { + value = a[ i ]; + if( value < a[ K - 1 ] ) { + for( j = K - 2; ( j >= 0 ) && ( value < a[ j ] ); j-- ) { + a[ j + 1 ] = a[ j ]; /* Shift value */ + idx[ j + 1 ] = idx[ j ]; /* Shift index */ + } + a[ j + 1 ] = value; /* Write value */ + idx[ j + 1 ] = i; /* Write index */ + } + } +} + +#ifdef FIXED_POINT +/* This function is only used by the fixed-point build */ +void silk_insertion_sort_decreasing_int16( + opus_int16 *a, /* I/O Unsorted / Sorted vector */ + opus_int *idx, /* O Index vector for the sorted elements */ + const opus_int L, /* I Vector length */ + const opus_int K /* I Number of correctly sorted positions */ +) +{ + opus_int i, j; + opus_int value; + + /* Safety checks */ + silk_assert( K > 0 ); + silk_assert( L > 0 ); + silk_assert( L >= K ); + + /* Write start indices in index vector */ + for( i = 0; i < K; i++ ) { + idx[ i ] = i; + } + + /* Sort vector elements by value, decreasing order */ + for( i = 1; i < K; i++ ) { + value = a[ i ]; + for( j = i - 1; ( j >= 0 ) && ( value > a[ j ] ); j-- ) { + a[ j + 1 ] = a[ j ]; /* Shift value */ + idx[ j + 1 ] = idx[ j ]; /* Shift index */ + } + a[ j + 1 ] = value; /* Write value */ + idx[ j + 1 ] = i; /* Write index */ + } + + /* If less than L values are asked for, check the remaining values, */ + /* but only spend CPU to ensure that the K first values are correct */ + for( i = K; i < L; i++ ) { + value = a[ i ]; + if( value > a[ K - 1 ] ) { + for( j = K - 2; ( j >= 0 ) && ( value > a[ j ] ); j-- ) { + a[ j + 1 ] = a[ j ]; /* Shift value */ + idx[ j + 1 ] = idx[ j ]; /* Shift index */ + } + a[ j + 1 ] = value; /* Write value */ + idx[ j + 1 ] = i; /* Write index */ + } + } +} +#endif + +void silk_insertion_sort_increasing_all_values_int16( + opus_int16 *a, /* I/O Unsorted / Sorted vector */ + const opus_int L /* I Vector length */ +) +{ + opus_int value; + opus_int i, j; + + /* Safety checks */ + silk_assert( L > 0 ); + + /* Sort vector elements by value, increasing order */ + for( i = 1; i < L; i++ ) { + value = a[ i ]; + for( j = i - 1; ( j >= 0 ) && ( value < a[ j ] ); j-- ) { + a[ j + 1 ] = a[ j ]; /* Shift value */ + } + a[ j + 1 ] = value; /* Write value */ + } +} diff --git a/src/opus-1.1/silk/stereo_LR_to_MS.c b/src/opus-1.1/silk/stereo_LR_to_MS.c new file mode 100644 index 00000000..42906e6f --- /dev/null +++ b/src/opus-1.1/silk/stereo_LR_to_MS.c @@ -0,0 +1,229 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main.h" +#include "stack_alloc.h" + +/* Convert Left/Right stereo signal to adaptive Mid/Side representation */ +void silk_stereo_LR_to_MS( + stereo_enc_state *state, /* I/O State */ + opus_int16 x1[], /* I/O Left input signal, becomes mid signal */ + opus_int16 x2[], /* I/O Right input signal, becomes side signal */ + opus_int8 ix[ 2 ][ 3 ], /* O Quantization indices */ + opus_int8 *mid_only_flag, /* O Flag: only mid signal coded */ + opus_int32 mid_side_rates_bps[], /* O Bitrates for mid and side signals */ + opus_int32 total_rate_bps, /* I Total bitrate */ + opus_int prev_speech_act_Q8, /* I Speech activity level in previous frame */ + opus_int toMono, /* I Last frame before a stereo->mono transition */ + opus_int fs_kHz, /* I Sample rate (kHz) */ + opus_int frame_length /* I Number of samples */ +) +{ + opus_int n, is10msFrame, denom_Q16, delta0_Q13, delta1_Q13; + opus_int32 sum, diff, smooth_coef_Q16, pred_Q13[ 2 ], pred0_Q13, pred1_Q13; + opus_int32 LP_ratio_Q14, HP_ratio_Q14, frac_Q16, frac_3_Q16, min_mid_rate_bps, width_Q14, w_Q24, deltaw_Q24; + VARDECL( opus_int16, side ); + VARDECL( opus_int16, LP_mid ); + VARDECL( opus_int16, HP_mid ); + VARDECL( opus_int16, LP_side ); + VARDECL( opus_int16, HP_side ); + opus_int16 *mid = &x1[ -2 ]; + SAVE_STACK; + + ALLOC( side, frame_length + 2, opus_int16 ); + /* Convert to basic mid/side signals */ + for( n = 0; n < frame_length + 2; n++ ) { + sum = x1[ n - 2 ] + (opus_int32)x2[ n - 2 ]; + diff = x1[ n - 2 ] - (opus_int32)x2[ n - 2 ]; + mid[ n ] = (opus_int16)silk_RSHIFT_ROUND( sum, 1 ); + side[ n ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( diff, 1 ) ); + } + + /* Buffering */ + silk_memcpy( mid, state->sMid, 2 * sizeof( opus_int16 ) ); + silk_memcpy( side, state->sSide, 2 * sizeof( opus_int16 ) ); + silk_memcpy( state->sMid, &mid[ frame_length ], 2 * sizeof( opus_int16 ) ); + silk_memcpy( state->sSide, &side[ frame_length ], 2 * sizeof( opus_int16 ) ); + + /* LP and HP filter mid signal */ + ALLOC( LP_mid, frame_length, opus_int16 ); + ALLOC( HP_mid, frame_length, opus_int16 ); + for( n = 0; n < frame_length; n++ ) { + sum = silk_RSHIFT_ROUND( silk_ADD_LSHIFT( mid[ n ] + mid[ n + 2 ], mid[ n + 1 ], 1 ), 2 ); + LP_mid[ n ] = sum; + HP_mid[ n ] = mid[ n + 1 ] - sum; + } + + /* LP and HP filter side signal */ + ALLOC( LP_side, frame_length, opus_int16 ); + ALLOC( HP_side, frame_length, opus_int16 ); + for( n = 0; n < frame_length; n++ ) { + sum = silk_RSHIFT_ROUND( silk_ADD_LSHIFT( side[ n ] + side[ n + 2 ], side[ n + 1 ], 1 ), 2 ); + LP_side[ n ] = sum; + HP_side[ n ] = side[ n + 1 ] - sum; + } + + /* Find energies and predictors */ + is10msFrame = frame_length == 10 * fs_kHz; + smooth_coef_Q16 = is10msFrame ? + SILK_FIX_CONST( STEREO_RATIO_SMOOTH_COEF / 2, 16 ) : + SILK_FIX_CONST( STEREO_RATIO_SMOOTH_COEF, 16 ); + smooth_coef_Q16 = silk_SMULWB( silk_SMULBB( prev_speech_act_Q8, prev_speech_act_Q8 ), smooth_coef_Q16 ); + + pred_Q13[ 0 ] = silk_stereo_find_predictor( &LP_ratio_Q14, LP_mid, LP_side, &state->mid_side_amp_Q0[ 0 ], frame_length, smooth_coef_Q16 ); + pred_Q13[ 1 ] = silk_stereo_find_predictor( &HP_ratio_Q14, HP_mid, HP_side, &state->mid_side_amp_Q0[ 2 ], frame_length, smooth_coef_Q16 ); + /* Ratio of the norms of residual and mid signals */ + frac_Q16 = silk_SMLABB( HP_ratio_Q14, LP_ratio_Q14, 3 ); + frac_Q16 = silk_min( frac_Q16, SILK_FIX_CONST( 1, 16 ) ); + + /* Determine bitrate distribution between mid and side, and possibly reduce stereo width */ + total_rate_bps -= is10msFrame ? 1200 : 600; /* Subtract approximate bitrate for coding stereo parameters */ + if( total_rate_bps < 1 ) { + total_rate_bps = 1; + } + min_mid_rate_bps = silk_SMLABB( 2000, fs_kHz, 900 ); + silk_assert( min_mid_rate_bps < 32767 ); + /* Default bitrate distribution: 8 parts for Mid and (5+3*frac) parts for Side. so: mid_rate = ( 8 / ( 13 + 3 * frac ) ) * total_ rate */ + frac_3_Q16 = silk_MUL( 3, frac_Q16 ); + mid_side_rates_bps[ 0 ] = silk_DIV32_varQ( total_rate_bps, SILK_FIX_CONST( 8 + 5, 16 ) + frac_3_Q16, 16+3 ); + /* If Mid bitrate below minimum, reduce stereo width */ + if( mid_side_rates_bps[ 0 ] < min_mid_rate_bps ) { + mid_side_rates_bps[ 0 ] = min_mid_rate_bps; + mid_side_rates_bps[ 1 ] = total_rate_bps - mid_side_rates_bps[ 0 ]; + /* width = 4 * ( 2 * side_rate - min_rate ) / ( ( 1 + 3 * frac ) * min_rate ) */ + width_Q14 = silk_DIV32_varQ( silk_LSHIFT( mid_side_rates_bps[ 1 ], 1 ) - min_mid_rate_bps, + silk_SMULWB( SILK_FIX_CONST( 1, 16 ) + frac_3_Q16, min_mid_rate_bps ), 14+2 ); + width_Q14 = silk_LIMIT( width_Q14, 0, SILK_FIX_CONST( 1, 14 ) ); + } else { + mid_side_rates_bps[ 1 ] = total_rate_bps - mid_side_rates_bps[ 0 ]; + width_Q14 = SILK_FIX_CONST( 1, 14 ); + } + + /* Smoother */ + state->smth_width_Q14 = (opus_int16)silk_SMLAWB( state->smth_width_Q14, width_Q14 - state->smth_width_Q14, smooth_coef_Q16 ); + + /* At very low bitrates or for inputs that are nearly amplitude panned, switch to panned-mono coding */ + *mid_only_flag = 0; + if( toMono ) { + /* Last frame before stereo->mono transition; collapse stereo width */ + width_Q14 = 0; + pred_Q13[ 0 ] = 0; + pred_Q13[ 1 ] = 0; + silk_stereo_quant_pred( pred_Q13, ix ); + } else if( state->width_prev_Q14 == 0 && + ( 8 * total_rate_bps < 13 * min_mid_rate_bps || silk_SMULWB( frac_Q16, state->smth_width_Q14 ) < SILK_FIX_CONST( 0.05, 14 ) ) ) + { + /* Code as panned-mono; previous frame already had zero width */ + /* Scale down and quantize predictors */ + pred_Q13[ 0 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 0 ] ), 14 ); + pred_Q13[ 1 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 1 ] ), 14 ); + silk_stereo_quant_pred( pred_Q13, ix ); + /* Collapse stereo width */ + width_Q14 = 0; + pred_Q13[ 0 ] = 0; + pred_Q13[ 1 ] = 0; + mid_side_rates_bps[ 0 ] = total_rate_bps; + mid_side_rates_bps[ 1 ] = 0; + *mid_only_flag = 1; + } else if( state->width_prev_Q14 != 0 && + ( 8 * total_rate_bps < 11 * min_mid_rate_bps || silk_SMULWB( frac_Q16, state->smth_width_Q14 ) < SILK_FIX_CONST( 0.02, 14 ) ) ) + { + /* Transition to zero-width stereo */ + /* Scale down and quantize predictors */ + pred_Q13[ 0 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 0 ] ), 14 ); + pred_Q13[ 1 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 1 ] ), 14 ); + silk_stereo_quant_pred( pred_Q13, ix ); + /* Collapse stereo width */ + width_Q14 = 0; + pred_Q13[ 0 ] = 0; + pred_Q13[ 1 ] = 0; + } else if( state->smth_width_Q14 > SILK_FIX_CONST( 0.95, 14 ) ) { + /* Full-width stereo coding */ + silk_stereo_quant_pred( pred_Q13, ix ); + width_Q14 = SILK_FIX_CONST( 1, 14 ); + } else { + /* Reduced-width stereo coding; scale down and quantize predictors */ + pred_Q13[ 0 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 0 ] ), 14 ); + pred_Q13[ 1 ] = silk_RSHIFT( silk_SMULBB( state->smth_width_Q14, pred_Q13[ 1 ] ), 14 ); + silk_stereo_quant_pred( pred_Q13, ix ); + width_Q14 = state->smth_width_Q14; + } + + /* Make sure to keep on encoding until the tapered output has been transmitted */ + if( *mid_only_flag == 1 ) { + state->silent_side_len += frame_length - STEREO_INTERP_LEN_MS * fs_kHz; + if( state->silent_side_len < LA_SHAPE_MS * fs_kHz ) { + *mid_only_flag = 0; + } else { + /* Limit to avoid wrapping around */ + state->silent_side_len = 10000; + } + } else { + state->silent_side_len = 0; + } + + if( *mid_only_flag == 0 && mid_side_rates_bps[ 1 ] < 1 ) { + mid_side_rates_bps[ 1 ] = 1; + mid_side_rates_bps[ 0 ] = silk_max_int( 1, total_rate_bps - mid_side_rates_bps[ 1 ]); + } + + /* Interpolate predictors and subtract prediction from side channel */ + pred0_Q13 = -state->pred_prev_Q13[ 0 ]; + pred1_Q13 = -state->pred_prev_Q13[ 1 ]; + w_Q24 = silk_LSHIFT( state->width_prev_Q14, 10 ); + denom_Q16 = silk_DIV32_16( (opus_int32)1 << 16, STEREO_INTERP_LEN_MS * fs_kHz ); + delta0_Q13 = -silk_RSHIFT_ROUND( silk_SMULBB( pred_Q13[ 0 ] - state->pred_prev_Q13[ 0 ], denom_Q16 ), 16 ); + delta1_Q13 = -silk_RSHIFT_ROUND( silk_SMULBB( pred_Q13[ 1 ] - state->pred_prev_Q13[ 1 ], denom_Q16 ), 16 ); + deltaw_Q24 = silk_LSHIFT( silk_SMULWB( width_Q14 - state->width_prev_Q14, denom_Q16 ), 10 ); + for( n = 0; n < STEREO_INTERP_LEN_MS * fs_kHz; n++ ) { + pred0_Q13 += delta0_Q13; + pred1_Q13 += delta1_Q13; + w_Q24 += deltaw_Q24; + sum = silk_LSHIFT( silk_ADD_LSHIFT( mid[ n ] + mid[ n + 2 ], mid[ n + 1 ], 1 ), 9 ); /* Q11 */ + sum = silk_SMLAWB( silk_SMULWB( w_Q24, side[ n + 1 ] ), sum, pred0_Q13 ); /* Q8 */ + sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)mid[ n + 1 ], 11 ), pred1_Q13 ); /* Q8 */ + x2[ n - 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) ); + } + + pred0_Q13 = -pred_Q13[ 0 ]; + pred1_Q13 = -pred_Q13[ 1 ]; + w_Q24 = silk_LSHIFT( width_Q14, 10 ); + for( n = STEREO_INTERP_LEN_MS * fs_kHz; n < frame_length; n++ ) { + sum = silk_LSHIFT( silk_ADD_LSHIFT( mid[ n ] + mid[ n + 2 ], mid[ n + 1 ], 1 ), 9 ); /* Q11 */ + sum = silk_SMLAWB( silk_SMULWB( w_Q24, side[ n + 1 ] ), sum, pred0_Q13 ); /* Q8 */ + sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)mid[ n + 1 ], 11 ), pred1_Q13 ); /* Q8 */ + x2[ n - 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) ); + } + state->pred_prev_Q13[ 0 ] = (opus_int16)pred_Q13[ 0 ]; + state->pred_prev_Q13[ 1 ] = (opus_int16)pred_Q13[ 1 ]; + state->width_prev_Q14 = (opus_int16)width_Q14; + RESTORE_STACK; +} diff --git a/src/opus-1.1/silk/stereo_MS_to_LR.c b/src/opus-1.1/silk/stereo_MS_to_LR.c new file mode 100644 index 00000000..62521a4f --- /dev/null +++ b/src/opus-1.1/silk/stereo_MS_to_LR.c @@ -0,0 +1,85 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main.h" + +/* Convert adaptive Mid/Side representation to Left/Right stereo signal */ +void silk_stereo_MS_to_LR( + stereo_dec_state *state, /* I/O State */ + opus_int16 x1[], /* I/O Left input signal, becomes mid signal */ + opus_int16 x2[], /* I/O Right input signal, becomes side signal */ + const opus_int32 pred_Q13[], /* I Predictors */ + opus_int fs_kHz, /* I Samples rate (kHz) */ + opus_int frame_length /* I Number of samples */ +) +{ + opus_int n, denom_Q16, delta0_Q13, delta1_Q13; + opus_int32 sum, diff, pred0_Q13, pred1_Q13; + + /* Buffering */ + silk_memcpy( x1, state->sMid, 2 * sizeof( opus_int16 ) ); + silk_memcpy( x2, state->sSide, 2 * sizeof( opus_int16 ) ); + silk_memcpy( state->sMid, &x1[ frame_length ], 2 * sizeof( opus_int16 ) ); + silk_memcpy( state->sSide, &x2[ frame_length ], 2 * sizeof( opus_int16 ) ); + + /* Interpolate predictors and add prediction to side channel */ + pred0_Q13 = state->pred_prev_Q13[ 0 ]; + pred1_Q13 = state->pred_prev_Q13[ 1 ]; + denom_Q16 = silk_DIV32_16( (opus_int32)1 << 16, STEREO_INTERP_LEN_MS * fs_kHz ); + delta0_Q13 = silk_RSHIFT_ROUND( silk_SMULBB( pred_Q13[ 0 ] - state->pred_prev_Q13[ 0 ], denom_Q16 ), 16 ); + delta1_Q13 = silk_RSHIFT_ROUND( silk_SMULBB( pred_Q13[ 1 ] - state->pred_prev_Q13[ 1 ], denom_Q16 ), 16 ); + for( n = 0; n < STEREO_INTERP_LEN_MS * fs_kHz; n++ ) { + pred0_Q13 += delta0_Q13; + pred1_Q13 += delta1_Q13; + sum = silk_LSHIFT( silk_ADD_LSHIFT( x1[ n ] + x1[ n + 2 ], x1[ n + 1 ], 1 ), 9 ); /* Q11 */ + sum = silk_SMLAWB( silk_LSHIFT( (opus_int32)x2[ n + 1 ], 8 ), sum, pred0_Q13 ); /* Q8 */ + sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)x1[ n + 1 ], 11 ), pred1_Q13 ); /* Q8 */ + x2[ n + 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) ); + } + pred0_Q13 = pred_Q13[ 0 ]; + pred1_Q13 = pred_Q13[ 1 ]; + for( n = STEREO_INTERP_LEN_MS * fs_kHz; n < frame_length; n++ ) { + sum = silk_LSHIFT( silk_ADD_LSHIFT( x1[ n ] + x1[ n + 2 ], x1[ n + 1 ], 1 ), 9 ); /* Q11 */ + sum = silk_SMLAWB( silk_LSHIFT( (opus_int32)x2[ n + 1 ], 8 ), sum, pred0_Q13 ); /* Q8 */ + sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)x1[ n + 1 ], 11 ), pred1_Q13 ); /* Q8 */ + x2[ n + 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) ); + } + state->pred_prev_Q13[ 0 ] = pred_Q13[ 0 ]; + state->pred_prev_Q13[ 1 ] = pred_Q13[ 1 ]; + + /* Convert to left/right signals */ + for( n = 0; n < frame_length; n++ ) { + sum = x1[ n + 1 ] + (opus_int32)x2[ n + 1 ]; + diff = x1[ n + 1 ] - (opus_int32)x2[ n + 1 ]; + x1[ n + 1 ] = (opus_int16)silk_SAT16( sum ); + x2[ n + 1 ] = (opus_int16)silk_SAT16( diff ); + } +} diff --git a/src/opus-1.1/silk/stereo_decode_pred.c b/src/opus-1.1/silk/stereo_decode_pred.c new file mode 100644 index 00000000..56ba3925 --- /dev/null +++ b/src/opus-1.1/silk/stereo_decode_pred.c @@ -0,0 +1,73 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main.h" + +/* Decode mid/side predictors */ +void silk_stereo_decode_pred( + ec_dec *psRangeDec, /* I/O Compressor data structure */ + opus_int32 pred_Q13[] /* O Predictors */ +) +{ + opus_int n, ix[ 2 ][ 3 ]; + opus_int32 low_Q13, step_Q13; + + /* Entropy decoding */ + n = ec_dec_icdf( psRangeDec, silk_stereo_pred_joint_iCDF, 8 ); + ix[ 0 ][ 2 ] = silk_DIV32_16( n, 5 ); + ix[ 1 ][ 2 ] = n - 5 * ix[ 0 ][ 2 ]; + for( n = 0; n < 2; n++ ) { + ix[ n ][ 0 ] = ec_dec_icdf( psRangeDec, silk_uniform3_iCDF, 8 ); + ix[ n ][ 1 ] = ec_dec_icdf( psRangeDec, silk_uniform5_iCDF, 8 ); + } + + /* Dequantize */ + for( n = 0; n < 2; n++ ) { + ix[ n ][ 0 ] += 3 * ix[ n ][ 2 ]; + low_Q13 = silk_stereo_pred_quant_Q13[ ix[ n ][ 0 ] ]; + step_Q13 = silk_SMULWB( silk_stereo_pred_quant_Q13[ ix[ n ][ 0 ] + 1 ] - low_Q13, + SILK_FIX_CONST( 0.5 / STEREO_QUANT_SUB_STEPS, 16 ) ); + pred_Q13[ n ] = silk_SMLABB( low_Q13, step_Q13, 2 * ix[ n ][ 1 ] + 1 ); + } + + /* Subtract second from first predictor (helps when actually applying these) */ + pred_Q13[ 0 ] -= pred_Q13[ 1 ]; +} + +/* Decode mid-only flag */ +void silk_stereo_decode_mid_only( + ec_dec *psRangeDec, /* I/O Compressor data structure */ + opus_int *decode_only_mid /* O Flag that only mid channel has been coded */ +) +{ + /* Decode flag that only mid channel is coded */ + *decode_only_mid = ec_dec_icdf( psRangeDec, silk_stereo_only_code_mid_iCDF, 8 ); +} diff --git a/src/opus-1.1/silk/stereo_encode_pred.c b/src/opus-1.1/silk/stereo_encode_pred.c new file mode 100644 index 00000000..e6dd1950 --- /dev/null +++ b/src/opus-1.1/silk/stereo_encode_pred.c @@ -0,0 +1,62 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main.h" + +/* Entropy code the mid/side quantization indices */ +void silk_stereo_encode_pred( + ec_enc *psRangeEnc, /* I/O Compressor data structure */ + opus_int8 ix[ 2 ][ 3 ] /* I Quantization indices */ +) +{ + opus_int n; + + /* Entropy coding */ + n = 5 * ix[ 0 ][ 2 ] + ix[ 1 ][ 2 ]; + silk_assert( n < 25 ); + ec_enc_icdf( psRangeEnc, n, silk_stereo_pred_joint_iCDF, 8 ); + for( n = 0; n < 2; n++ ) { + silk_assert( ix[ n ][ 0 ] < 3 ); + silk_assert( ix[ n ][ 1 ] < STEREO_QUANT_SUB_STEPS ); + ec_enc_icdf( psRangeEnc, ix[ n ][ 0 ], silk_uniform3_iCDF, 8 ); + ec_enc_icdf( psRangeEnc, ix[ n ][ 1 ], silk_uniform5_iCDF, 8 ); + } +} + +/* Entropy code the mid-only flag */ +void silk_stereo_encode_mid_only( + ec_enc *psRangeEnc, /* I/O Compressor data structure */ + opus_int8 mid_only_flag +) +{ + /* Encode flag that only mid channel is coded */ + ec_enc_icdf( psRangeEnc, mid_only_flag, silk_stereo_only_code_mid_iCDF, 8 ); +} diff --git a/src/opus-1.1/silk/stereo_find_predictor.c b/src/opus-1.1/silk/stereo_find_predictor.c new file mode 100644 index 00000000..e30e90bd --- /dev/null +++ b/src/opus-1.1/silk/stereo_find_predictor.c @@ -0,0 +1,79 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main.h" + +/* Find least-squares prediction gain for one signal based on another and quantize it */ +opus_int32 silk_stereo_find_predictor( /* O Returns predictor in Q13 */ + opus_int32 *ratio_Q14, /* O Ratio of residual and mid energies */ + const opus_int16 x[], /* I Basis signal */ + const opus_int16 y[], /* I Target signal */ + opus_int32 mid_res_amp_Q0[], /* I/O Smoothed mid, residual norms */ + opus_int length, /* I Number of samples */ + opus_int smooth_coef_Q16 /* I Smoothing coefficient */ +) +{ + opus_int scale, scale1, scale2; + opus_int32 nrgx, nrgy, corr, pred_Q13, pred2_Q10; + + /* Find predictor */ + silk_sum_sqr_shift( &nrgx, &scale1, x, length ); + silk_sum_sqr_shift( &nrgy, &scale2, y, length ); + scale = silk_max_int( scale1, scale2 ); + scale = scale + ( scale & 1 ); /* make even */ + nrgy = silk_RSHIFT32( nrgy, scale - scale2 ); + nrgx = silk_RSHIFT32( nrgx, scale - scale1 ); + nrgx = silk_max_int( nrgx, 1 ); + corr = silk_inner_prod_aligned_scale( x, y, scale, length ); + pred_Q13 = silk_DIV32_varQ( corr, nrgx, 13 ); + pred_Q13 = silk_LIMIT( pred_Q13, -(1 << 14), 1 << 14 ); + pred2_Q10 = silk_SMULWB( pred_Q13, pred_Q13 ); + + /* Faster update for signals with large prediction parameters */ + smooth_coef_Q16 = (opus_int)silk_max_int( smooth_coef_Q16, silk_abs( pred2_Q10 ) ); + + /* Smoothed mid and residual norms */ + silk_assert( smooth_coef_Q16 < 32768 ); + scale = silk_RSHIFT( scale, 1 ); + mid_res_amp_Q0[ 0 ] = silk_SMLAWB( mid_res_amp_Q0[ 0 ], silk_LSHIFT( silk_SQRT_APPROX( nrgx ), scale ) - mid_res_amp_Q0[ 0 ], + smooth_coef_Q16 ); + /* Residual energy = nrgy - 2 * pred * corr + pred^2 * nrgx */ + nrgy = silk_SUB_LSHIFT32( nrgy, silk_SMULWB( corr, pred_Q13 ), 3 + 1 ); + nrgy = silk_ADD_LSHIFT32( nrgy, silk_SMULWB( nrgx, pred2_Q10 ), 6 ); + mid_res_amp_Q0[ 1 ] = silk_SMLAWB( mid_res_amp_Q0[ 1 ], silk_LSHIFT( silk_SQRT_APPROX( nrgy ), scale ) - mid_res_amp_Q0[ 1 ], + smooth_coef_Q16 ); + + /* Ratio of smoothed residual and mid norms */ + *ratio_Q14 = silk_DIV32_varQ( mid_res_amp_Q0[ 1 ], silk_max( mid_res_amp_Q0[ 0 ], 1 ), 14 ); + *ratio_Q14 = silk_LIMIT( *ratio_Q14, 0, 32767 ); + + return pred_Q13; +} diff --git a/src/opus-1.1/silk/stereo_quant_pred.c b/src/opus-1.1/silk/stereo_quant_pred.c new file mode 100644 index 00000000..d4ced6c3 --- /dev/null +++ b/src/opus-1.1/silk/stereo_quant_pred.c @@ -0,0 +1,73 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "main.h" + +/* Quantize mid/side predictors */ +void silk_stereo_quant_pred( + opus_int32 pred_Q13[], /* I/O Predictors (out: quantized) */ + opus_int8 ix[ 2 ][ 3 ] /* O Quantization indices */ +) +{ + opus_int i, j, n; + opus_int32 low_Q13, step_Q13, lvl_Q13, err_min_Q13, err_Q13, quant_pred_Q13 = 0; + + /* Quantize */ + for( n = 0; n < 2; n++ ) { + /* Brute-force search over quantization levels */ + err_min_Q13 = silk_int32_MAX; + for( i = 0; i < STEREO_QUANT_TAB_SIZE - 1; i++ ) { + low_Q13 = silk_stereo_pred_quant_Q13[ i ]; + step_Q13 = silk_SMULWB( silk_stereo_pred_quant_Q13[ i + 1 ] - low_Q13, + SILK_FIX_CONST( 0.5 / STEREO_QUANT_SUB_STEPS, 16 ) ); + for( j = 0; j < STEREO_QUANT_SUB_STEPS; j++ ) { + lvl_Q13 = silk_SMLABB( low_Q13, step_Q13, 2 * j + 1 ); + err_Q13 = silk_abs( pred_Q13[ n ] - lvl_Q13 ); + if( err_Q13 < err_min_Q13 ) { + err_min_Q13 = err_Q13; + quant_pred_Q13 = lvl_Q13; + ix[ n ][ 0 ] = i; + ix[ n ][ 1 ] = j; + } else { + /* Error increasing, so we're past the optimum */ + goto done; + } + } + } + done: + ix[ n ][ 2 ] = silk_DIV32_16( ix[ n ][ 0 ], 3 ); + ix[ n ][ 0 ] -= ix[ n ][ 2 ] * 3; + pred_Q13[ n ] = quant_pred_Q13; + } + + /* Subtract second from first predictor (helps when actually applying these) */ + pred_Q13[ 0 ] -= pred_Q13[ 1 ]; +} diff --git a/src/opus-1.1/silk/structs.h b/src/opus-1.1/silk/structs.h new file mode 100644 index 00000000..1826b36a --- /dev/null +++ b/src/opus-1.1/silk/structs.h @@ -0,0 +1,327 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifndef SILK_STRUCTS_H +#define SILK_STRUCTS_H + +#include "typedef.h" +#include "SigProc_FIX.h" +#include "define.h" +#include "entenc.h" +#include "entdec.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/************************************/ +/* Noise shaping quantization state */ +/************************************/ +typedef struct { + opus_int16 xq[ 2 * MAX_FRAME_LENGTH ]; /* Buffer for quantized output signal */ + opus_int32 sLTP_shp_Q14[ 2 * MAX_FRAME_LENGTH ]; + opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ]; + opus_int32 sAR2_Q14[ MAX_SHAPE_LPC_ORDER ]; + opus_int32 sLF_AR_shp_Q14; + opus_int lagPrev; + opus_int sLTP_buf_idx; + opus_int sLTP_shp_buf_idx; + opus_int32 rand_seed; + opus_int32 prev_gain_Q16; + opus_int rewhite_flag; +} silk_nsq_state; + +/********************************/ +/* VAD state */ +/********************************/ +typedef struct { + opus_int32 AnaState[ 2 ]; /* Analysis filterbank state: 0-8 kHz */ + opus_int32 AnaState1[ 2 ]; /* Analysis filterbank state: 0-4 kHz */ + opus_int32 AnaState2[ 2 ]; /* Analysis filterbank state: 0-2 kHz */ + opus_int32 XnrgSubfr[ VAD_N_BANDS ]; /* Subframe energies */ + opus_int32 NrgRatioSmth_Q8[ VAD_N_BANDS ]; /* Smoothed energy level in each band */ + opus_int16 HPstate; /* State of differentiator in the lowest band */ + opus_int32 NL[ VAD_N_BANDS ]; /* Noise energy level in each band */ + opus_int32 inv_NL[ VAD_N_BANDS ]; /* Inverse noise energy level in each band */ + opus_int32 NoiseLevelBias[ VAD_N_BANDS ]; /* Noise level estimator bias/offset */ + opus_int32 counter; /* Frame counter used in the initial phase */ +} silk_VAD_state; + +/* Variable cut-off low-pass filter state */ +typedef struct { + opus_int32 In_LP_State[ 2 ]; /* Low pass filter state */ + opus_int32 transition_frame_no; /* Counter which is mapped to a cut-off frequency */ + opus_int mode; /* Operating mode, <0: switch down, >0: switch up; 0: do nothing */ +} silk_LP_state; + +/* Structure containing NLSF codebook */ +typedef struct { + const opus_int16 nVectors; + const opus_int16 order; + const opus_int16 quantStepSize_Q16; + const opus_int16 invQuantStepSize_Q6; + const opus_uint8 *CB1_NLSF_Q8; + const opus_uint8 *CB1_iCDF; + const opus_uint8 *pred_Q8; + const opus_uint8 *ec_sel; + const opus_uint8 *ec_iCDF; + const opus_uint8 *ec_Rates_Q5; + const opus_int16 *deltaMin_Q15; +} silk_NLSF_CB_struct; + +typedef struct { + opus_int16 pred_prev_Q13[ 2 ]; + opus_int16 sMid[ 2 ]; + opus_int16 sSide[ 2 ]; + opus_int32 mid_side_amp_Q0[ 4 ]; + opus_int16 smth_width_Q14; + opus_int16 width_prev_Q14; + opus_int16 silent_side_len; + opus_int8 predIx[ MAX_FRAMES_PER_PACKET ][ 2 ][ 3 ]; + opus_int8 mid_only_flags[ MAX_FRAMES_PER_PACKET ]; +} stereo_enc_state; + +typedef struct { + opus_int16 pred_prev_Q13[ 2 ]; + opus_int16 sMid[ 2 ]; + opus_int16 sSide[ 2 ]; +} stereo_dec_state; + +typedef struct { + opus_int8 GainsIndices[ MAX_NB_SUBFR ]; + opus_int8 LTPIndex[ MAX_NB_SUBFR ]; + opus_int8 NLSFIndices[ MAX_LPC_ORDER + 1 ]; + opus_int16 lagIndex; + opus_int8 contourIndex; + opus_int8 signalType; + opus_int8 quantOffsetType; + opus_int8 NLSFInterpCoef_Q2; + opus_int8 PERIndex; + opus_int8 LTP_scaleIndex; + opus_int8 Seed; +} SideInfoIndices; + +/********************************/ +/* Encoder state */ +/********************************/ +typedef struct { + opus_int32 In_HP_State[ 2 ]; /* High pass filter state */ + opus_int32 variable_HP_smth1_Q15; /* State of first smoother */ + opus_int32 variable_HP_smth2_Q15; /* State of second smoother */ + silk_LP_state sLP; /* Low pass filter state */ + silk_VAD_state sVAD; /* Voice activity detector state */ + silk_nsq_state sNSQ; /* Noise Shape Quantizer State */ + opus_int16 prev_NLSFq_Q15[ MAX_LPC_ORDER ]; /* Previously quantized NLSF vector */ + opus_int speech_activity_Q8; /* Speech activity */ + opus_int allow_bandwidth_switch; /* Flag indicating that switching of internal bandwidth is allowed */ + opus_int8 LBRRprevLastGainIndex; + opus_int8 prevSignalType; + opus_int prevLag; + opus_int pitch_LPC_win_length; + opus_int max_pitch_lag; /* Highest possible pitch lag (samples) */ + opus_int32 API_fs_Hz; /* API sampling frequency (Hz) */ + opus_int32 prev_API_fs_Hz; /* Previous API sampling frequency (Hz) */ + opus_int maxInternal_fs_Hz; /* Maximum internal sampling frequency (Hz) */ + opus_int minInternal_fs_Hz; /* Minimum internal sampling frequency (Hz) */ + opus_int desiredInternal_fs_Hz; /* Soft request for internal sampling frequency (Hz) */ + opus_int fs_kHz; /* Internal sampling frequency (kHz) */ + opus_int nb_subfr; /* Number of 5 ms subframes in a frame */ + opus_int frame_length; /* Frame length (samples) */ + opus_int subfr_length; /* Subframe length (samples) */ + opus_int ltp_mem_length; /* Length of LTP memory */ + opus_int la_pitch; /* Look-ahead for pitch analysis (samples) */ + opus_int la_shape; /* Look-ahead for noise shape analysis (samples) */ + opus_int shapeWinLength; /* Window length for noise shape analysis (samples) */ + opus_int32 TargetRate_bps; /* Target bitrate (bps) */ + opus_int PacketSize_ms; /* Number of milliseconds to put in each packet */ + opus_int PacketLoss_perc; /* Packet loss rate measured by farend */ + opus_int32 frameCounter; + opus_int Complexity; /* Complexity setting */ + opus_int nStatesDelayedDecision; /* Number of states in delayed decision quantization */ + opus_int useInterpolatedNLSFs; /* Flag for using NLSF interpolation */ + opus_int shapingLPCOrder; /* Filter order for noise shaping filters */ + opus_int predictLPCOrder; /* Filter order for prediction filters */ + opus_int pitchEstimationComplexity; /* Complexity level for pitch estimator */ + opus_int pitchEstimationLPCOrder; /* Whitening filter order for pitch estimator */ + opus_int32 pitchEstimationThreshold_Q16; /* Threshold for pitch estimator */ + opus_int LTPQuantLowComplexity; /* Flag for low complexity LTP quantization */ + opus_int mu_LTP_Q9; /* Rate-distortion tradeoff in LTP quantization */ + opus_int32 sum_log_gain_Q7; /* Cumulative max prediction gain */ + opus_int NLSF_MSVQ_Survivors; /* Number of survivors in NLSF MSVQ */ + opus_int first_frame_after_reset; /* Flag for deactivating NLSF interpolation, pitch prediction */ + opus_int controlled_since_last_payload; /* Flag for ensuring codec_control only runs once per packet */ + opus_int warping_Q16; /* Warping parameter for warped noise shaping */ + opus_int useCBR; /* Flag to enable constant bitrate */ + opus_int prefillFlag; /* Flag to indicate that only buffers are prefilled, no coding */ + const opus_uint8 *pitch_lag_low_bits_iCDF; /* Pointer to iCDF table for low bits of pitch lag index */ + const opus_uint8 *pitch_contour_iCDF; /* Pointer to iCDF table for pitch contour index */ + const silk_NLSF_CB_struct *psNLSF_CB; /* Pointer to NLSF codebook */ + opus_int input_quality_bands_Q15[ VAD_N_BANDS ]; + opus_int input_tilt_Q15; + opus_int SNR_dB_Q7; /* Quality setting */ + + opus_int8 VAD_flags[ MAX_FRAMES_PER_PACKET ]; + opus_int8 LBRR_flag; + opus_int LBRR_flags[ MAX_FRAMES_PER_PACKET ]; + + SideInfoIndices indices; + opus_int8 pulses[ MAX_FRAME_LENGTH ]; + + int arch; + + /* Input/output buffering */ + opus_int16 inputBuf[ MAX_FRAME_LENGTH + 2 ]; /* Buffer containing input signal */ + opus_int inputBufIx; + opus_int nFramesPerPacket; + opus_int nFramesEncoded; /* Number of frames analyzed in current packet */ + + opus_int nChannelsAPI; + opus_int nChannelsInternal; + opus_int channelNb; + + /* Parameters For LTP scaling Control */ + opus_int frames_since_onset; + + /* Specifically for entropy coding */ + opus_int ec_prevSignalType; + opus_int16 ec_prevLagIndex; + + silk_resampler_state_struct resampler_state; + + /* DTX */ + opus_int useDTX; /* Flag to enable DTX */ + opus_int inDTX; /* Flag to signal DTX period */ + opus_int noSpeechCounter; /* Counts concecutive nonactive frames, used by DTX */ + + /* Inband Low Bitrate Redundancy (LBRR) data */ + opus_int useInBandFEC; /* Saves the API setting for query */ + opus_int LBRR_enabled; /* Depends on useInBandFRC, bitrate and packet loss rate */ + opus_int LBRR_GainIncreases; /* Gains increment for coding LBRR frames */ + SideInfoIndices indices_LBRR[ MAX_FRAMES_PER_PACKET ]; + opus_int8 pulses_LBRR[ MAX_FRAMES_PER_PACKET ][ MAX_FRAME_LENGTH ]; +} silk_encoder_state; + + +/* Struct for Packet Loss Concealment */ +typedef struct { + opus_int32 pitchL_Q8; /* Pitch lag to use for voiced concealment */ + opus_int16 LTPCoef_Q14[ LTP_ORDER ]; /* LTP coeficients to use for voiced concealment */ + opus_int16 prevLPC_Q12[ MAX_LPC_ORDER ]; + opus_int last_frame_lost; /* Was previous frame lost */ + opus_int32 rand_seed; /* Seed for unvoiced signal generation */ + opus_int16 randScale_Q14; /* Scaling of unvoiced random signal */ + opus_int32 conc_energy; + opus_int conc_energy_shift; + opus_int16 prevLTP_scale_Q14; + opus_int32 prevGain_Q16[ 2 ]; + opus_int fs_kHz; + opus_int nb_subfr; + opus_int subfr_length; +} silk_PLC_struct; + +/* Struct for CNG */ +typedef struct { + opus_int32 CNG_exc_buf_Q14[ MAX_FRAME_LENGTH ]; + opus_int16 CNG_smth_NLSF_Q15[ MAX_LPC_ORDER ]; + opus_int32 CNG_synth_state[ MAX_LPC_ORDER ]; + opus_int32 CNG_smth_Gain_Q16; + opus_int32 rand_seed; + opus_int fs_kHz; +} silk_CNG_struct; + +/********************************/ +/* Decoder state */ +/********************************/ +typedef struct { + opus_int32 prev_gain_Q16; + opus_int32 exc_Q14[ MAX_FRAME_LENGTH ]; + opus_int32 sLPC_Q14_buf[ MAX_LPC_ORDER ]; + opus_int16 outBuf[ MAX_FRAME_LENGTH + 2 * MAX_SUB_FRAME_LENGTH ]; /* Buffer for output signal */ + opus_int lagPrev; /* Previous Lag */ + opus_int8 LastGainIndex; /* Previous gain index */ + opus_int fs_kHz; /* Sampling frequency in kHz */ + opus_int32 fs_API_hz; /* API sample frequency (Hz) */ + opus_int nb_subfr; /* Number of 5 ms subframes in a frame */ + opus_int frame_length; /* Frame length (samples) */ + opus_int subfr_length; /* Subframe length (samples) */ + opus_int ltp_mem_length; /* Length of LTP memory */ + opus_int LPC_order; /* LPC order */ + opus_int16 prevNLSF_Q15[ MAX_LPC_ORDER ]; /* Used to interpolate LSFs */ + opus_int first_frame_after_reset; /* Flag for deactivating NLSF interpolation */ + const opus_uint8 *pitch_lag_low_bits_iCDF; /* Pointer to iCDF table for low bits of pitch lag index */ + const opus_uint8 *pitch_contour_iCDF; /* Pointer to iCDF table for pitch contour index */ + + /* For buffering payload in case of more frames per packet */ + opus_int nFramesDecoded; + opus_int nFramesPerPacket; + + /* Specifically for entropy coding */ + opus_int ec_prevSignalType; + opus_int16 ec_prevLagIndex; + + opus_int VAD_flags[ MAX_FRAMES_PER_PACKET ]; + opus_int LBRR_flag; + opus_int LBRR_flags[ MAX_FRAMES_PER_PACKET ]; + + silk_resampler_state_struct resampler_state; + + const silk_NLSF_CB_struct *psNLSF_CB; /* Pointer to NLSF codebook */ + + /* Quantization indices */ + SideInfoIndices indices; + + /* CNG state */ + silk_CNG_struct sCNG; + + /* Stuff used for PLC */ + opus_int lossCnt; + opus_int prevSignalType; + + silk_PLC_struct sPLC; + +} silk_decoder_state; + +/************************/ +/* Decoder control */ +/************************/ +typedef struct { + /* Prediction and coding parameters */ + opus_int pitchL[ MAX_NB_SUBFR ]; + opus_int32 Gains_Q16[ MAX_NB_SUBFR ]; + /* Holds interpolated and final coefficients, 4-byte aligned */ + silk_DWORD_ALIGN opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ]; + opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ]; + opus_int LTP_scale_Q14; +} silk_decoder_control; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/opus-1.1/silk/sum_sqr_shift.c b/src/opus-1.1/silk/sum_sqr_shift.c new file mode 100644 index 00000000..12514c99 --- /dev/null +++ b/src/opus-1.1/silk/sum_sqr_shift.c @@ -0,0 +1,85 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "SigProc_FIX.h" + +/* Compute number of bits to right shift the sum of squares of a vector */ +/* of int16s to make it fit in an int32 */ +void silk_sum_sqr_shift( + opus_int32 *energy, /* O Energy of x, after shifting to the right */ + opus_int *shift, /* O Number of bits right shift applied to energy */ + const opus_int16 *x, /* I Input vector */ + opus_int len /* I Length of input vector */ +) +{ + opus_int i, shft; + opus_int32 nrg_tmp, nrg; + + nrg = 0; + shft = 0; + len--; + for( i = 0; i < len; i += 2 ) { + nrg = silk_SMLABB_ovflw( nrg, x[ i ], x[ i ] ); + nrg = silk_SMLABB_ovflw( nrg, x[ i + 1 ], x[ i + 1 ] ); + if( nrg < 0 ) { + /* Scale down */ + nrg = (opus_int32)silk_RSHIFT_uint( (opus_uint32)nrg, 2 ); + shft = 2; + break; + } + } + for( ; i < len; i += 2 ) { + nrg_tmp = silk_SMULBB( x[ i ], x[ i ] ); + nrg_tmp = silk_SMLABB_ovflw( nrg_tmp, x[ i + 1 ], x[ i + 1 ] ); + nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, (opus_uint32)nrg_tmp, shft ); + if( nrg < 0 ) { + /* Scale down */ + nrg = (opus_int32)silk_RSHIFT_uint( (opus_uint32)nrg, 2 ); + shft += 2; + } + } + if( i == len ) { + /* One sample left to process */ + nrg_tmp = silk_SMULBB( x[ i ], x[ i ] ); + nrg = (opus_int32)silk_ADD_RSHIFT_uint( nrg, nrg_tmp, shft ); + } + + /* Make sure to have at least one extra leading zero (two leading zeros in total) */ + if( nrg & 0xC0000000 ) { + nrg = silk_RSHIFT_uint( (opus_uint32)nrg, 2 ); + shft += 2; + } + + /* Output arguments */ + *shift = shft; + *energy = nrg; +} + diff --git a/src/opus-1.1/silk/table_LSF_cos.c b/src/opus-1.1/silk/table_LSF_cos.c new file mode 100644 index 00000000..ec9dc639 --- /dev/null +++ b/src/opus-1.1/silk/table_LSF_cos.c @@ -0,0 +1,70 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "tables.h" + +/* Cosine approximation table for LSF conversion */ +/* Q12 values (even) */ +const opus_int16 silk_LSFCosTab_FIX_Q12[ LSF_COS_TAB_SZ_FIX + 1 ] = { + 8192, 8190, 8182, 8170, + 8152, 8130, 8104, 8072, + 8034, 7994, 7946, 7896, + 7840, 7778, 7714, 7644, + 7568, 7490, 7406, 7318, + 7226, 7128, 7026, 6922, + 6812, 6698, 6580, 6458, + 6332, 6204, 6070, 5934, + 5792, 5648, 5502, 5352, + 5198, 5040, 4880, 4718, + 4552, 4382, 4212, 4038, + 3862, 3684, 3502, 3320, + 3136, 2948, 2760, 2570, + 2378, 2186, 1990, 1794, + 1598, 1400, 1202, 1002, + 802, 602, 402, 202, + 0, -202, -402, -602, + -802, -1002, -1202, -1400, + -1598, -1794, -1990, -2186, + -2378, -2570, -2760, -2948, + -3136, -3320, -3502, -3684, + -3862, -4038, -4212, -4382, + -4552, -4718, -4880, -5040, + -5198, -5352, -5502, -5648, + -5792, -5934, -6070, -6204, + -6332, -6458, -6580, -6698, + -6812, -6922, -7026, -7128, + -7226, -7318, -7406, -7490, + -7568, -7644, -7714, -7778, + -7840, -7896, -7946, -7994, + -8034, -8072, -8104, -8130, + -8152, -8170, -8182, -8190, + -8192 +}; diff --git a/src/opus-1.1/silk/tables.h b/src/opus-1.1/silk/tables.h new file mode 100644 index 00000000..a91431e8 --- /dev/null +++ b/src/opus-1.1/silk/tables.h @@ -0,0 +1,122 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifndef SILK_TABLES_H +#define SILK_TABLES_H + +#include "define.h" +#include "structs.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Entropy coding tables (with size in bytes indicated) */ +extern const opus_uint8 silk_gain_iCDF[ 3 ][ N_LEVELS_QGAIN / 8 ]; /* 24 */ +extern const opus_uint8 silk_delta_gain_iCDF[ MAX_DELTA_GAIN_QUANT - MIN_DELTA_GAIN_QUANT + 1 ]; /* 41 */ + +extern const opus_uint8 silk_pitch_lag_iCDF[ 2 * ( PITCH_EST_MAX_LAG_MS - PITCH_EST_MIN_LAG_MS ) ];/* 32 */ +extern const opus_uint8 silk_pitch_delta_iCDF[ 21 ]; /* 21 */ +extern const opus_uint8 silk_pitch_contour_iCDF[ 34 ]; /* 34 */ +extern const opus_uint8 silk_pitch_contour_NB_iCDF[ 11 ]; /* 11 */ +extern const opus_uint8 silk_pitch_contour_10_ms_iCDF[ 12 ]; /* 12 */ +extern const opus_uint8 silk_pitch_contour_10_ms_NB_iCDF[ 3 ]; /* 3 */ + +extern const opus_uint8 silk_pulses_per_block_iCDF[ N_RATE_LEVELS ][ MAX_PULSES + 2 ]; /* 180 */ +extern const opus_uint8 silk_pulses_per_block_BITS_Q5[ N_RATE_LEVELS - 1 ][ MAX_PULSES + 2 ]; /* 162 */ + +extern const opus_uint8 silk_rate_levels_iCDF[ 2 ][ N_RATE_LEVELS - 1 ]; /* 18 */ +extern const opus_uint8 silk_rate_levels_BITS_Q5[ 2 ][ N_RATE_LEVELS - 1 ]; /* 18 */ + +extern const opus_uint8 silk_max_pulses_table[ 4 ]; /* 4 */ + +extern const opus_uint8 silk_shell_code_table0[ 152 ]; /* 152 */ +extern const opus_uint8 silk_shell_code_table1[ 152 ]; /* 152 */ +extern const opus_uint8 silk_shell_code_table2[ 152 ]; /* 152 */ +extern const opus_uint8 silk_shell_code_table3[ 152 ]; /* 152 */ +extern const opus_uint8 silk_shell_code_table_offsets[ MAX_PULSES + 1 ]; /* 17 */ + +extern const opus_uint8 silk_lsb_iCDF[ 2 ]; /* 2 */ + +extern const opus_uint8 silk_sign_iCDF[ 42 ]; /* 42 */ + +extern const opus_uint8 silk_uniform3_iCDF[ 3 ]; /* 3 */ +extern const opus_uint8 silk_uniform4_iCDF[ 4 ]; /* 4 */ +extern const opus_uint8 silk_uniform5_iCDF[ 5 ]; /* 5 */ +extern const opus_uint8 silk_uniform6_iCDF[ 6 ]; /* 6 */ +extern const opus_uint8 silk_uniform8_iCDF[ 8 ]; /* 8 */ + +extern const opus_uint8 silk_NLSF_EXT_iCDF[ 7 ]; /* 7 */ + +extern const opus_uint8 silk_LTP_per_index_iCDF[ 3 ]; /* 3 */ +extern const opus_uint8 * const silk_LTP_gain_iCDF_ptrs[ NB_LTP_CBKS ]; /* 3 */ +extern const opus_uint8 * const silk_LTP_gain_BITS_Q5_ptrs[ NB_LTP_CBKS ]; /* 3 */ +extern const opus_int16 silk_LTP_gain_middle_avg_RD_Q14; +extern const opus_int8 * const silk_LTP_vq_ptrs_Q7[ NB_LTP_CBKS ]; /* 168 */ +extern const opus_uint8 * const silk_LTP_vq_gain_ptrs_Q7[NB_LTP_CBKS]; + +extern const opus_int8 silk_LTP_vq_sizes[ NB_LTP_CBKS ]; /* 3 */ + +extern const opus_uint8 silk_LTPscale_iCDF[ 3 ]; /* 4 */ +extern const opus_int16 silk_LTPScales_table_Q14[ 3 ]; /* 6 */ + +extern const opus_uint8 silk_type_offset_VAD_iCDF[ 4 ]; /* 4 */ +extern const opus_uint8 silk_type_offset_no_VAD_iCDF[ 2 ]; /* 2 */ + +extern const opus_int16 silk_stereo_pred_quant_Q13[ STEREO_QUANT_TAB_SIZE ]; /* 32 */ +extern const opus_uint8 silk_stereo_pred_joint_iCDF[ 25 ]; /* 25 */ +extern const opus_uint8 silk_stereo_only_code_mid_iCDF[ 2 ]; /* 2 */ + +extern const opus_uint8 * const silk_LBRR_flags_iCDF_ptr[ 2 ]; /* 10 */ + +extern const opus_uint8 silk_NLSF_interpolation_factor_iCDF[ 5 ]; /* 5 */ + +extern const silk_NLSF_CB_struct silk_NLSF_CB_WB; /* 1040 */ +extern const silk_NLSF_CB_struct silk_NLSF_CB_NB_MB; /* 728 */ + +/* Piece-wise linear mapping from bitrate in kbps to coding quality in dB SNR */ +extern const opus_int32 silk_TargetRate_table_NB[ TARGET_RATE_TAB_SZ ]; /* 32 */ +extern const opus_int32 silk_TargetRate_table_MB[ TARGET_RATE_TAB_SZ ]; /* 32 */ +extern const opus_int32 silk_TargetRate_table_WB[ TARGET_RATE_TAB_SZ ]; /* 32 */ +extern const opus_int16 silk_SNR_table_Q1[ TARGET_RATE_TAB_SZ ]; /* 32 */ + +/* Quantization offsets */ +extern const opus_int16 silk_Quantization_Offsets_Q10[ 2 ][ 2 ]; /* 8 */ + +/* Interpolation points for filter coefficients used in the bandwidth transition smoother */ +extern const opus_int32 silk_Transition_LP_B_Q28[ TRANSITION_INT_NUM ][ TRANSITION_NB ]; /* 60 */ +extern const opus_int32 silk_Transition_LP_A_Q28[ TRANSITION_INT_NUM ][ TRANSITION_NA ]; /* 60 */ + +/* Rom table with cosine values */ +extern const opus_int16 silk_LSFCosTab_FIX_Q12[ LSF_COS_TAB_SZ_FIX + 1 ]; /* 258 */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/opus-1.1/silk/tables_LTP.c b/src/opus-1.1/silk/tables_LTP.c new file mode 100644 index 00000000..0e6a0254 --- /dev/null +++ b/src/opus-1.1/silk/tables_LTP.c @@ -0,0 +1,296 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "tables.h" + +const opus_uint8 silk_LTP_per_index_iCDF[3] = { + 179, 99, 0 +}; + +static const opus_uint8 silk_LTP_gain_iCDF_0[8] = { + 71, 56, 43, 30, 21, 12, 6, 0 +}; + +static const opus_uint8 silk_LTP_gain_iCDF_1[16] = { + 199, 165, 144, 124, 109, 96, 84, 71, + 61, 51, 42, 32, 23, 15, 8, 0 +}; + +static const opus_uint8 silk_LTP_gain_iCDF_2[32] = { + 241, 225, 211, 199, 187, 175, 164, 153, + 142, 132, 123, 114, 105, 96, 88, 80, + 72, 64, 57, 50, 44, 38, 33, 29, + 24, 20, 16, 12, 9, 5, 2, 0 +}; + +const opus_int16 silk_LTP_gain_middle_avg_RD_Q14 = 12304; + +static const opus_uint8 silk_LTP_gain_BITS_Q5_0[8] = { + 15, 131, 138, 138, 155, 155, 173, 173 +}; + +static const opus_uint8 silk_LTP_gain_BITS_Q5_1[16] = { + 69, 93, 115, 118, 131, 138, 141, 138, + 150, 150, 155, 150, 155, 160, 166, 160 +}; + +static const opus_uint8 silk_LTP_gain_BITS_Q5_2[32] = { + 131, 128, 134, 141, 141, 141, 145, 145, + 145, 150, 155, 155, 155, 155, 160, 160, + 160, 160, 166, 166, 173, 173, 182, 192, + 182, 192, 192, 192, 205, 192, 205, 224 +}; + +const opus_uint8 * const silk_LTP_gain_iCDF_ptrs[NB_LTP_CBKS] = { + silk_LTP_gain_iCDF_0, + silk_LTP_gain_iCDF_1, + silk_LTP_gain_iCDF_2 +}; + +const opus_uint8 * const silk_LTP_gain_BITS_Q5_ptrs[NB_LTP_CBKS] = { + silk_LTP_gain_BITS_Q5_0, + silk_LTP_gain_BITS_Q5_1, + silk_LTP_gain_BITS_Q5_2 +}; + +static const opus_int8 silk_LTP_gain_vq_0[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 opus_int8 silk_LTP_gain_vq_1[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 opus_int8 silk_LTP_gain_vq_2[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 +} +}; + +const opus_int8 * const silk_LTP_vq_ptrs_Q7[NB_LTP_CBKS] = { + (opus_int8 *)&silk_LTP_gain_vq_0[0][0], + (opus_int8 *)&silk_LTP_gain_vq_1[0][0], + (opus_int8 *)&silk_LTP_gain_vq_2[0][0] +}; + +/* Maximum frequency-dependent response of the pitch taps above, + computed as max(abs(freqz(taps))) */ +static const opus_uint8 silk_LTP_gain_vq_0_gain[8] = { + 46, 2, 90, 87, 93, 91, 82, 98 +}; + +static const opus_uint8 silk_LTP_gain_vq_1_gain[16] = { + 109, 120, 118, 12, 113, 115, 117, 119, + 99, 59, 87, 111, 63, 111, 112, 80 +}; + +static const opus_uint8 silk_LTP_gain_vq_2_gain[32] = { + 126, 124, 125, 124, 129, 121, 126, 23, + 132, 127, 127, 127, 126, 127, 122, 133, + 130, 134, 101, 118, 119, 145, 126, 86, + 124, 120, 123, 119, 170, 173, 107, 109 +}; + +const opus_uint8 * const silk_LTP_vq_gain_ptrs_Q7[NB_LTP_CBKS] = { + &silk_LTP_gain_vq_0_gain[0], + &silk_LTP_gain_vq_1_gain[0], + &silk_LTP_gain_vq_2_gain[0] +}; + +const opus_int8 silk_LTP_vq_sizes[NB_LTP_CBKS] = { + 8, 16, 32 +}; diff --git a/src/opus-1.1/silk/tables_NLSF_CB_NB_MB.c b/src/opus-1.1/silk/tables_NLSF_CB_NB_MB.c new file mode 100644 index 00000000..8c59d207 --- /dev/null +++ b/src/opus-1.1/silk/tables_NLSF_CB_NB_MB.c @@ -0,0 +1,159 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "tables.h" + +static const opus_uint8 silk_NLSF_CB1_NB_MB_Q8[ 320 ] = { + 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 opus_uint8 silk_NLSF_CB1_iCDF_NB_MB[ 64 ] = { + 212, 178, 148, 129, 108, 96, 85, 82, + 79, 77, 61, 59, 57, 56, 51, 49, + 48, 45, 42, 41, 40, 38, 36, 34, + 31, 30, 21, 12, 10, 3, 1, 0, + 255, 245, 244, 236, 233, 225, 217, 203, + 190, 176, 175, 161, 149, 136, 125, 114, + 102, 91, 81, 71, 60, 52, 43, 35, + 28, 20, 19, 18, 12, 11, 5, 0 +}; + +static const opus_uint8 silk_NLSF_CB2_SELECT_NB_MB[ 160 ] = { + 16, 0, 0, 0, 0, 99, 66, 36, + 36, 34, 36, 34, 34, 34, 34, 83, + 69, 36, 52, 34, 116, 102, 70, 68, + 68, 176, 102, 68, 68, 34, 65, 85, + 68, 84, 36, 116, 141, 152, 139, 170, + 132, 187, 184, 216, 137, 132, 249, 168, + 185, 139, 104, 102, 100, 68, 68, 178, + 218, 185, 185, 170, 244, 216, 187, 187, + 170, 244, 187, 187, 219, 138, 103, 155, + 184, 185, 137, 116, 183, 155, 152, 136, + 132, 217, 184, 184, 170, 164, 217, 171, + 155, 139, 244, 169, 184, 185, 170, 164, + 216, 223, 218, 138, 214, 143, 188, 218, + 168, 244, 141, 136, 155, 170, 168, 138, + 220, 219, 139, 164, 219, 202, 216, 137, + 168, 186, 246, 185, 139, 116, 185, 219, + 185, 138, 100, 100, 134, 100, 102, 34, + 68, 68, 100, 68, 168, 203, 221, 218, + 168, 167, 154, 136, 104, 70, 164, 246, + 171, 137, 139, 137, 155, 218, 219, 139 +}; + +static const opus_uint8 silk_NLSF_CB2_iCDF_NB_MB[ 72 ] = { + 255, 254, 253, 238, 14, 3, 2, 1, + 0, 255, 254, 252, 218, 35, 3, 2, + 1, 0, 255, 254, 250, 208, 59, 4, + 2, 1, 0, 255, 254, 246, 194, 71, + 10, 2, 1, 0, 255, 252, 236, 183, + 82, 8, 2, 1, 0, 255, 252, 235, + 180, 90, 17, 2, 1, 0, 255, 248, + 224, 171, 97, 30, 4, 1, 0, 255, + 254, 236, 173, 95, 37, 7, 1, 0 +}; + +static const opus_uint8 silk_NLSF_CB2_BITS_NB_MB_Q5[ 72 ] = { + 255, 255, 255, 131, 6, 145, 255, 255, + 255, 255, 255, 236, 93, 15, 96, 255, + 255, 255, 255, 255, 194, 83, 25, 71, + 221, 255, 255, 255, 255, 162, 73, 34, + 66, 162, 255, 255, 255, 210, 126, 73, + 43, 57, 173, 255, 255, 255, 201, 125, + 71, 48, 58, 130, 255, 255, 255, 166, + 110, 73, 57, 62, 104, 210, 255, 255, + 251, 123, 65, 55, 68, 100, 171, 255 +}; + +static const opus_uint8 silk_NLSF_PRED_NB_MB_Q8[ 18 ] = { + 179, 138, 140, 148, 151, 149, 153, 151, + 163, 116, 67, 82, 59, 92, 72, 100, + 89, 92 +}; + +static const opus_int16 silk_NLSF_DELTA_MIN_NB_MB_Q15[ 11 ] = { + 250, 3, 6, 3, 3, 3, 4, 3, + 3, 3, 461 +}; + +const silk_NLSF_CB_struct silk_NLSF_CB_NB_MB = +{ + 32, + 10, + SILK_FIX_CONST( 0.18, 16 ), + SILK_FIX_CONST( 1.0 / 0.18, 6 ), + silk_NLSF_CB1_NB_MB_Q8, + silk_NLSF_CB1_iCDF_NB_MB, + silk_NLSF_PRED_NB_MB_Q8, + silk_NLSF_CB2_SELECT_NB_MB, + silk_NLSF_CB2_iCDF_NB_MB, + silk_NLSF_CB2_BITS_NB_MB_Q5, + silk_NLSF_DELTA_MIN_NB_MB_Q15, +}; diff --git a/src/opus-1.1/silk/tables_NLSF_CB_WB.c b/src/opus-1.1/silk/tables_NLSF_CB_WB.c new file mode 100644 index 00000000..50af87eb --- /dev/null +++ b/src/opus-1.1/silk/tables_NLSF_CB_WB.c @@ -0,0 +1,198 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "tables.h" + +static const opus_uint8 silk_NLSF_CB1_WB_Q8[ 512 ] = { + 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 opus_uint8 silk_NLSF_CB1_iCDF_WB[ 64 ] = { + 225, 204, 201, 184, 183, 175, 158, 154, + 153, 135, 119, 115, 113, 110, 109, 99, + 98, 95, 79, 68, 52, 50, 48, 45, + 43, 32, 31, 27, 18, 10, 3, 0, + 255, 251, 235, 230, 212, 201, 196, 182, + 167, 166, 163, 151, 138, 124, 110, 104, + 90, 78, 76, 70, 69, 57, 45, 34, + 24, 21, 11, 6, 5, 4, 3, 0 +}; + +static const opus_uint8 silk_NLSF_CB2_SELECT_WB[ 256 ] = { + 0, 0, 0, 0, 0, 0, 0, 1, + 100, 102, 102, 68, 68, 36, 34, 96, + 164, 107, 158, 185, 180, 185, 139, 102, + 64, 66, 36, 34, 34, 0, 1, 32, + 208, 139, 141, 191, 152, 185, 155, 104, + 96, 171, 104, 166, 102, 102, 102, 132, + 1, 0, 0, 0, 0, 16, 16, 0, + 80, 109, 78, 107, 185, 139, 103, 101, + 208, 212, 141, 139, 173, 153, 123, 103, + 36, 0, 0, 0, 0, 0, 0, 1, + 48, 0, 0, 0, 0, 0, 0, 32, + 68, 135, 123, 119, 119, 103, 69, 98, + 68, 103, 120, 118, 118, 102, 71, 98, + 134, 136, 157, 184, 182, 153, 139, 134, + 208, 168, 248, 75, 189, 143, 121, 107, + 32, 49, 34, 34, 34, 0, 17, 2, + 210, 235, 139, 123, 185, 137, 105, 134, + 98, 135, 104, 182, 100, 183, 171, 134, + 100, 70, 68, 70, 66, 66, 34, 131, + 64, 166, 102, 68, 36, 2, 1, 0, + 134, 166, 102, 68, 34, 34, 66, 132, + 212, 246, 158, 139, 107, 107, 87, 102, + 100, 219, 125, 122, 137, 118, 103, 132, + 114, 135, 137, 105, 171, 106, 50, 34, + 164, 214, 141, 143, 185, 151, 121, 103, + 192, 34, 0, 0, 0, 0, 0, 1, + 208, 109, 74, 187, 134, 249, 159, 137, + 102, 110, 154, 118, 87, 101, 119, 101, + 0, 2, 0, 36, 36, 66, 68, 35, + 96, 164, 102, 100, 36, 0, 2, 33, + 167, 138, 174, 102, 100, 84, 2, 2, + 100, 107, 120, 119, 36, 197, 24, 0 +}; + +static const opus_uint8 silk_NLSF_CB2_iCDF_WB[ 72 ] = { + 255, 254, 253, 244, 12, 3, 2, 1, + 0, 255, 254, 252, 224, 38, 3, 2, + 1, 0, 255, 254, 251, 209, 57, 4, + 2, 1, 0, 255, 254, 244, 195, 69, + 4, 2, 1, 0, 255, 251, 232, 184, + 84, 7, 2, 1, 0, 255, 254, 240, + 186, 86, 14, 2, 1, 0, 255, 254, + 239, 178, 91, 30, 5, 1, 0, 255, + 248, 227, 177, 100, 19, 2, 1, 0 +}; + +static const opus_uint8 silk_NLSF_CB2_BITS_WB_Q5[ 72 ] = { + 255, 255, 255, 156, 4, 154, 255, 255, + 255, 255, 255, 227, 102, 15, 92, 255, + 255, 255, 255, 255, 213, 83, 24, 72, + 236, 255, 255, 255, 255, 150, 76, 33, + 63, 214, 255, 255, 255, 190, 121, 77, + 43, 55, 185, 255, 255, 255, 245, 137, + 71, 43, 59, 139, 255, 255, 255, 255, + 131, 66, 50, 66, 107, 194, 255, 255, + 166, 116, 76, 55, 53, 125, 255, 255 +}; + +static const opus_uint8 silk_NLSF_PRED_WB_Q8[ 30 ] = { + 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 opus_int16 silk_NLSF_DELTA_MIN_WB_Q15[ 17 ] = { + 100, 3, 40, 3, 3, 3, 5, 14, + 14, 10, 11, 3, 8, 9, 7, 3, + 347 +}; + +const silk_NLSF_CB_struct silk_NLSF_CB_WB = +{ + 32, + 16, + SILK_FIX_CONST( 0.15, 16 ), + SILK_FIX_CONST( 1.0 / 0.15, 6 ), + silk_NLSF_CB1_WB_Q8, + silk_NLSF_CB1_iCDF_WB, + silk_NLSF_PRED_WB_Q8, + silk_NLSF_CB2_SELECT_WB, + silk_NLSF_CB2_iCDF_WB, + silk_NLSF_CB2_BITS_WB_Q5, + silk_NLSF_DELTA_MIN_WB_Q15, +}; + diff --git a/src/opus-1.1/silk/tables_gain.c b/src/opus-1.1/silk/tables_gain.c new file mode 100644 index 00000000..37e41d89 --- /dev/null +++ b/src/opus-1.1/silk/tables_gain.c @@ -0,0 +1,63 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "tables.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +const opus_uint8 silk_gain_iCDF[ 3 ][ N_LEVELS_QGAIN / 8 ] = +{ +{ + 224, 112, 44, 15, 3, 2, 1, 0 +}, +{ + 254, 237, 192, 132, 70, 23, 4, 0 +}, +{ + 255, 252, 226, 155, 61, 11, 2, 0 +} +}; + +const opus_uint8 silk_delta_gain_iCDF[ MAX_DELTA_GAIN_QUANT - MIN_DELTA_GAIN_QUANT + 1 ] = { + 250, 245, 234, 203, 71, 50, 42, 38, + 35, 33, 31, 29, 28, 27, 26, 25, + 24, 23, 22, 21, 20, 19, 18, 17, + 16, 15, 14, 13, 12, 11, 10, 9, + 8, 7, 6, 5, 4, 3, 2, 1, + 0 +}; + +#ifdef __cplusplus +} +#endif diff --git a/src/opus-1.1/silk/tables_other.c b/src/opus-1.1/silk/tables_other.c new file mode 100644 index 00000000..398686bf --- /dev/null +++ b/src/opus-1.1/silk/tables_other.c @@ -0,0 +1,138 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "structs.h" +#include "define.h" +#include "tables.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Piece-wise linear mapping from bitrate in kbps to coding quality in dB SNR */ +const opus_int32 silk_TargetRate_table_NB[ TARGET_RATE_TAB_SZ ] = { + 0, 8000, 9400, 11500, 13500, 17500, 25000, MAX_TARGET_RATE_BPS +}; +const opus_int32 silk_TargetRate_table_MB[ TARGET_RATE_TAB_SZ ] = { + 0, 9000, 12000, 14500, 18500, 24500, 35500, MAX_TARGET_RATE_BPS +}; +const opus_int32 silk_TargetRate_table_WB[ TARGET_RATE_TAB_SZ ] = { + 0, 10500, 14000, 17000, 21500, 28500, 42000, MAX_TARGET_RATE_BPS +}; +const opus_int16 silk_SNR_table_Q1[ TARGET_RATE_TAB_SZ ] = { + 18, 29, 38, 40, 46, 52, 62, 84 +}; + +/* Tables for stereo predictor coding */ +const opus_int16 silk_stereo_pred_quant_Q13[ STEREO_QUANT_TAB_SIZE ] = { + -13732, -10050, -8266, -7526, -6500, -5000, -2950, -820, + 820, 2950, 5000, 6500, 7526, 8266, 10050, 13732 +}; +const opus_uint8 silk_stereo_pred_joint_iCDF[ 25 ] = { + 249, 247, 246, 245, 244, + 234, 210, 202, 201, 200, + 197, 174, 82, 59, 56, + 55, 54, 46, 22, 12, + 11, 10, 9, 7, 0 +}; +const opus_uint8 silk_stereo_only_code_mid_iCDF[ 2 ] = { 64, 0 }; + +/* Tables for LBRR flags */ +static const opus_uint8 silk_LBRR_flags_2_iCDF[ 3 ] = { 203, 150, 0 }; +static const opus_uint8 silk_LBRR_flags_3_iCDF[ 7 ] = { 215, 195, 166, 125, 110, 82, 0 }; +const opus_uint8 * const silk_LBRR_flags_iCDF_ptr[ 2 ] = { + silk_LBRR_flags_2_iCDF, + silk_LBRR_flags_3_iCDF +}; + +/* Table for LSB coding */ +const opus_uint8 silk_lsb_iCDF[ 2 ] = { 120, 0 }; + +/* Tables for LTPScale */ +const opus_uint8 silk_LTPscale_iCDF[ 3 ] = { 128, 64, 0 }; + +/* Tables for signal type and offset coding */ +const opus_uint8 silk_type_offset_VAD_iCDF[ 4 ] = { + 232, 158, 10, 0 +}; +const opus_uint8 silk_type_offset_no_VAD_iCDF[ 2 ] = { + 230, 0 +}; + +/* Tables for NLSF interpolation factor */ +const opus_uint8 silk_NLSF_interpolation_factor_iCDF[ 5 ] = { 243, 221, 192, 181, 0 }; + +/* Quantization offsets */ +const opus_int16 silk_Quantization_Offsets_Q10[ 2 ][ 2 ] = { + { OFFSET_UVL_Q10, OFFSET_UVH_Q10 }, { OFFSET_VL_Q10, OFFSET_VH_Q10 } +}; + +/* Table for LTPScale */ +const opus_int16 silk_LTPScales_table_Q14[ 3 ] = { 15565, 12288, 8192 }; + +/* Uniform entropy tables */ +const opus_uint8 silk_uniform3_iCDF[ 3 ] = { 171, 85, 0 }; +const opus_uint8 silk_uniform4_iCDF[ 4 ] = { 192, 128, 64, 0 }; +const opus_uint8 silk_uniform5_iCDF[ 5 ] = { 205, 154, 102, 51, 0 }; +const opus_uint8 silk_uniform6_iCDF[ 6 ] = { 213, 171, 128, 85, 43, 0 }; +const opus_uint8 silk_uniform8_iCDF[ 8 ] = { 224, 192, 160, 128, 96, 64, 32, 0 }; + +const opus_uint8 silk_NLSF_EXT_iCDF[ 7 ] = { 100, 40, 16, 7, 3, 1, 0 }; + +/* Elliptic/Cauer filters designed with 0.1 dB passband ripple, + 80 dB minimum stopband attenuation, and + [0.95 : 0.15 : 0.35] normalized cut off frequencies. */ + +/* Interpolation points for filter coefficients used in the bandwidth transition smoother */ +const opus_int32 silk_Transition_LP_B_Q28[ TRANSITION_INT_NUM ][ TRANSITION_NB ] = +{ +{ 250767114, 501534038, 250767114 }, +{ 209867381, 419732057, 209867381 }, +{ 170987846, 341967853, 170987846 }, +{ 131531482, 263046905, 131531482 }, +{ 89306658, 178584282, 89306658 } +}; + +/* Interpolation points for filter coefficients used in the bandwidth transition smoother */ +const opus_int32 silk_Transition_LP_A_Q28[ TRANSITION_INT_NUM ][ TRANSITION_NA ] = +{ +{ 506393414, 239854379 }, +{ 411067935, 169683996 }, +{ 306733530, 116694253 }, +{ 185807084, 77959395 }, +{ 35497197, 57401098 } +}; + +#ifdef __cplusplus +} +#endif + diff --git a/src/opus-1.1/silk/tables_pitch_lag.c b/src/opus-1.1/silk/tables_pitch_lag.c new file mode 100644 index 00000000..e80cc59a --- /dev/null +++ b/src/opus-1.1/silk/tables_pitch_lag.c @@ -0,0 +1,69 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "tables.h" + +const opus_uint8 silk_pitch_lag_iCDF[ 2 * ( PITCH_EST_MAX_LAG_MS - PITCH_EST_MIN_LAG_MS ) ] = { + 253, 250, 244, 233, 212, 182, 150, 131, + 120, 110, 98, 85, 72, 60, 49, 40, + 32, 25, 19, 15, 13, 11, 9, 8, + 7, 6, 5, 4, 3, 2, 1, 0 +}; + +const opus_uint8 silk_pitch_delta_iCDF[21] = { + 210, 208, 206, 203, 199, 193, 183, 168, + 142, 104, 74, 52, 37, 27, 20, 14, + 10, 6, 4, 2, 0 +}; + +const opus_uint8 silk_pitch_contour_iCDF[34] = { + 223, 201, 183, 167, 152, 138, 124, 111, + 98, 88, 79, 70, 62, 56, 50, 44, + 39, 35, 31, 27, 24, 21, 18, 16, + 14, 12, 10, 8, 6, 4, 3, 2, + 1, 0 +}; + +const opus_uint8 silk_pitch_contour_NB_iCDF[11] = { + 188, 176, 155, 138, 119, 97, 67, 43, + 26, 10, 0 +}; + +const opus_uint8 silk_pitch_contour_10_ms_iCDF[12] = { + 165, 119, 80, 61, 47, 35, 27, 20, + 14, 9, 4, 0 +}; + +const opus_uint8 silk_pitch_contour_10_ms_NB_iCDF[3] = { + 113, 63, 0 +}; + + diff --git a/src/opus-1.1/silk/tables_pulses_per_block.c b/src/opus-1.1/silk/tables_pulses_per_block.c new file mode 100644 index 00000000..c7c01c88 --- /dev/null +++ b/src/opus-1.1/silk/tables_pulses_per_block.c @@ -0,0 +1,264 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "tables.h" + +const opus_uint8 silk_max_pulses_table[ 4 ] = { + 8, 10, 12, 16 +}; + +const opus_uint8 silk_pulses_per_block_iCDF[ 10 ][ 18 ] = { +{ + 125, 51, 26, 18, 15, 12, 11, 10, + 9, 8, 7, 6, 5, 4, 3, 2, + 1, 0 +}, +{ + 198, 105, 45, 22, 15, 12, 11, 10, + 9, 8, 7, 6, 5, 4, 3, 2, + 1, 0 +}, +{ + 213, 162, 116, 83, 59, 43, 32, 24, + 18, 15, 12, 9, 7, 6, 5, 3, + 2, 0 +}, +{ + 239, 187, 116, 59, 28, 16, 11, 10, + 9, 8, 7, 6, 5, 4, 3, 2, + 1, 0 +}, +{ + 250, 229, 188, 135, 86, 51, 30, 19, + 13, 10, 8, 6, 5, 4, 3, 2, + 1, 0 +}, +{ + 249, 235, 213, 185, 156, 128, 103, 83, + 66, 53, 42, 33, 26, 21, 17, 13, + 10, 0 +}, +{ + 254, 249, 235, 206, 164, 118, 77, 46, + 27, 16, 10, 7, 5, 4, 3, 2, + 1, 0 +}, +{ + 255, 253, 249, 239, 220, 191, 156, 119, + 85, 57, 37, 23, 15, 10, 6, 4, + 2, 0 +}, +{ + 255, 253, 251, 246, 237, 223, 203, 179, + 152, 124, 98, 75, 55, 40, 29, 21, + 15, 0 +}, +{ + 255, 254, 253, 247, 220, 162, 106, 67, + 42, 28, 18, 12, 9, 6, 4, 3, + 2, 0 +} +}; + +const opus_uint8 silk_pulses_per_block_BITS_Q5[ 9 ][ 18 ] = { +{ + 31, 57, 107, 160, 205, 205, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255 +}, +{ + 69, 47, 67, 111, 166, 205, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255 +}, +{ + 82, 74, 79, 95, 109, 128, 145, 160, + 173, 205, 205, 205, 224, 255, 255, 224, + 255, 224 +}, +{ + 125, 74, 59, 69, 97, 141, 182, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255 +}, +{ + 173, 115, 85, 73, 76, 92, 115, 145, + 173, 205, 224, 224, 255, 255, 255, 255, + 255, 255 +}, +{ + 166, 134, 113, 102, 101, 102, 107, 118, + 125, 138, 145, 155, 166, 182, 192, 192, + 205, 150 +}, +{ + 224, 182, 134, 101, 83, 79, 85, 97, + 120, 145, 173, 205, 224, 255, 255, 255, + 255, 255 +}, +{ + 255, 224, 192, 150, 120, 101, 92, 89, + 93, 102, 118, 134, 160, 182, 192, 224, + 224, 224 +}, +{ + 255, 224, 224, 182, 155, 134, 118, 109, + 104, 102, 106, 111, 118, 131, 145, 160, + 173, 131 +} +}; + +const opus_uint8 silk_rate_levels_iCDF[ 2 ][ 9 ] = +{ +{ + 241, 190, 178, 132, 87, 74, 41, 14, + 0 +}, +{ + 223, 193, 157, 140, 106, 57, 39, 18, + 0 +} +}; + +const opus_uint8 silk_rate_levels_BITS_Q5[ 2 ][ 9 ] = +{ +{ + 131, 74, 141, 79, 80, 138, 95, 104, + 134 +}, +{ + 95, 99, 91, 125, 93, 76, 123, 115, + 123 +} +}; + +const opus_uint8 silk_shell_code_table0[ 152 ] = { + 128, 0, 214, 42, 0, 235, 128, 21, + 0, 244, 184, 72, 11, 0, 248, 214, + 128, 42, 7, 0, 248, 225, 170, 80, + 25, 5, 0, 251, 236, 198, 126, 54, + 18, 3, 0, 250, 238, 211, 159, 82, + 35, 15, 5, 0, 250, 231, 203, 168, + 128, 88, 53, 25, 6, 0, 252, 238, + 216, 185, 148, 108, 71, 40, 18, 4, + 0, 253, 243, 225, 199, 166, 128, 90, + 57, 31, 13, 3, 0, 254, 246, 233, + 212, 183, 147, 109, 73, 44, 23, 10, + 2, 0, 255, 250, 240, 223, 198, 166, + 128, 90, 58, 33, 16, 6, 1, 0, + 255, 251, 244, 231, 210, 181, 146, 110, + 75, 46, 25, 12, 5, 1, 0, 255, + 253, 248, 238, 221, 196, 164, 128, 92, + 60, 35, 18, 8, 3, 1, 0, 255, + 253, 249, 242, 229, 208, 180, 146, 110, + 76, 48, 27, 14, 7, 3, 1, 0 +}; + +const opus_uint8 silk_shell_code_table1[ 152 ] = { + 129, 0, 207, 50, 0, 236, 129, 20, + 0, 245, 185, 72, 10, 0, 249, 213, + 129, 42, 6, 0, 250, 226, 169, 87, + 27, 4, 0, 251, 233, 194, 130, 62, + 20, 4, 0, 250, 236, 207, 160, 99, + 47, 17, 3, 0, 255, 240, 217, 182, + 131, 81, 41, 11, 1, 0, 255, 254, + 233, 201, 159, 107, 61, 20, 2, 1, + 0, 255, 249, 233, 206, 170, 128, 86, + 50, 23, 7, 1, 0, 255, 250, 238, + 217, 186, 148, 108, 70, 39, 18, 6, + 1, 0, 255, 252, 243, 226, 200, 166, + 128, 90, 56, 30, 13, 4, 1, 0, + 255, 252, 245, 231, 209, 180, 146, 110, + 76, 47, 25, 11, 4, 1, 0, 255, + 253, 248, 237, 219, 194, 163, 128, 93, + 62, 37, 19, 8, 3, 1, 0, 255, + 254, 250, 241, 226, 205, 177, 145, 111, + 79, 51, 30, 15, 6, 2, 1, 0 +}; + +const opus_uint8 silk_shell_code_table2[ 152 ] = { + 129, 0, 203, 54, 0, 234, 129, 23, + 0, 245, 184, 73, 10, 0, 250, 215, + 129, 41, 5, 0, 252, 232, 173, 86, + 24, 3, 0, 253, 240, 200, 129, 56, + 15, 2, 0, 253, 244, 217, 164, 94, + 38, 10, 1, 0, 253, 245, 226, 189, + 132, 71, 27, 7, 1, 0, 253, 246, + 231, 203, 159, 105, 56, 23, 6, 1, + 0, 255, 248, 235, 213, 179, 133, 85, + 47, 19, 5, 1, 0, 255, 254, 243, + 221, 194, 159, 117, 70, 37, 12, 2, + 1, 0, 255, 254, 248, 234, 208, 171, + 128, 85, 48, 22, 8, 2, 1, 0, + 255, 254, 250, 240, 220, 189, 149, 107, + 67, 36, 16, 6, 2, 1, 0, 255, + 254, 251, 243, 227, 201, 166, 128, 90, + 55, 29, 13, 5, 2, 1, 0, 255, + 254, 252, 246, 234, 213, 183, 147, 109, + 73, 43, 22, 10, 4, 2, 1, 0 +}; + +const opus_uint8 silk_shell_code_table3[ 152 ] = { + 130, 0, 200, 58, 0, 231, 130, 26, + 0, 244, 184, 76, 12, 0, 249, 214, + 130, 43, 6, 0, 252, 232, 173, 87, + 24, 3, 0, 253, 241, 203, 131, 56, + 14, 2, 0, 254, 246, 221, 167, 94, + 35, 8, 1, 0, 254, 249, 232, 193, + 130, 65, 23, 5, 1, 0, 255, 251, + 239, 211, 162, 99, 45, 15, 4, 1, + 0, 255, 251, 243, 223, 186, 131, 74, + 33, 11, 3, 1, 0, 255, 252, 245, + 230, 202, 158, 105, 57, 24, 8, 2, + 1, 0, 255, 253, 247, 235, 214, 179, + 132, 84, 44, 19, 7, 2, 1, 0, + 255, 254, 250, 240, 223, 196, 159, 112, + 69, 36, 15, 6, 2, 1, 0, 255, + 254, 253, 245, 231, 209, 176, 136, 93, + 55, 27, 11, 3, 2, 1, 0, 255, + 254, 253, 252, 239, 221, 194, 158, 117, + 76, 42, 18, 4, 3, 2, 1, 0 +}; + +const opus_uint8 silk_shell_code_table_offsets[ 17 ] = { + 0, 0, 2, 5, 9, 14, 20, 27, + 35, 44, 54, 65, 77, 90, 104, 119, + 135 +}; + +const opus_uint8 silk_sign_iCDF[ 42 ] = { + 254, 49, 67, 77, 82, 93, 99, + 198, 11, 18, 24, 31, 36, 45, + 255, 46, 66, 78, 87, 94, 104, + 208, 14, 21, 32, 42, 51, 66, + 255, 94, 104, 109, 112, 115, 118, + 248, 53, 69, 80, 88, 95, 102 +}; diff --git a/src/opus-1.1/silk/tuning_parameters.h b/src/opus-1.1/silk/tuning_parameters.h new file mode 100644 index 00000000..e1057bba --- /dev/null +++ b/src/opus-1.1/silk/tuning_parameters.h @@ -0,0 +1,171 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifndef SILK_TUNING_PARAMETERS_H +#define SILK_TUNING_PARAMETERS_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Decay time for bitreservoir */ +#define BITRESERVOIR_DECAY_TIME_MS 500 + +/*******************/ +/* Pitch estimator */ +/*******************/ + +/* Level of noise floor for whitening filter LPC analysis in pitch analysis */ +#define FIND_PITCH_WHITE_NOISE_FRACTION 1e-3f + +/* Bandwidth expansion for whitening filter in pitch analysis */ +#define FIND_PITCH_BANDWIDTH_EXPANSION 0.99f + +/*********************/ +/* Linear prediction */ +/*********************/ + +/* LPC analysis regularization */ +#define FIND_LPC_COND_FAC 1e-5f + +/* LTP analysis defines */ +#define FIND_LTP_COND_FAC 1e-5f +#define LTP_DAMPING 0.05f +#define LTP_SMOOTHING 0.1f + +/* LTP quantization settings */ +#define MU_LTP_QUANT_NB 0.03f +#define MU_LTP_QUANT_MB 0.025f +#define MU_LTP_QUANT_WB 0.02f + +/* Max cumulative LTP gain */ +#define MAX_SUM_LOG_GAIN_DB 250.0f + +/***********************/ +/* High pass filtering */ +/***********************/ + +/* Smoothing parameters for low end of pitch frequency range estimation */ +#define VARIABLE_HP_SMTH_COEF1 0.1f +#define VARIABLE_HP_SMTH_COEF2 0.015f +#define VARIABLE_HP_MAX_DELTA_FREQ 0.4f + +/* Min and max cut-off frequency values (-3 dB points) */ +#define VARIABLE_HP_MIN_CUTOFF_HZ 60 +#define VARIABLE_HP_MAX_CUTOFF_HZ 100 + +/***********/ +/* Various */ +/***********/ + +/* VAD threshold */ +#define SPEECH_ACTIVITY_DTX_THRES 0.05f + +/* Speech Activity LBRR enable threshold */ +#define LBRR_SPEECH_ACTIVITY_THRES 0.3f + +/*************************/ +/* Perceptual parameters */ +/*************************/ + +/* reduction in coding SNR during low speech activity */ +#define BG_SNR_DECR_dB 2.0f + +/* factor for reducing quantization noise during voiced speech */ +#define HARM_SNR_INCR_dB 2.0f + +/* factor for reducing quantization noise for unvoiced sparse signals */ +#define SPARSE_SNR_INCR_dB 2.0f + +/* threshold for sparseness measure above which to use lower quantization offset during unvoiced */ +#define SPARSENESS_THRESHOLD_QNT_OFFSET 0.75f + +/* warping control */ +#define WARPING_MULTIPLIER 0.015f + +/* fraction added to first autocorrelation value */ +#define SHAPE_WHITE_NOISE_FRACTION 5e-5f + +/* noise shaping filter chirp factor */ +#define BANDWIDTH_EXPANSION 0.95f + +/* difference between chirp factors for analysis and synthesis noise shaping filters at low bitrates */ +#define LOW_RATE_BANDWIDTH_EXPANSION_DELTA 0.01f + +/* extra harmonic boosting (signal shaping) at low bitrates */ +#define LOW_RATE_HARMONIC_BOOST 0.1f + +/* extra harmonic boosting (signal shaping) for noisy input signals */ +#define LOW_INPUT_QUALITY_HARMONIC_BOOST 0.1f + +/* harmonic noise shaping */ +#define HARMONIC_SHAPING 0.3f + +/* extra harmonic noise shaping for high bitrates or noisy input */ +#define HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING 0.2f + +/* parameter for shaping noise towards higher frequencies */ +#define HP_NOISE_COEF 0.25f + +/* parameter for shaping noise even more towards higher frequencies during voiced speech */ +#define HARM_HP_NOISE_COEF 0.35f + +/* parameter for applying a high-pass tilt to the input signal */ +#define INPUT_TILT 0.05f + +/* parameter for extra high-pass tilt to the input signal at high rates */ +#define HIGH_RATE_INPUT_TILT 0.1f + +/* parameter for reducing noise at the very low frequencies */ +#define LOW_FREQ_SHAPING 4.0f + +/* less reduction of noise at the very low frequencies for signals with low SNR at low frequencies */ +#define LOW_QUALITY_LOW_FREQ_SHAPING_DECR 0.5f + +/* subframe smoothing coefficient for HarmBoost, HarmShapeGain, Tilt (lower -> more smoothing) */ +#define SUBFR_SMTH_COEF 0.4f + +/* parameters defining the R/D tradeoff in the residual quantizer */ +#define LAMBDA_OFFSET 1.2f +#define LAMBDA_SPEECH_ACT -0.2f +#define LAMBDA_DELAYED_DECISIONS -0.05f +#define LAMBDA_INPUT_QUALITY -0.1f +#define LAMBDA_CODING_QUALITY -0.2f +#define LAMBDA_QUANT_OFFSET 0.8f + +/* Compensation in bitrate calculations for 10 ms modes */ +#define REDUCE_BITRATE_10_MS_BPS 2200 + +/* Maximum time before allowing a bandwidth transition */ +#define MAX_BANDWIDTH_SWITCH_DELAY_MS 5000 + +#ifdef __cplusplus +} +#endif + +#endif /* SILK_TUNING_PARAMETERS_H */ diff --git a/src/opus-1.1/silk/typedef.h b/src/opus-1.1/silk/typedef.h new file mode 100644 index 00000000..97b7e709 --- /dev/null +++ b/src/opus-1.1/silk/typedef.h @@ -0,0 +1,78 @@ +/*********************************************************************** +Copyright (c) 2006-2011, Skype Limited. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +- Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +- Neither the name of Internet Society, IETF or IETF Trust, nor the +names of specific contributors, may be used to endorse or promote +products derived from this software without specific prior written +permission. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. +***********************************************************************/ + +#ifndef SILK_TYPEDEF_H +#define SILK_TYPEDEF_H + +#include "opus_types.h" +#include "opus_defines.h" + +#ifndef FIXED_POINT +# include +# define silk_float float +# define silk_float_MAX FLT_MAX +#endif + +#define silk_int64_MAX ((opus_int64)0x7FFFFFFFFFFFFFFFLL) /* 2^63 - 1 */ +#define silk_int64_MIN ((opus_int64)0x8000000000000000LL) /* -2^63 */ +#define silk_int32_MAX 0x7FFFFFFF /* 2^31 - 1 = 2147483647 */ +#define silk_int32_MIN ((opus_int32)0x80000000) /* -2^31 = -2147483648 */ +#define silk_int16_MAX 0x7FFF /* 2^15 - 1 = 32767 */ +#define silk_int16_MIN ((opus_int16)0x8000) /* -2^15 = -32768 */ +#define silk_int8_MAX 0x7F /* 2^7 - 1 = 127 */ +#define silk_int8_MIN ((opus_int8)0x80) /* -2^7 = -128 */ +#define silk_uint8_MAX 0xFF /* 2^8 - 1 = 255 */ + +#define silk_TRUE 1 +#define silk_FALSE 0 + +/* assertions */ +#if (defined _WIN32 && !defined _WINCE && !defined(__GNUC__) && !defined(NO_ASSERTS)) +# ifndef silk_assert +# include /* ASSERTE() */ +# define silk_assert(COND) _ASSERTE(COND) +# endif +#else +# ifdef ENABLE_ASSERTIONS +# include +# include +#define silk_fatal(str) _silk_fatal(str, __FILE__, __LINE__); +#ifdef __GNUC__ +__attribute__((noreturn)) +#endif +static OPUS_INLINE void _silk_fatal(const char *str, const char *file, int line) +{ + fprintf (stderr, "Fatal (internal) error in %s, line %d: %s\n", file, line, str); + abort(); +} +# define silk_assert(COND) {if (!(COND)) {silk_fatal("assertion failed: " #COND);}} +# else +# define silk_assert(COND) +# endif +#endif + +#endif /* SILK_TYPEDEF_H */ diff --git a/src/opus-1.1/src/analysis.c b/src/opus-1.1/src/analysis.c new file mode 100644 index 00000000..778a62aa --- /dev/null +++ b/src/opus-1.1/src/analysis.c @@ -0,0 +1,645 @@ +/* Copyright (c) 2011 Xiph.Org Foundation + Written by Jean-Marc Valin */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "kiss_fft.h" +#include "celt.h" +#include "modes.h" +#include "arch.h" +#include "quant_bands.h" +#include +#include "analysis.h" +#include "mlp.h" +#include "stack_alloc.h" + +extern const MLP net; + +#ifndef M_PI +#define M_PI 3.141592653 +#endif + +static const float dct_table[128] = { + 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, + 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, 0.250000f, + 0.351851f, 0.338330f, 0.311806f, 0.273300f, 0.224292f, 0.166664f, 0.102631f, 0.034654f, + -0.034654f,-0.102631f,-0.166664f,-0.224292f,-0.273300f,-0.311806f,-0.338330f,-0.351851f, + 0.346760f, 0.293969f, 0.196424f, 0.068975f,-0.068975f,-0.196424f,-0.293969f,-0.346760f, + -0.346760f,-0.293969f,-0.196424f,-0.068975f, 0.068975f, 0.196424f, 0.293969f, 0.346760f, + 0.338330f, 0.224292f, 0.034654f,-0.166664f,-0.311806f,-0.351851f,-0.273300f,-0.102631f, + 0.102631f, 0.273300f, 0.351851f, 0.311806f, 0.166664f,-0.034654f,-0.224292f,-0.338330f, + 0.326641f, 0.135299f,-0.135299f,-0.326641f,-0.326641f,-0.135299f, 0.135299f, 0.326641f, + 0.326641f, 0.135299f,-0.135299f,-0.326641f,-0.326641f,-0.135299f, 0.135299f, 0.326641f, + 0.311806f, 0.034654f,-0.273300f,-0.338330f,-0.102631f, 0.224292f, 0.351851f, 0.166664f, + -0.166664f,-0.351851f,-0.224292f, 0.102631f, 0.338330f, 0.273300f,-0.034654f,-0.311806f, + 0.293969f,-0.068975f,-0.346760f,-0.196424f, 0.196424f, 0.346760f, 0.068975f,-0.293969f, + -0.293969f, 0.068975f, 0.346760f, 0.196424f,-0.196424f,-0.346760f,-0.068975f, 0.293969f, + 0.273300f,-0.166664f,-0.338330f, 0.034654f, 0.351851f, 0.102631f,-0.311806f,-0.224292f, + 0.224292f, 0.311806f,-0.102631f,-0.351851f,-0.034654f, 0.338330f, 0.166664f,-0.273300f, +}; + +static const float analysis_window[240] = { + 0.000043f, 0.000171f, 0.000385f, 0.000685f, 0.001071f, 0.001541f, 0.002098f, 0.002739f, + 0.003466f, 0.004278f, 0.005174f, 0.006156f, 0.007222f, 0.008373f, 0.009607f, 0.010926f, + 0.012329f, 0.013815f, 0.015385f, 0.017037f, 0.018772f, 0.020590f, 0.022490f, 0.024472f, + 0.026535f, 0.028679f, 0.030904f, 0.033210f, 0.035595f, 0.038060f, 0.040604f, 0.043227f, + 0.045928f, 0.048707f, 0.051564f, 0.054497f, 0.057506f, 0.060591f, 0.063752f, 0.066987f, + 0.070297f, 0.073680f, 0.077136f, 0.080665f, 0.084265f, 0.087937f, 0.091679f, 0.095492f, + 0.099373f, 0.103323f, 0.107342f, 0.111427f, 0.115579f, 0.119797f, 0.124080f, 0.128428f, + 0.132839f, 0.137313f, 0.141849f, 0.146447f, 0.151105f, 0.155823f, 0.160600f, 0.165435f, + 0.170327f, 0.175276f, 0.180280f, 0.185340f, 0.190453f, 0.195619f, 0.200838f, 0.206107f, + 0.211427f, 0.216797f, 0.222215f, 0.227680f, 0.233193f, 0.238751f, 0.244353f, 0.250000f, + 0.255689f, 0.261421f, 0.267193f, 0.273005f, 0.278856f, 0.284744f, 0.290670f, 0.296632f, + 0.302628f, 0.308658f, 0.314721f, 0.320816f, 0.326941f, 0.333097f, 0.339280f, 0.345492f, + 0.351729f, 0.357992f, 0.364280f, 0.370590f, 0.376923f, 0.383277f, 0.389651f, 0.396044f, + 0.402455f, 0.408882f, 0.415325f, 0.421783f, 0.428254f, 0.434737f, 0.441231f, 0.447736f, + 0.454249f, 0.460770f, 0.467298f, 0.473832f, 0.480370f, 0.486912f, 0.493455f, 0.500000f, + 0.506545f, 0.513088f, 0.519630f, 0.526168f, 0.532702f, 0.539230f, 0.545751f, 0.552264f, + 0.558769f, 0.565263f, 0.571746f, 0.578217f, 0.584675f, 0.591118f, 0.597545f, 0.603956f, + 0.610349f, 0.616723f, 0.623077f, 0.629410f, 0.635720f, 0.642008f, 0.648271f, 0.654508f, + 0.660720f, 0.666903f, 0.673059f, 0.679184f, 0.685279f, 0.691342f, 0.697372f, 0.703368f, + 0.709330f, 0.715256f, 0.721144f, 0.726995f, 0.732807f, 0.738579f, 0.744311f, 0.750000f, + 0.755647f, 0.761249f, 0.766807f, 0.772320f, 0.777785f, 0.783203f, 0.788573f, 0.793893f, + 0.799162f, 0.804381f, 0.809547f, 0.814660f, 0.819720f, 0.824724f, 0.829673f, 0.834565f, + 0.839400f, 0.844177f, 0.848895f, 0.853553f, 0.858151f, 0.862687f, 0.867161f, 0.871572f, + 0.875920f, 0.880203f, 0.884421f, 0.888573f, 0.892658f, 0.896677f, 0.900627f, 0.904508f, + 0.908321f, 0.912063f, 0.915735f, 0.919335f, 0.922864f, 0.926320f, 0.929703f, 0.933013f, + 0.936248f, 0.939409f, 0.942494f, 0.945503f, 0.948436f, 0.951293f, 0.954072f, 0.956773f, + 0.959396f, 0.961940f, 0.964405f, 0.966790f, 0.969096f, 0.971321f, 0.973465f, 0.975528f, + 0.977510f, 0.979410f, 0.981228f, 0.982963f, 0.984615f, 0.986185f, 0.987671f, 0.989074f, + 0.990393f, 0.991627f, 0.992778f, 0.993844f, 0.994826f, 0.995722f, 0.996534f, 0.997261f, + 0.997902f, 0.998459f, 0.998929f, 0.999315f, 0.999615f, 0.999829f, 0.999957f, 1.000000f, +}; + +static const int tbands[NB_TBANDS+1] = { + 2, 4, 6, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 68, 80, 96, 120 +}; + +static const int extra_bands[NB_TOT_BANDS+1] = { + 1, 2, 4, 6, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, 68, 80, 96, 120, 160, 200 +}; + +/*static const float tweight[NB_TBANDS+1] = { + .3, .4, .5, .6, .7, .8, .9, 1., 1., 1., 1., 1., 1., 1., .8, .7, .6, .5 +};*/ + +#define NB_TONAL_SKIP_BANDS 9 + +#define cA 0.43157974f +#define cB 0.67848403f +#define cC 0.08595542f +#define cE ((float)M_PI/2) +static OPUS_INLINE float fast_atan2f(float y, float x) { + float x2, y2; + /* Should avoid underflow on the values we'll get */ + if (ABS16(x)+ABS16(y)<1e-9f) + { + x*=1e12f; + y*=1e12f; + } + x2 = x*x; + y2 = y*y; + if(x2read_pos; + curr_lookahead = tonal->write_pos-tonal->read_pos; + if (curr_lookahead<0) + curr_lookahead += DETECT_SIZE; + + if (len > 480 && pos != tonal->write_pos) + { + pos++; + if (pos==DETECT_SIZE) + pos=0; + } + if (pos == tonal->write_pos) + pos--; + if (pos<0) + pos = DETECT_SIZE-1; + OPUS_COPY(info_out, &tonal->info[pos], 1); + tonal->read_subframe += len/120; + while (tonal->read_subframe>=4) + { + tonal->read_subframe -= 4; + tonal->read_pos++; + } + if (tonal->read_pos>=DETECT_SIZE) + tonal->read_pos-=DETECT_SIZE; + + /* Compensate for the delay in the features themselves. + FIXME: Need a better estimate the 10 I just made up */ + curr_lookahead = IMAX(curr_lookahead-10, 0); + + psum=0; + /* Summing the probability of transition patterns that involve music at + time (DETECT_SIZE-curr_lookahead-1) */ + for (i=0;ipmusic[i]; + for (;ipspeech[i]; + psum = psum*tonal->music_confidence + (1-psum)*tonal->speech_confidence; + /*printf("%f %f %f\n", psum, info_out->music_prob, info_out->tonality);*/ + + info_out->music_prob = psum; +} + +void tonality_analysis(TonalityAnalysisState *tonal, AnalysisInfo *info_out, const CELTMode *celt_mode, const void *x, int len, int offset, int c1, int c2, int C, int lsb_depth, downmix_func downmix) +{ + int i, b; + const kiss_fft_state *kfft; + VARDECL(kiss_fft_cpx, in); + VARDECL(kiss_fft_cpx, out); + int N = 480, N2=240; + float * OPUS_RESTRICT A = tonal->angle; + float * OPUS_RESTRICT dA = tonal->d_angle; + float * OPUS_RESTRICT d2A = tonal->d2_angle; + VARDECL(float, tonality); + VARDECL(float, noisiness); + float band_tonality[NB_TBANDS]; + float logE[NB_TBANDS]; + float BFCC[8]; + float features[25]; + float frame_tonality; + float max_frame_tonality; + /*float tw_sum=0;*/ + float frame_noisiness; + const float pi4 = (float)(M_PI*M_PI*M_PI*M_PI); + float slope=0; + float frame_stationarity; + float relativeE; + float frame_probs[2]; + float alpha, alphaE, alphaE2; + float frame_loudness; + float bandwidth_mask; + int bandwidth=0; + float maxE = 0; + float noise_floor; + int remaining; + AnalysisInfo *info; + SAVE_STACK; + + tonal->last_transition++; + alpha = 1.f/IMIN(20, 1+tonal->count); + alphaE = 1.f/IMIN(50, 1+tonal->count); + alphaE2 = 1.f/IMIN(1000, 1+tonal->count); + + if (tonal->count<4) + tonal->music_prob = .5; + kfft = celt_mode->mdct.kfft[0]; + if (tonal->count==0) + tonal->mem_fill = 240; + downmix(x, &tonal->inmem[tonal->mem_fill], IMIN(len, ANALYSIS_BUF_SIZE-tonal->mem_fill), offset, c1, c2, C); + if (tonal->mem_fill+len < ANALYSIS_BUF_SIZE) + { + tonal->mem_fill += len; + /* Don't have enough to update the analysis */ + RESTORE_STACK; + return; + } + info = &tonal->info[tonal->write_pos++]; + if (tonal->write_pos>=DETECT_SIZE) + tonal->write_pos-=DETECT_SIZE; + + ALLOC(in, 480, kiss_fft_cpx); + ALLOC(out, 480, kiss_fft_cpx); + ALLOC(tonality, 240, float); + ALLOC(noisiness, 240, float); + for (i=0;iinmem[i]); + in[i].i = (kiss_fft_scalar)(w*tonal->inmem[N2+i]); + in[N-i-1].r = (kiss_fft_scalar)(w*tonal->inmem[N-i-1]); + in[N-i-1].i = (kiss_fft_scalar)(w*tonal->inmem[N+N2-i-1]); + } + OPUS_MOVE(tonal->inmem, tonal->inmem+ANALYSIS_BUF_SIZE-240, 240); + remaining = len - (ANALYSIS_BUF_SIZE-tonal->mem_fill); + downmix(x, &tonal->inmem[240], remaining, offset+ANALYSIS_BUF_SIZE-tonal->mem_fill, c1, c2, C); + tonal->mem_fill = 240 + remaining; + opus_fft(kfft, in, out); + + for (i=1;iactivity = 0; + frame_noisiness = 0; + frame_stationarity = 0; + if (!tonal->count) + { + for (b=0;blowE[b] = 1e10; + tonal->highE[b] = -1e10; + } + } + relativeE = 0; + frame_loudness = 0; + for (b=0;bE[tonal->E_count][b] = E; + frame_noisiness += nE/(1e-15f+E); + + frame_loudness += (float)sqrt(E+1e-10f); + logE[b] = (float)log(E+1e-10f); + tonal->lowE[b] = MIN32(logE[b], tonal->lowE[b]+.01f); + tonal->highE[b] = MAX32(logE[b], tonal->highE[b]-.1f); + if (tonal->highE[b] < tonal->lowE[b]+1.f) + { + tonal->highE[b]+=.5f; + tonal->lowE[b]-=.5f; + } + relativeE += (logE[b]-tonal->lowE[b])/(1e-15f+tonal->highE[b]-tonal->lowE[b]); + + L1=L2=0; + for (i=0;iE[i][b]); + L2 += tonal->E[i][b]; + } + + stationarity = MIN16(0.99f,L1/(float)sqrt(1e-15+NB_FRAMES*L2)); + stationarity *= stationarity; + stationarity *= stationarity; + frame_stationarity += stationarity; + /*band_tonality[b] = tE/(1e-15+E)*/; + band_tonality[b] = MAX16(tE/(1e-15f+E), stationarity*tonal->prev_band_tonality[b]); +#if 0 + if (b>=NB_TONAL_SKIP_BANDS) + { + frame_tonality += tweight[b]*band_tonality[b]; + tw_sum += tweight[b]; + } +#else + frame_tonality += band_tonality[b]; + if (b>=NB_TBANDS-NB_TONAL_SKIP_BANDS) + frame_tonality -= band_tonality[b-NB_TBANDS+NB_TONAL_SKIP_BANDS]; +#endif + max_frame_tonality = MAX16(max_frame_tonality, (1.f+.03f*(b-NB_TBANDS))*frame_tonality); + slope += band_tonality[b]*(b-8); + /*printf("%f %f ", band_tonality[b], stationarity);*/ + tonal->prev_band_tonality[b] = band_tonality[b]; + } + + bandwidth_mask = 0; + bandwidth = 0; + maxE = 0; + noise_floor = 5.7e-4f/(1<<(IMAX(0,lsb_depth-8))); +#ifdef FIXED_POINT + noise_floor *= 1<<(15+SIG_SHIFT); +#endif + noise_floor *= noise_floor; + for (b=0;bmeanE[b] = MAX32((1-alphaE2)*tonal->meanE[b], E); + E = MAX32(E, tonal->meanE[b]); + /* Use a simple follower with 13 dB/Bark slope for spreading function */ + bandwidth_mask = MAX32(.05f*bandwidth_mask, E); + /* Consider the band "active" only if all these conditions are met: + 1) less than 10 dB below the simple follower + 2) less than 90 dB below the peak band (maximal masking possible considering + both the ATH and the loudness-dependent slope of the spreading function) + 3) above the PCM quantization noise floor + */ + if (E>.1*bandwidth_mask && E*1e9f > maxE && E > noise_floor*(band_end-band_start)) + bandwidth = b; + } + if (tonal->count<=2) + bandwidth = 20; + frame_loudness = 20*(float)log10(frame_loudness); + tonal->Etracker = MAX32(tonal->Etracker-.03f, frame_loudness); + tonal->lowECount *= (1-alphaE); + if (frame_loudness < tonal->Etracker-30) + tonal->lowECount += alphaE; + + for (i=0;i<8;i++) + { + float sum=0; + for (b=0;b<16;b++) + sum += dct_table[i*16+b]*logE[b]; + BFCC[i] = sum; + } + + frame_stationarity /= NB_TBANDS; + relativeE /= NB_TBANDS; + if (tonal->count<10) + relativeE = .5; + frame_noisiness /= NB_TBANDS; +#if 1 + info->activity = frame_noisiness + (1-frame_noisiness)*relativeE; +#else + info->activity = .5*(1+frame_noisiness-frame_stationarity); +#endif + frame_tonality = (max_frame_tonality/(NB_TBANDS-NB_TONAL_SKIP_BANDS)); + frame_tonality = MAX16(frame_tonality, tonal->prev_tonality*.8f); + tonal->prev_tonality = frame_tonality; + + slope /= 8*8; + info->tonality_slope = slope; + + tonal->E_count = (tonal->E_count+1)%NB_FRAMES; + tonal->count++; + info->tonality = frame_tonality; + + for (i=0;i<4;i++) + features[i] = -0.12299f*(BFCC[i]+tonal->mem[i+24]) + 0.49195f*(tonal->mem[i]+tonal->mem[i+16]) + 0.69693f*tonal->mem[i+8] - 1.4349f*tonal->cmean[i]; + + for (i=0;i<4;i++) + tonal->cmean[i] = (1-alpha)*tonal->cmean[i] + alpha*BFCC[i]; + + for (i=0;i<4;i++) + features[4+i] = 0.63246f*(BFCC[i]-tonal->mem[i+24]) + 0.31623f*(tonal->mem[i]-tonal->mem[i+16]); + for (i=0;i<3;i++) + features[8+i] = 0.53452f*(BFCC[i]+tonal->mem[i+24]) - 0.26726f*(tonal->mem[i]+tonal->mem[i+16]) -0.53452f*tonal->mem[i+8]; + + if (tonal->count > 5) + { + for (i=0;i<9;i++) + tonal->std[i] = (1-alpha)*tonal->std[i] + alpha*features[i]*features[i]; + } + + for (i=0;i<8;i++) + { + tonal->mem[i+24] = tonal->mem[i+16]; + tonal->mem[i+16] = tonal->mem[i+8]; + tonal->mem[i+8] = tonal->mem[i]; + tonal->mem[i] = BFCC[i]; + } + for (i=0;i<9;i++) + features[11+i] = (float)sqrt(tonal->std[i]); + features[20] = info->tonality; + features[21] = info->activity; + features[22] = frame_stationarity; + features[23] = info->tonality_slope; + features[24] = tonal->lowECount; + +#ifndef DISABLE_FLOAT_API + mlp_process(&net, features, frame_probs); + frame_probs[0] = .5f*(frame_probs[0]+1); + /* Curve fitting between the MLP probability and the actual probability */ + frame_probs[0] = .01f + 1.21f*frame_probs[0]*frame_probs[0] - .23f*(float)pow(frame_probs[0], 10); + /* Probability of active audio (as opposed to silence) */ + frame_probs[1] = .5f*frame_probs[1]+.5f; + /* Consider that silence has a 50-50 probability. */ + frame_probs[0] = frame_probs[1]*frame_probs[0] + (1-frame_probs[1])*.5f; + + /*printf("%f %f ", frame_probs[0], frame_probs[1]);*/ + { + /* Probability of state transition */ + float tau; + /* Represents independence of the MLP probabilities, where + beta=1 means fully independent. */ + float beta; + /* Denormalized probability of speech (p0) and music (p1) after update */ + float p0, p1; + /* Probabilities for "all speech" and "all music" */ + float s0, m0; + /* Probability sum for renormalisation */ + float psum; + /* Instantaneous probability of speech and music, with beta pre-applied. */ + float speech0; + float music0; + + /* One transition every 3 minutes of active audio */ + tau = .00005f*frame_probs[1]; + beta = .05f; + if (1) { + /* Adapt beta based on how "unexpected" the new prob is */ + float p, q; + p = MAX16(.05f,MIN16(.95f,frame_probs[0])); + q = MAX16(.05f,MIN16(.95f,tonal->music_prob)); + beta = .01f+.05f*ABS16(p-q)/(p*(1-q)+q*(1-p)); + } + /* p0 and p1 are the probabilities of speech and music at this frame + using only information from previous frame and applying the + state transition model */ + p0 = (1-tonal->music_prob)*(1-tau) + tonal->music_prob *tau; + p1 = tonal->music_prob *(1-tau) + (1-tonal->music_prob)*tau; + /* We apply the current probability with exponent beta to work around + the fact that the probability estimates aren't independent. */ + p0 *= (float)pow(1-frame_probs[0], beta); + p1 *= (float)pow(frame_probs[0], beta); + /* Normalise the probabilities to get the Marokv probability of music. */ + tonal->music_prob = p1/(p0+p1); + info->music_prob = tonal->music_prob; + + /* This chunk of code deals with delayed decision. */ + psum=1e-20f; + /* Instantaneous probability of speech and music, with beta pre-applied. */ + speech0 = (float)pow(1-frame_probs[0], beta); + music0 = (float)pow(frame_probs[0], beta); + if (tonal->count==1) + { + tonal->pspeech[0]=.5; + tonal->pmusic [0]=.5; + } + /* Updated probability of having only speech (s0) or only music (m0), + before considering the new observation. */ + s0 = tonal->pspeech[0] + tonal->pspeech[1]; + m0 = tonal->pmusic [0] + tonal->pmusic [1]; + /* Updates s0 and m0 with instantaneous probability. */ + tonal->pspeech[0] = s0*(1-tau)*speech0; + tonal->pmusic [0] = m0*(1-tau)*music0; + /* Propagate the transition probabilities */ + for (i=1;ipspeech[i] = tonal->pspeech[i+1]*speech0; + tonal->pmusic [i] = tonal->pmusic [i+1]*music0; + } + /* Probability that the latest frame is speech, when all the previous ones were music. */ + tonal->pspeech[DETECT_SIZE-1] = m0*tau*speech0; + /* Probability that the latest frame is music, when all the previous ones were speech. */ + tonal->pmusic [DETECT_SIZE-1] = s0*tau*music0; + + /* Renormalise probabilities to 1 */ + for (i=0;ipspeech[i] + tonal->pmusic[i]; + psum = 1.f/psum; + for (i=0;ipspeech[i] *= psum; + tonal->pmusic [i] *= psum; + } + psum = tonal->pmusic[0]; + for (i=1;ipspeech[i]; + + /* Estimate our confidence in the speech/music decisions */ + if (frame_probs[1]>.75) + { + if (tonal->music_prob>.9) + { + float adapt; + adapt = 1.f/(++tonal->music_confidence_count); + tonal->music_confidence_count = IMIN(tonal->music_confidence_count, 500); + tonal->music_confidence += adapt*MAX16(-.2f,frame_probs[0]-tonal->music_confidence); + } + if (tonal->music_prob<.1) + { + float adapt; + adapt = 1.f/(++tonal->speech_confidence_count); + tonal->speech_confidence_count = IMIN(tonal->speech_confidence_count, 500); + tonal->speech_confidence += adapt*MIN16(.2f,frame_probs[0]-tonal->speech_confidence); + } + } else { + if (tonal->music_confidence_count==0) + tonal->music_confidence = .9f; + if (tonal->speech_confidence_count==0) + tonal->speech_confidence = .1f; + } + } + if (tonal->last_music != (tonal->music_prob>.5f)) + tonal->last_transition=0; + tonal->last_music = tonal->music_prob>.5f; +#else + info->music_prob = 0; +#endif + /*for (i=0;i<25;i++) + printf("%f ", features[i]); + printf("\n");*/ + + info->bandwidth = bandwidth; + /*printf("%d %d\n", info->bandwidth, info->opus_bandwidth);*/ + info->noisiness = frame_noisiness; + info->valid = 1; + if (info_out!=NULL) + OPUS_COPY(info_out, info, 1); + RESTORE_STACK; +} + +void run_analysis(TonalityAnalysisState *analysis, const CELTMode *celt_mode, const void *analysis_pcm, + int analysis_frame_size, int frame_size, int c1, int c2, int C, opus_int32 Fs, + int lsb_depth, downmix_func downmix, AnalysisInfo *analysis_info) +{ + int offset; + int pcm_len; + + if (analysis_pcm != NULL) + { + /* Avoid overflow/wrap-around of the analysis buffer */ + analysis_frame_size = IMIN((DETECT_SIZE-5)*Fs/100, analysis_frame_size); + + pcm_len = analysis_frame_size - analysis->analysis_offset; + offset = analysis->analysis_offset; + do { + tonality_analysis(analysis, NULL, celt_mode, analysis_pcm, IMIN(480, pcm_len), offset, c1, c2, C, lsb_depth, downmix); + offset += 480; + pcm_len -= 480; + } while (pcm_len>0); + analysis->analysis_offset = analysis_frame_size; + + analysis->analysis_offset -= frame_size; + } + + analysis_info->valid = 0; + tonality_get_info(analysis, analysis_info, frame_size); +} diff --git a/src/opus-1.1/src/analysis.h b/src/opus-1.1/src/analysis.h new file mode 100644 index 00000000..be0388fa --- /dev/null +++ b/src/opus-1.1/src/analysis.h @@ -0,0 +1,90 @@ +/* Copyright (c) 2011 Xiph.Org Foundation + Written by Jean-Marc Valin */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef ANALYSIS_H +#define ANALYSIS_H + +#include "celt.h" +#include "opus_private.h" + +#define NB_FRAMES 8 +#define NB_TBANDS 18 +#define NB_TOT_BANDS 21 +#define ANALYSIS_BUF_SIZE 720 /* 15 ms at 48 kHz */ + +#define DETECT_SIZE 200 + +typedef struct { + float angle[240]; + float d_angle[240]; + float d2_angle[240]; + opus_val32 inmem[ANALYSIS_BUF_SIZE]; + int mem_fill; /* number of usable samples in the buffer */ + float prev_band_tonality[NB_TBANDS]; + float prev_tonality; + float E[NB_FRAMES][NB_TBANDS]; + float lowE[NB_TBANDS]; + float highE[NB_TBANDS]; + float meanE[NB_TOT_BANDS]; + float mem[32]; + float cmean[8]; + float std[9]; + float music_prob; + float Etracker; + float lowECount; + int E_count; + int last_music; + int last_transition; + int count; + float subframe_mem[3]; + int analysis_offset; + /** Probability of having speech for time i to DETECT_SIZE-1 (and music before). + pspeech[0] is the probability that all frames in the window are speech. */ + float pspeech[DETECT_SIZE]; + /** Probability of having music for time i to DETECT_SIZE-1 (and speech before). + pmusic[0] is the probability that all frames in the window are music. */ + float pmusic[DETECT_SIZE]; + float speech_confidence; + float music_confidence; + int speech_confidence_count; + int music_confidence_count; + int write_pos; + int read_pos; + int read_subframe; + AnalysisInfo info[DETECT_SIZE]; +} TonalityAnalysisState; + +void tonality_analysis(TonalityAnalysisState *tonal, AnalysisInfo *info, + const CELTMode *celt_mode, const void *x, int len, int offset, int c1, int c2, int C, int lsb_depth, downmix_func downmix); + +void tonality_get_info(TonalityAnalysisState *tonal, AnalysisInfo *info_out, int len); + +void run_analysis(TonalityAnalysisState *analysis, const CELTMode *celt_mode, const void *analysis_pcm, + int analysis_frame_size, int frame_size, int c1, int c2, int C, opus_int32 Fs, + int lsb_depth, downmix_func downmix, AnalysisInfo *analysis_info); + +#endif diff --git a/src/opus-1.1/src/mlp.c b/src/opus-1.1/src/mlp.c new file mode 100644 index 00000000..46386026 --- /dev/null +++ b/src/opus-1.1/src/mlp.c @@ -0,0 +1,140 @@ +/* Copyright (c) 2008-2011 Octasic Inc. + Written by Jean-Marc Valin */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "opus_types.h" +#include "opus_defines.h" + +#include +#include "mlp.h" +#include "arch.h" +#include "tansig_table.h" +#define MAX_NEURONS 100 + +#if 0 +static OPUS_INLINE opus_val16 tansig_approx(opus_val32 _x) /* Q19 */ +{ + int i; + opus_val16 xx; /* Q11 */ + /*double x, y;*/ + opus_val16 dy, yy; /* Q14 */ + /*x = 1.9073e-06*_x;*/ + if (_x>=QCONST32(8,19)) + return QCONST32(1.,14); + if (_x<=-QCONST32(8,19)) + return -QCONST32(1.,14); + xx = EXTRACT16(SHR32(_x, 8)); + /*i = lrint(25*x);*/ + i = SHR32(ADD32(1024,MULT16_16(25, xx)),11); + /*x -= .04*i;*/ + xx -= EXTRACT16(SHR32(MULT16_16(20972,i),8)); + /*x = xx*(1./2048);*/ + /*y = tansig_table[250+i];*/ + yy = tansig_table[250+i]; + /*y = yy*(1./16384);*/ + dy = 16384-MULT16_16_Q14(yy,yy); + yy = yy + MULT16_16_Q14(MULT16_16_Q11(xx,dy),(16384 - MULT16_16_Q11(yy,xx))); + return yy; +} +#else +/*extern const float tansig_table[501];*/ +static OPUS_INLINE float tansig_approx(float x) +{ + int i; + float y, dy; + float sign=1; + /* Tests are reversed to catch NaNs */ + if (!(x<8)) + return 1; + if (!(x>-8)) + return -1; + if (x<0) + { + x=-x; + sign=-1; + } + i = (int)floor(.5f+25*x); + x -= .04f*i; + y = tansig_table[i]; + dy = 1-y*y; + y = y + x*dy*(1 - y*x); + return sign*y; +} +#endif + +#if 0 +void mlp_process(const MLP *m, const opus_val16 *in, opus_val16 *out) +{ + int j; + opus_val16 hidden[MAX_NEURONS]; + const opus_val16 *W = m->weights; + /* Copy to tmp_in */ + for (j=0;jtopo[1];j++) + { + int k; + opus_val32 sum = SHL32(EXTEND32(*W++),8); + for (k=0;ktopo[0];k++) + sum = MAC16_16(sum, in[k],*W++); + hidden[j] = tansig_approx(sum); + } + for (j=0;jtopo[2];j++) + { + int k; + opus_val32 sum = SHL32(EXTEND32(*W++),14); + for (k=0;ktopo[1];k++) + sum = MAC16_16(sum, hidden[k], *W++); + out[j] = tansig_approx(EXTRACT16(PSHR32(sum,17))); + } +} +#else +void mlp_process(const MLP *m, const float *in, float *out) +{ + int j; + float hidden[MAX_NEURONS]; + const float *W = m->weights; + /* Copy to tmp_in */ + for (j=0;jtopo[1];j++) + { + int k; + float sum = *W++; + for (k=0;ktopo[0];k++) + sum = sum + in[k]**W++; + hidden[j] = tansig_approx(sum); + } + for (j=0;jtopo[2];j++) + { + int k; + float sum = *W++; + for (k=0;ktopo[1];k++) + sum = sum + hidden[k]**W++; + out[j] = tansig_approx(sum); + } +} +#endif diff --git a/src/opus-1.1/src/mlp.h b/src/opus-1.1/src/mlp.h new file mode 100644 index 00000000..86c8e061 --- /dev/null +++ b/src/opus-1.1/src/mlp.h @@ -0,0 +1,41 @@ +/* Copyright (c) 2008-2011 Octasic Inc. + Written by Jean-Marc Valin */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef _MLP_H_ +#define _MLP_H_ + +#include "arch.h" + +typedef struct { + int layers; + const int *topo; + const float *weights; +} MLP; + +void mlp_process(const MLP *m, const float *in, float *out); + +#endif /* _MLP_H_ */ diff --git a/src/opus-1.1/src/mlp_data.c b/src/opus-1.1/src/mlp_data.c new file mode 100644 index 00000000..401c4c02 --- /dev/null +++ b/src/opus-1.1/src/mlp_data.c @@ -0,0 +1,105 @@ +/* The contents of this file was automatically generated by mlp_train.c + It contains multi-layer perceptron (MLP) weights. */ + +#include "mlp.h" + +/* RMS error was 0.138320, seed was 1361535663 */ + +static const float weights[422] = { + +/* hidden layer */ +-0.0941125f, -0.302976f, -0.603555f, -0.19393f, -0.185983f, +-0.601617f, -0.0465317f, -0.114563f, -0.103599f, -0.618938f, +-0.317859f, -0.169949f, -0.0702885f, 0.148065f, 0.409524f, +0.548432f, 0.367649f, -0.494393f, 0.764306f, -1.83957f, +0.170849f, 12.786f, -1.08848f, -1.27284f, -16.2606f, +24.1773f, -5.57454f, -0.17276f, -0.163388f, -0.224421f, +-0.0948944f, -0.0728695f, -0.26557f, -0.100283f, -0.0515459f, +-0.146142f, -0.120674f, -0.180655f, 0.12857f, 0.442138f, +-0.493735f, 0.167767f, 0.206699f, -0.197567f, 0.417999f, +1.50364f, -0.773341f, -10.0401f, 0.401872f, 2.97966f, +15.2165f, -1.88905f, -1.19254f, 0.0285397f, -0.00405139f, +0.0707565f, 0.00825699f, -0.0927269f, -0.010393f, -0.00428882f, +-0.00489743f, -0.0709731f, -0.00255992f, 0.0395619f, 0.226424f, +0.0325231f, 0.162175f, -0.100118f, 0.485789f, 0.12697f, +0.285937f, 0.0155637f, 0.10546f, 3.05558f, 1.15059f, +-1.00904f, -1.83088f, 3.31766f, -3.42516f, -0.119135f, +-0.0405654f, 0.00690068f, 0.0179877f, -0.0382487f, 0.00597941f, +-0.0183611f, 0.00190395f, -0.144322f, -0.0435671f, 0.000990594f, +0.221087f, 0.142405f, 0.484066f, 0.404395f, 0.511955f, +-0.237255f, 0.241742f, 0.35045f, -0.699428f, 10.3993f, +2.6507f, -2.43459f, -4.18838f, 1.05928f, 1.71067f, +0.00667811f, -0.0721335f, -0.0397346f, 0.0362704f, -0.11496f, +-0.0235776f, 0.0082161f, -0.0141741f, -0.0329699f, -0.0354253f, +0.00277404f, -0.290654f, -1.14767f, -0.319157f, -0.686544f, +0.36897f, 0.478899f, 0.182579f, -0.411069f, 0.881104f, +-4.60683f, 1.4697f, 0.335845f, -1.81905f, -30.1699f, +5.55225f, 0.0019508f, -0.123576f, -0.0727332f, -0.0641597f, +-0.0534458f, -0.108166f, -0.0937368f, -0.0697883f, -0.0275475f, +-0.192309f, -0.110074f, 0.285375f, -0.405597f, 0.0926724f, +-0.287881f, -0.851193f, -0.099493f, -0.233764f, -1.2852f, +1.13611f, 3.12168f, -0.0699f, -1.86216f, 2.65292f, +-7.31036f, 2.44776f, -0.00111802f, -0.0632786f, -0.0376296f, +-0.149851f, 0.142963f, 0.184368f, 0.123433f, 0.0756158f, +0.117312f, 0.0933395f, 0.0692163f, 0.0842592f, 0.0704683f, +0.0589963f, 0.0942205f, -0.448862f, 0.0262677f, 0.270352f, +-0.262317f, 0.172586f, 2.00227f, -0.159216f, 0.038422f, +10.2073f, 4.15536f, -2.3407f, -0.0550265f, 0.00964792f, +-0.141336f, 0.0274501f, 0.0343921f, -0.0487428f, 0.0950172f, +-0.00775017f, -0.0372492f, -0.00548121f, -0.0663695f, 0.0960506f, +-0.200008f, -0.0412827f, 0.58728f, 0.0515787f, 0.337254f, +0.855024f, 0.668371f, -0.114904f, -3.62962f, -0.467477f, +-0.215472f, 2.61537f, 0.406117f, -1.36373f, 0.0425394f, +0.12208f, 0.0934502f, 0.123055f, 0.0340935f, -0.142466f, +0.035037f, -0.0490666f, 0.0733208f, 0.0576672f, 0.123984f, +-0.0517194f, -0.253018f, 0.590565f, 0.145849f, 0.315185f, +0.221534f, -0.149081f, 0.216161f, -0.349575f, 24.5664f, +-0.994196f, 0.614289f, -18.7905f, -2.83277f, -0.716801f, +-0.347201f, 0.479515f, -0.246027f, 0.0758683f, 0.137293f, +-0.17781f, 0.118751f, -0.00108329f, -0.237334f, 0.355732f, +-0.12991f, -0.0547627f, -0.318576f, -0.325524f, 0.180494f, +-0.0625604f, 0.141219f, 0.344064f, 0.37658f, -0.591772f, +5.8427f, -0.38075f, 0.221894f, -1.41934f, -1.87943e+06f, +1.34114f, 0.0283355f, -0.0447856f, -0.0211466f, -0.0256927f, +0.0139618f, 0.0207934f, -0.0107666f, 0.0110969f, 0.0586069f, +-0.0253545f, -0.0328433f, 0.11872f, -0.216943f, 0.145748f, +0.119808f, -0.0915211f, -0.120647f, -0.0787719f, -0.143644f, +-0.595116f, -1.152f, -1.25335f, -1.17092f, 4.34023f, +-975268.f, -1.37033f, -0.0401123f, 0.210602f, -0.136656f, +0.135962f, -0.0523293f, 0.0444604f, 0.0143928f, 0.00412666f, +-0.0193003f, 0.218452f, -0.110204f, -2.02563f, 0.918238f, +-2.45362f, 1.19542f, -0.061362f, -1.92243f, 0.308111f, +0.49764f, 0.912356f, 0.209272f, -2.34525f, 2.19326f, +-6.47121f, 1.69771f, -0.725123f, 0.0118929f, 0.0377944f, +0.0554003f, 0.0226452f, -0.0704421f, -0.0300309f, 0.0122978f, +-0.0041782f, -0.0686612f, 0.0313115f, 0.039111f, 0.364111f, +-0.0945548f, 0.0229876f, -0.17414f, 0.329795f, 0.114714f, +0.30022f, 0.106997f, 0.132355f, 5.79932f, 0.908058f, +-0.905324f, -3.3561f, 0.190647f, 0.184211f, -0.673648f, +0.231807f, -0.0586222f, 0.230752f, -0.438277f, 0.245857f, +-0.17215f, 0.0876383f, -0.720512f, 0.162515f, 0.0170571f, +0.101781f, 0.388477f, 1.32931f, 1.08548f, -0.936301f, +-2.36958f, -6.71988f, -3.44376f, 2.13818f, 14.2318f, +4.91459f, -3.09052f, -9.69191f, -0.768234f, 1.79604f, +0.0549653f, 0.163399f, 0.0797025f, 0.0343933f, -0.0555876f, +-0.00505673f, 0.0187258f, 0.0326628f, 0.0231486f, 0.15573f, +0.0476223f, -0.254824f, 1.60155f, -0.801221f, 2.55496f, +0.737629f, -1.36249f, -0.695463f, -2.44301f, -1.73188f, +3.95279f, 1.89068f, 0.486087f, -11.3343f, 3.9416e+06f, + +/* output layer */ +-0.381439f, 0.12115f, -0.906927f, 2.93878f, 1.6388f, +0.882811f, 0.874344f, 1.21726f, -0.874545f, 0.321706f, +0.785055f, 0.946558f, -0.575066f, -3.46553f, 0.884905f, +0.0924047f, -9.90712f, 0.391338f, 0.160103f, -2.04954f, +4.1455f, 0.0684029f, -0.144761f, -0.285282f, 0.379244f, +-1.1584f, -0.0277241f, -9.85f, -4.82386f, 3.71333f, +3.87308f, 3.52558f}; + +static const int topo[3] = {25, 15, 2}; + +const MLP net = { + 3, + topo, + weights +}; diff --git a/src/opus-1.1/src/opus.c b/src/opus-1.1/src/opus.c new file mode 100644 index 00000000..30890b9c --- /dev/null +++ b/src/opus-1.1/src/opus.c @@ -0,0 +1,329 @@ +/* Copyright (c) 2011 Xiph.Org Foundation, Skype Limited + Written by Jean-Marc Valin and Koen Vos */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "opus.h" +#include "opus_private.h" + +#ifndef DISABLE_FLOAT_API +OPUS_EXPORT void opus_pcm_soft_clip(float *_x, int N, int C, float *declip_mem) +{ + int c; + int i; + float *x; + + if (C<1 || N<1 || !_x || !declip_mem) return; + + /* First thing: saturate everything to +/- 2 which is the highest level our + non-linearity can handle. At the point where the signal reaches +/-2, + the derivative will be zero anyway, so this doesn't introduce any + discontinuity in the derivative. */ + for (i=0;i=0) + break; + x[i*C] = x[i*C]+a*x[i*C]*x[i*C]; + } + + curr=0; + x0 = x[0]; + while(1) + { + int start, end; + float maxval; + int special=0; + int peak_pos; + for (i=curr;i1 || x[i*C]<-1) + break; + } + if (i==N) + { + a=0; + break; + } + peak_pos = i; + start=end=i; + maxval=ABS16(x[i*C]); + /* Look for first zero crossing before clipping */ + while (start>0 && x[i*C]*x[(start-1)*C]>=0) + start--; + /* Look for first zero crossing after clipping */ + while (end=0) + { + /* Look for other peaks until the next zero-crossing. */ + if (ABS16(x[end*C])>maxval) + { + maxval = ABS16(x[end*C]); + peak_pos = end; + } + end++; + } + /* Detect the special case where we clip before the first zero crossing */ + special = (start==0 && x[i*C]*x[0]>=0); + + /* Compute a such that maxval + a*maxval^2 = 1 */ + a=(maxval-1)/(maxval*maxval); + if (x[i*C]>0) + a = -a; + /* Apply soft clipping */ + for (i=start;i=2) + { + /* Add a linear ramp from the first sample to the signal peak. + This avoids a discontinuity at the beginning of the frame. */ + float delta; + float offset = x0-x[0]; + delta = offset / peak_pos; + for (i=curr;i>2; + return 2; + } +} + +static int parse_size(const unsigned char *data, opus_int32 len, opus_int16 *size) +{ + if (len<1) + { + *size = -1; + return -1; + } else if (data[0]<252) + { + *size = data[0]; + return 1; + } else if (len<2) + { + *size = -1; + return -1; + } else { + *size = 4*data[1] + data[0]; + return 2; + } +} + +int opus_packet_parse_impl(const unsigned char *data, opus_int32 len, + int self_delimited, unsigned char *out_toc, + const unsigned char *frames[48], opus_int16 size[48], + int *payload_offset, opus_int32 *packet_offset) +{ + int i, bytes; + int count; + int cbr; + unsigned char ch, toc; + int framesize; + opus_int32 last_size; + opus_int32 pad = 0; + const unsigned char *data0 = data; + + if (size==NULL) + return OPUS_BAD_ARG; + + framesize = opus_packet_get_samples_per_frame(data, 48000); + + cbr = 0; + toc = *data++; + len--; + last_size = len; + switch (toc&0x3) + { + /* One frame */ + case 0: + count=1; + break; + /* Two CBR frames */ + case 1: + count=2; + cbr = 1; + if (!self_delimited) + { + if (len&0x1) + return OPUS_INVALID_PACKET; + last_size = len/2; + /* If last_size doesn't fit in size[0], we'll catch it later */ + size[0] = (opus_int16)last_size; + } + break; + /* Two VBR frames */ + case 2: + count = 2; + bytes = parse_size(data, len, size); + len -= bytes; + if (size[0]<0 || size[0] > len) + return OPUS_INVALID_PACKET; + data += bytes; + last_size = len-size[0]; + break; + /* Multiple CBR/VBR frames (from 0 to 120 ms) */ + default: /*case 3:*/ + if (len<1) + return OPUS_INVALID_PACKET; + /* Number of frames encoded in bits 0 to 5 */ + ch = *data++; + count = ch&0x3F; + if (count <= 0 || framesize*count > 5760) + return OPUS_INVALID_PACKET; + len--; + /* Padding flag is bit 6 */ + if (ch&0x40) + { + int p; + do { + int tmp; + if (len<=0) + return OPUS_INVALID_PACKET; + p = *data++; + len--; + tmp = p==255 ? 254: p; + len -= tmp; + pad += tmp; + } while (p==255); + } + if (len<0) + return OPUS_INVALID_PACKET; + /* VBR flag is bit 7 */ + cbr = !(ch&0x80); + if (!cbr) + { + /* VBR case */ + last_size = len; + for (i=0;i len) + return OPUS_INVALID_PACKET; + data += bytes; + last_size -= bytes+size[i]; + } + if (last_size<0) + return OPUS_INVALID_PACKET; + } else if (!self_delimited) + { + /* CBR case */ + last_size = len/count; + if (last_size*count!=len) + return OPUS_INVALID_PACKET; + for (i=0;i len) + return OPUS_INVALID_PACKET; + data += bytes; + /* For CBR packets, apply the size to all the frames. */ + if (cbr) + { + if (size[count-1]*count > len) + return OPUS_INVALID_PACKET; + for (i=0;i last_size) + return OPUS_INVALID_PACKET; + } else + { + /* Because it's not encoded explicitly, it's possible the size of the + last packet (or all the packets, for the CBR case) is larger than + 1275. Reject them here.*/ + if (last_size > 1275) + return OPUS_INVALID_PACKET; + size[count-1] = (opus_int16)last_size; + } + + if (payload_offset) + *payload_offset = (int)(data-data0); + + for (i=0;i= 2) && !defined(__OPTIMIZE__) +# pragma message "You appear to be compiling without optimization, if so opus will be very slow." +#endif + +#include +#include "celt.h" +#include "opus.h" +#include "entdec.h" +#include "modes.h" +#include "API.h" +#include "stack_alloc.h" +#include "float_cast.h" +#include "opus_private.h" +#include "os_support.h" +#include "structs.h" +#include "define.h" +#include "mathops.h" +#include "cpu_support.h" + +struct OpusDecoder { + int celt_dec_offset; + int silk_dec_offset; + int channels; + opus_int32 Fs; /** Sampling rate (at the API level) */ + silk_DecControlStruct DecControl; + int decode_gain; + + /* Everything beyond this point gets cleared on a reset */ +#define OPUS_DECODER_RESET_START stream_channels + int stream_channels; + + int bandwidth; + int mode; + int prev_mode; + int frame_size; + int prev_redundancy; + int last_packet_duration; +#ifndef FIXED_POINT + opus_val16 softclip_mem[2]; +#endif + + opus_uint32 rangeFinal; +}; + +#ifdef FIXED_POINT +static OPUS_INLINE opus_int16 SAT16(opus_int32 x) { + return x > 32767 ? 32767 : x < -32768 ? -32768 : (opus_int16)x; +} +#endif + + +int opus_decoder_get_size(int channels) +{ + int silkDecSizeBytes, celtDecSizeBytes; + int ret; + if (channels<1 || channels > 2) + return 0; + ret = silk_Get_Decoder_Size( &silkDecSizeBytes ); + if(ret) + return 0; + silkDecSizeBytes = align(silkDecSizeBytes); + celtDecSizeBytes = celt_decoder_get_size(channels); + return align(sizeof(OpusDecoder))+silkDecSizeBytes+celtDecSizeBytes; +} + +int opus_decoder_init(OpusDecoder *st, opus_int32 Fs, int channels) +{ + void *silk_dec; + CELTDecoder *celt_dec; + int ret, silkDecSizeBytes; + + if ((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000) + || (channels!=1&&channels!=2)) + return OPUS_BAD_ARG; + + OPUS_CLEAR((char*)st, opus_decoder_get_size(channels)); + /* Initialize SILK encoder */ + ret = silk_Get_Decoder_Size(&silkDecSizeBytes); + if (ret) + return OPUS_INTERNAL_ERROR; + + silkDecSizeBytes = align(silkDecSizeBytes); + st->silk_dec_offset = align(sizeof(OpusDecoder)); + st->celt_dec_offset = st->silk_dec_offset+silkDecSizeBytes; + silk_dec = (char*)st+st->silk_dec_offset; + celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset); + st->stream_channels = st->channels = channels; + + st->Fs = Fs; + st->DecControl.API_sampleRate = st->Fs; + st->DecControl.nChannelsAPI = st->channels; + + /* Reset decoder */ + ret = silk_InitDecoder( silk_dec ); + if(ret)return OPUS_INTERNAL_ERROR; + + /* Initialize CELT decoder */ + ret = celt_decoder_init(celt_dec, Fs, channels); + if(ret!=OPUS_OK)return OPUS_INTERNAL_ERROR; + + celt_decoder_ctl(celt_dec, CELT_SET_SIGNALLING(0)); + + st->prev_mode = 0; + st->frame_size = Fs/400; + return OPUS_OK; +} + +OpusDecoder *opus_decoder_create(opus_int32 Fs, int channels, int *error) +{ + int ret; + OpusDecoder *st; + if ((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000) + || (channels!=1&&channels!=2)) + { + if (error) + *error = OPUS_BAD_ARG; + return NULL; + } + st = (OpusDecoder *)opus_alloc(opus_decoder_get_size(channels)); + if (st == NULL) + { + if (error) + *error = OPUS_ALLOC_FAIL; + return NULL; + } + ret = opus_decoder_init(st, Fs, channels); + if (error) + *error = ret; + if (ret != OPUS_OK) + { + opus_free(st); + st = NULL; + } + return st; +} + +static void smooth_fade(const opus_val16 *in1, const opus_val16 *in2, + opus_val16 *out, int overlap, int channels, + const opus_val16 *window, opus_int32 Fs) +{ + int i, c; + int inc = 48000/Fs; + for (c=0;csilk_dec_offset; + celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset); + F20 = st->Fs/50; + F10 = F20>>1; + F5 = F10>>1; + F2_5 = F5>>1; + if (frame_size < F2_5) + { + RESTORE_STACK; + return OPUS_BUFFER_TOO_SMALL; + } + /* Limit frame_size to avoid excessive stack allocations. */ + frame_size = IMIN(frame_size, st->Fs/25*3); + /* Payloads of 1 (2 including ToC) or 0 trigger the PLC/DTX */ + if (len<=1) + { + data = NULL; + /* In that case, don't conceal more than what the ToC says */ + frame_size = IMIN(frame_size, st->frame_size); + } + if (data != NULL) + { + audiosize = st->frame_size; + mode = st->mode; + ec_dec_init(&dec,(unsigned char*)data,len); + } else { + audiosize = frame_size; + mode = st->prev_mode; + + if (mode == 0) + { + /* If we haven't got any packet yet, all we can do is return zeros */ + for (i=0;ichannels;i++) + pcm[i] = 0; + RESTORE_STACK; + return audiosize; + } + + /* Avoids trying to run the PLC on sizes other than 2.5 (CELT), 5 (CELT), + 10, or 20 (e.g. 12.5 or 30 ms). */ + if (audiosize > F20) + { + do { + int ret = opus_decode_frame(st, NULL, 0, pcm, IMIN(audiosize, F20), 0); + if (ret<0) + { + RESTORE_STACK; + return ret; + } + pcm += ret*st->channels; + audiosize -= ret; + } while (audiosize > 0); + RESTORE_STACK; + return frame_size; + } else if (audiosize < F20) + { + if (audiosize > F10) + audiosize = F10; + else if (mode != MODE_SILK_ONLY && audiosize > F5 && audiosize < F10) + audiosize = F5; + } + } + + pcm_transition_silk_size = ALLOC_NONE; + pcm_transition_celt_size = ALLOC_NONE; + if (data!=NULL && st->prev_mode > 0 && ( + (mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY && !st->prev_redundancy) + || (mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) ) + ) + { + transition = 1; + /* Decide where to allocate the stack memory for pcm_transition */ + if (mode == MODE_CELT_ONLY) + pcm_transition_celt_size = F5*st->channels; + else + pcm_transition_silk_size = F5*st->channels; + } + ALLOC(pcm_transition_celt, pcm_transition_celt_size, opus_val16); + if (transition && mode == MODE_CELT_ONLY) + { + pcm_transition = pcm_transition_celt; + opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0); + } + if (audiosize > frame_size) + { + /*fprintf(stderr, "PCM buffer too small: %d vs %d (mode = %d)\n", audiosize, frame_size, mode);*/ + RESTORE_STACK; + return OPUS_BAD_ARG; + } else { + frame_size = audiosize; + } + + /* Don't allocate any memory when in CELT-only mode */ + pcm_silk_size = (mode != MODE_CELT_ONLY) ? IMAX(F10, frame_size)*st->channels : ALLOC_NONE; + ALLOC(pcm_silk, pcm_silk_size, opus_int16); + + /* SILK processing */ + if (mode != MODE_CELT_ONLY) + { + int lost_flag, decoded_samples; + opus_int16 *pcm_ptr = pcm_silk; + + if (st->prev_mode==MODE_CELT_ONLY) + silk_InitDecoder( silk_dec ); + + /* The SILK PLC cannot produce frames of less than 10 ms */ + st->DecControl.payloadSize_ms = IMAX(10, 1000 * audiosize / st->Fs); + + if (data != NULL) + { + st->DecControl.nChannelsInternal = st->stream_channels; + if( mode == MODE_SILK_ONLY ) { + if( st->bandwidth == OPUS_BANDWIDTH_NARROWBAND ) { + st->DecControl.internalSampleRate = 8000; + } else if( st->bandwidth == OPUS_BANDWIDTH_MEDIUMBAND ) { + st->DecControl.internalSampleRate = 12000; + } else if( st->bandwidth == OPUS_BANDWIDTH_WIDEBAND ) { + st->DecControl.internalSampleRate = 16000; + } else { + st->DecControl.internalSampleRate = 16000; + silk_assert( 0 ); + } + } else { + /* Hybrid mode */ + st->DecControl.internalSampleRate = 16000; + } + } + + lost_flag = data == NULL ? 1 : 2 * decode_fec; + decoded_samples = 0; + do { + /* Call SILK decoder */ + int first_frame = decoded_samples == 0; + silk_ret = silk_Decode( silk_dec, &st->DecControl, + lost_flag, first_frame, &dec, pcm_ptr, &silk_frame_size ); + if( silk_ret ) { + if (lost_flag) { + /* PLC failure should not be fatal */ + silk_frame_size = frame_size; + for (i=0;ichannels;i++) + pcm_ptr[i] = 0; + } else { + RESTORE_STACK; + return OPUS_INTERNAL_ERROR; + } + } + pcm_ptr += silk_frame_size * st->channels; + decoded_samples += silk_frame_size; + } while( decoded_samples < frame_size ); + } + + start_band = 0; + if (!decode_fec && mode != MODE_CELT_ONLY && data != NULL + && ec_tell(&dec)+17+20*(st->mode == MODE_HYBRID) <= 8*len) + { + /* Check if we have a redundant 0-8 kHz band */ + if (mode == MODE_HYBRID) + redundancy = ec_dec_bit_logp(&dec, 12); + else + redundancy = 1; + if (redundancy) + { + celt_to_silk = ec_dec_bit_logp(&dec, 1); + /* redundancy_bytes will be at least two, in the non-hybrid + case due to the ec_tell() check above */ + redundancy_bytes = mode==MODE_HYBRID ? + (opus_int32)ec_dec_uint(&dec, 256)+2 : + len-((ec_tell(&dec)+7)>>3); + len -= redundancy_bytes; + /* This is a sanity check. It should never happen for a valid + packet, so the exact behaviour is not normative. */ + if (len*8 < ec_tell(&dec)) + { + len = 0; + redundancy_bytes = 0; + redundancy = 0; + } + /* Shrink decoder because of raw bits */ + dec.storage -= redundancy_bytes; + } + } + if (mode != MODE_CELT_ONLY) + start_band = 17; + + { + int endband=21; + + switch(st->bandwidth) + { + case OPUS_BANDWIDTH_NARROWBAND: + endband = 13; + break; + case OPUS_BANDWIDTH_MEDIUMBAND: + case OPUS_BANDWIDTH_WIDEBAND: + endband = 17; + break; + case OPUS_BANDWIDTH_SUPERWIDEBAND: + endband = 19; + break; + case OPUS_BANDWIDTH_FULLBAND: + endband = 21; + break; + } + celt_decoder_ctl(celt_dec, CELT_SET_END_BAND(endband)); + celt_decoder_ctl(celt_dec, CELT_SET_CHANNELS(st->stream_channels)); + } + + if (redundancy) + { + transition = 0; + pcm_transition_silk_size=ALLOC_NONE; + } + + ALLOC(pcm_transition_silk, pcm_transition_silk_size, opus_val16); + + if (transition && mode != MODE_CELT_ONLY) + { + pcm_transition = pcm_transition_silk; + opus_decode_frame(st, NULL, 0, pcm_transition, IMIN(F5, audiosize), 0); + } + + /* Only allocation memory for redundancy if/when needed */ + redundant_audio_size = redundancy ? F5*st->channels : ALLOC_NONE; + ALLOC(redundant_audio, redundant_audio_size, opus_val16); + + /* 5 ms redundant frame for CELT->SILK*/ + if (redundancy && celt_to_silk) + { + celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)); + celt_decode_with_ec(celt_dec, data+len, redundancy_bytes, + redundant_audio, F5, NULL); + celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng)); + } + + /* MUST be after PLC */ + celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(start_band)); + + if (mode != MODE_SILK_ONLY) + { + int celt_frame_size = IMIN(F20, frame_size); + /* Make sure to discard any previous CELT state */ + if (mode != st->prev_mode && st->prev_mode > 0 && !st->prev_redundancy) + celt_decoder_ctl(celt_dec, OPUS_RESET_STATE); + /* Decode CELT */ + celt_ret = celt_decode_with_ec(celt_dec, decode_fec ? NULL : data, + len, pcm, celt_frame_size, &dec); + } else { + unsigned char silence[2] = {0xFF, 0xFF}; + for (i=0;ichannels;i++) + pcm[i] = 0; + /* For hybrid -> SILK transitions, we let the CELT MDCT + do a fade-out by decoding a silence frame */ + if (st->prev_mode == MODE_HYBRID && !(redundancy && celt_to_silk && st->prev_redundancy) ) + { + celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)); + celt_decode_with_ec(celt_dec, silence, 2, pcm, F2_5, NULL); + } + } + + if (mode != MODE_CELT_ONLY) + { +#ifdef FIXED_POINT + for (i=0;ichannels;i++) + pcm[i] = SAT16(pcm[i] + pcm_silk[i]); +#else + for (i=0;ichannels;i++) + pcm[i] = pcm[i] + (opus_val16)((1.f/32768.f)*pcm_silk[i]); +#endif + } + + { + const CELTMode *celt_mode; + celt_decoder_ctl(celt_dec, CELT_GET_MODE(&celt_mode)); + window = celt_mode->window; + } + + /* 5 ms redundant frame for SILK->CELT */ + if (redundancy && !celt_to_silk) + { + celt_decoder_ctl(celt_dec, OPUS_RESET_STATE); + celt_decoder_ctl(celt_dec, CELT_SET_START_BAND(0)); + + celt_decode_with_ec(celt_dec, data+len, redundancy_bytes, redundant_audio, F5, NULL); + celt_decoder_ctl(celt_dec, OPUS_GET_FINAL_RANGE(&redundant_rng)); + smooth_fade(pcm+st->channels*(frame_size-F2_5), redundant_audio+st->channels*F2_5, + pcm+st->channels*(frame_size-F2_5), F2_5, st->channels, window, st->Fs); + } + if (redundancy && celt_to_silk) + { + for (c=0;cchannels;c++) + { + for (i=0;ichannels*i+c] = redundant_audio[st->channels*i+c]; + } + smooth_fade(redundant_audio+st->channels*F2_5, pcm+st->channels*F2_5, + pcm+st->channels*F2_5, F2_5, st->channels, window, st->Fs); + } + if (transition) + { + if (audiosize >= F5) + { + for (i=0;ichannels*F2_5;i++) + pcm[i] = pcm_transition[i]; + smooth_fade(pcm_transition+st->channels*F2_5, pcm+st->channels*F2_5, + pcm+st->channels*F2_5, F2_5, + st->channels, window, st->Fs); + } else { + /* Not enough time to do a clean transition, but we do it anyway + This will not preserve amplitude perfectly and may introduce + a bit of temporal aliasing, but it shouldn't be too bad and + that's pretty much the best we can do. In any case, generating this + transition it pretty silly in the first place */ + smooth_fade(pcm_transition, pcm, + pcm, F2_5, + st->channels, window, st->Fs); + } + } + + if(st->decode_gain) + { + opus_val32 gain; + gain = celt_exp2(MULT16_16_P15(QCONST16(6.48814081e-4f, 25), st->decode_gain)); + for (i=0;ichannels;i++) + { + opus_val32 x; + x = MULT16_32_P16(pcm[i],gain); + pcm[i] = SATURATE(x, 32767); + } + } + + if (len <= 1) + st->rangeFinal = 0; + else + st->rangeFinal = dec.rng ^ redundant_rng; + + st->prev_mode = mode; + st->prev_redundancy = redundancy && !celt_to_silk; + + if (celt_ret>=0) + { + if (OPUS_CHECK_ARRAY(pcm, audiosize*st->channels)) + OPUS_PRINT_INT(audiosize); + } + + RESTORE_STACK; + return celt_ret < 0 ? celt_ret : audiosize; + +} + +int opus_decode_native(OpusDecoder *st, const unsigned char *data, + opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec, + int self_delimited, opus_int32 *packet_offset, int soft_clip) +{ + int i, nb_samples; + int count, offset; + unsigned char toc; + int packet_frame_size, packet_bandwidth, packet_mode, packet_stream_channels; + /* 48 x 2.5 ms = 120 ms */ + opus_int16 size[48]; + if (decode_fec<0 || decode_fec>1) + return OPUS_BAD_ARG; + /* For FEC/PLC, frame_size has to be to have a multiple of 2.5 ms */ + if ((decode_fec || len==0 || data==NULL) && frame_size%(st->Fs/400)!=0) + return OPUS_BAD_ARG; + if (len==0 || data==NULL) + { + int pcm_count=0; + do { + int ret; + ret = opus_decode_frame(st, NULL, 0, pcm+pcm_count*st->channels, frame_size-pcm_count, 0); + if (ret<0) + return ret; + pcm_count += ret; + } while (pcm_count < frame_size); + celt_assert(pcm_count == frame_size); + if (OPUS_CHECK_ARRAY(pcm, pcm_count*st->channels)) + OPUS_PRINT_INT(pcm_count); + st->last_packet_duration = pcm_count; + return pcm_count; + } else if (len<0) + return OPUS_BAD_ARG; + + packet_mode = opus_packet_get_mode(data); + packet_bandwidth = opus_packet_get_bandwidth(data); + packet_frame_size = opus_packet_get_samples_per_frame(data, st->Fs); + packet_stream_channels = opus_packet_get_nb_channels(data); + + count = opus_packet_parse_impl(data, len, self_delimited, &toc, NULL, + size, &offset, packet_offset); + if (count<0) + return count; + + data += offset; + + if (decode_fec) + { + int duration_copy; + int ret; + /* If no FEC can be present, run the PLC (recursive call) */ + if (frame_size < packet_frame_size || packet_mode == MODE_CELT_ONLY || st->mode == MODE_CELT_ONLY) + return opus_decode_native(st, NULL, 0, pcm, frame_size, 0, 0, NULL, soft_clip); + /* Otherwise, run the PLC on everything except the size for which we might have FEC */ + duration_copy = st->last_packet_duration; + if (frame_size-packet_frame_size!=0) + { + ret = opus_decode_native(st, NULL, 0, pcm, frame_size-packet_frame_size, 0, 0, NULL, soft_clip); + if (ret<0) + { + st->last_packet_duration = duration_copy; + return ret; + } + celt_assert(ret==frame_size-packet_frame_size); + } + /* Complete with FEC */ + st->mode = packet_mode; + st->bandwidth = packet_bandwidth; + st->frame_size = packet_frame_size; + st->stream_channels = packet_stream_channels; + ret = opus_decode_frame(st, data, size[0], pcm+st->channels*(frame_size-packet_frame_size), + packet_frame_size, 1); + if (ret<0) + return ret; + else { + if (OPUS_CHECK_ARRAY(pcm, frame_size*st->channels)) + OPUS_PRINT_INT(frame_size); + st->last_packet_duration = frame_size; + return frame_size; + } + } + + if (count*packet_frame_size > frame_size) + return OPUS_BUFFER_TOO_SMALL; + + /* Update the state as the last step to avoid updating it on an invalid packet */ + st->mode = packet_mode; + st->bandwidth = packet_bandwidth; + st->frame_size = packet_frame_size; + st->stream_channels = packet_stream_channels; + + nb_samples=0; + for (i=0;ichannels, frame_size-nb_samples, 0); + if (ret<0) + return ret; + celt_assert(ret==packet_frame_size); + data += size[i]; + nb_samples += ret; + } + st->last_packet_duration = nb_samples; + if (OPUS_CHECK_ARRAY(pcm, nb_samples*st->channels)) + OPUS_PRINT_INT(nb_samples); +#ifndef FIXED_POINT + if (soft_clip) + opus_pcm_soft_clip(pcm, nb_samples, st->channels, st->softclip_mem); + else + st->softclip_mem[0]=st->softclip_mem[1]=0; +#endif + return nb_samples; +} + +#ifdef FIXED_POINT + +int opus_decode(OpusDecoder *st, const unsigned char *data, + opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec) +{ + if(frame_size<=0) + return OPUS_BAD_ARG; + return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL, 0); +} + +#ifndef DISABLE_FLOAT_API +int opus_decode_float(OpusDecoder *st, const unsigned char *data, + opus_int32 len, float *pcm, int frame_size, int decode_fec) +{ + VARDECL(opus_int16, out); + int ret, i; + ALLOC_STACK; + + if(frame_size<=0) + { + RESTORE_STACK; + return OPUS_BAD_ARG; + } + ALLOC(out, frame_size*st->channels, opus_int16); + + ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 0); + if (ret > 0) + { + for (i=0;ichannels;i++) + pcm[i] = (1.f/32768.f)*(out[i]); + } + RESTORE_STACK; + return ret; +} +#endif + + +#else +int opus_decode(OpusDecoder *st, const unsigned char *data, + opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec) +{ + VARDECL(float, out); + int ret, i; + ALLOC_STACK; + + if(frame_size<=0) + { + RESTORE_STACK; + return OPUS_BAD_ARG; + } + + ALLOC(out, frame_size*st->channels, float); + + ret = opus_decode_native(st, data, len, out, frame_size, decode_fec, 0, NULL, 1); + if (ret > 0) + { + for (i=0;ichannels;i++) + pcm[i] = FLOAT2INT16(out[i]); + } + RESTORE_STACK; + return ret; +} + +int opus_decode_float(OpusDecoder *st, const unsigned char *data, + opus_int32 len, opus_val16 *pcm, int frame_size, int decode_fec) +{ + if(frame_size<=0) + return OPUS_BAD_ARG; + return opus_decode_native(st, data, len, pcm, frame_size, decode_fec, 0, NULL, 0); +} + +#endif + +int opus_decoder_ctl(OpusDecoder *st, int request, ...) +{ + int ret = OPUS_OK; + va_list ap; + void *silk_dec; + CELTDecoder *celt_dec; + + silk_dec = (char*)st+st->silk_dec_offset; + celt_dec = (CELTDecoder*)((char*)st+st->celt_dec_offset); + + + va_start(ap, request); + + switch (request) + { + case OPUS_GET_BANDWIDTH_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } + *value = st->bandwidth; + } + break; + case OPUS_GET_FINAL_RANGE_REQUEST: + { + opus_uint32 *value = va_arg(ap, opus_uint32*); + if (!value) + { + goto bad_arg; + } + *value = st->rangeFinal; + } + break; + case OPUS_RESET_STATE: + { + OPUS_CLEAR((char*)&st->OPUS_DECODER_RESET_START, + sizeof(OpusDecoder)- + ((char*)&st->OPUS_DECODER_RESET_START - (char*)st)); + + celt_decoder_ctl(celt_dec, OPUS_RESET_STATE); + silk_InitDecoder( silk_dec ); + st->stream_channels = st->channels; + st->frame_size = st->Fs/400; + } + break; + case OPUS_GET_SAMPLE_RATE_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } + *value = st->Fs; + } + break; + case OPUS_GET_PITCH_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } + if (st->prev_mode == MODE_CELT_ONLY) + celt_decoder_ctl(celt_dec, OPUS_GET_PITCH(value)); + else + *value = st->DecControl.prevPitchLag; + } + break; + case OPUS_GET_GAIN_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } + *value = st->decode_gain; + } + break; + case OPUS_SET_GAIN_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if (value<-32768 || value>32767) + { + goto bad_arg; + } + st->decode_gain = value; + } + break; + case OPUS_GET_LAST_PACKET_DURATION_REQUEST: + { + opus_uint32 *value = va_arg(ap, opus_uint32*); + if (!value) + { + goto bad_arg; + } + *value = st->last_packet_duration; + } + break; + default: + /*fprintf(stderr, "unknown opus_decoder_ctl() request: %d", request);*/ + ret = OPUS_UNIMPLEMENTED; + break; + } + + va_end(ap); + return ret; +bad_arg: + va_end(ap); + return OPUS_BAD_ARG; +} + +void opus_decoder_destroy(OpusDecoder *st) +{ + opus_free(st); +} + + +int opus_packet_get_bandwidth(const unsigned char *data) +{ + int bandwidth; + if (data[0]&0x80) + { + bandwidth = OPUS_BANDWIDTH_MEDIUMBAND + ((data[0]>>5)&0x3); + if (bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) + bandwidth = OPUS_BANDWIDTH_NARROWBAND; + } else if ((data[0]&0x60) == 0x60) + { + bandwidth = (data[0]&0x10) ? OPUS_BANDWIDTH_FULLBAND : + OPUS_BANDWIDTH_SUPERWIDEBAND; + } else { + bandwidth = OPUS_BANDWIDTH_NARROWBAND + ((data[0]>>5)&0x3); + } + return bandwidth; +} + +int opus_packet_get_samples_per_frame(const unsigned char *data, + opus_int32 Fs) +{ + int audiosize; + if (data[0]&0x80) + { + audiosize = ((data[0]>>3)&0x3); + audiosize = (Fs<>3)&0x3); + if (audiosize == 3) + audiosize = Fs*60/1000; + else + audiosize = (Fs< Fs*3) + return OPUS_INVALID_PACKET; + else + return samples; +} + +int opus_decoder_get_nb_samples(const OpusDecoder *dec, + const unsigned char packet[], opus_int32 len) +{ + return opus_packet_get_nb_samples(packet, len, dec->Fs); +} diff --git a/src/opus-1.1/src/opus_encoder.c b/src/opus-1.1/src/opus_encoder.c new file mode 100644 index 00000000..fbd3de63 --- /dev/null +++ b/src/opus-1.1/src/opus_encoder.c @@ -0,0 +1,2488 @@ +/* Copyright (c) 2010-2011 Xiph.Org Foundation, Skype Limited + Written by Jean-Marc Valin and Koen Vos */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "celt.h" +#include "entenc.h" +#include "modes.h" +#include "API.h" +#include "stack_alloc.h" +#include "float_cast.h" +#include "opus.h" +#include "arch.h" +#include "opus_private.h" +#include "os_support.h" +#include "cpu_support.h" +#include "analysis.h" +#include "mathops.h" +#include "tuning_parameters.h" +#ifdef FIXED_POINT +#include "fixed/structs_FIX.h" +#else +#include "float/structs_FLP.h" +#endif + +#define MAX_ENCODER_BUFFER 480 + +typedef struct { + opus_val32 XX, XY, YY; + opus_val16 smoothed_width; + opus_val16 max_follower; +} StereoWidthState; + +struct OpusEncoder { + int celt_enc_offset; + int silk_enc_offset; + silk_EncControlStruct silk_mode; + int application; + int channels; + int delay_compensation; + int force_channels; + int signal_type; + int user_bandwidth; + int max_bandwidth; + int user_forced_mode; + int voice_ratio; + opus_int32 Fs; + int use_vbr; + int vbr_constraint; + int variable_duration; + opus_int32 bitrate_bps; + opus_int32 user_bitrate_bps; + int lsb_depth; + int encoder_buffer; + int lfe; + +#define OPUS_ENCODER_RESET_START stream_channels + int stream_channels; + opus_int16 hybrid_stereo_width_Q14; + opus_int32 variable_HP_smth2_Q15; + opus_val16 prev_HB_gain; + opus_val32 hp_mem[4]; + int mode; + int prev_mode; + int prev_channels; + int prev_framesize; + int bandwidth; + int silk_bw_switch; + /* Sampling rate (at the API level) */ + int first; + opus_val16 * energy_masking; + StereoWidthState width_mem; + opus_val16 delay_buffer[MAX_ENCODER_BUFFER*2]; +#ifndef DISABLE_FLOAT_API + TonalityAnalysisState analysis; + int detected_bandwidth; + int analysis_offset; +#endif + opus_uint32 rangeFinal; + int arch; +}; + +/* Transition tables for the voice and music. First column is the + middle (memoriless) threshold. The second column is the hysteresis + (difference with the middle) */ +static const opus_int32 mono_voice_bandwidth_thresholds[8] = { + 11000, 1000, /* NB<->MB */ + 14000, 1000, /* MB<->WB */ + 17000, 1000, /* WB<->SWB */ + 21000, 2000, /* SWB<->FB */ +}; +static const opus_int32 mono_music_bandwidth_thresholds[8] = { + 12000, 1000, /* NB<->MB */ + 15000, 1000, /* MB<->WB */ + 18000, 2000, /* WB<->SWB */ + 22000, 2000, /* SWB<->FB */ +}; +static const opus_int32 stereo_voice_bandwidth_thresholds[8] = { + 11000, 1000, /* NB<->MB */ + 14000, 1000, /* MB<->WB */ + 21000, 2000, /* WB<->SWB */ + 28000, 2000, /* SWB<->FB */ +}; +static const opus_int32 stereo_music_bandwidth_thresholds[8] = { + 12000, 1000, /* NB<->MB */ + 18000, 2000, /* MB<->WB */ + 21000, 2000, /* WB<->SWB */ + 30000, 2000, /* SWB<->FB */ +}; +/* Threshold bit-rates for switching between mono and stereo */ +static const opus_int32 stereo_voice_threshold = 30000; +static const opus_int32 stereo_music_threshold = 30000; + +/* Threshold bit-rate for switching between SILK/hybrid and CELT-only */ +static const opus_int32 mode_thresholds[2][2] = { + /* voice */ /* music */ + { 64000, 16000}, /* mono */ + { 36000, 16000}, /* stereo */ +}; + +int opus_encoder_get_size(int channels) +{ + int silkEncSizeBytes, celtEncSizeBytes; + int ret; + if (channels<1 || channels > 2) + return 0; + ret = silk_Get_Encoder_Size( &silkEncSizeBytes ); + if (ret) + return 0; + silkEncSizeBytes = align(silkEncSizeBytes); + celtEncSizeBytes = celt_encoder_get_size(channels); + return align(sizeof(OpusEncoder))+silkEncSizeBytes+celtEncSizeBytes; +} + +int opus_encoder_init(OpusEncoder* st, opus_int32 Fs, int channels, int application) +{ + void *silk_enc; + CELTEncoder *celt_enc; + int err; + int ret, silkEncSizeBytes; + + if((Fs!=48000&&Fs!=24000&&Fs!=16000&&Fs!=12000&&Fs!=8000)||(channels!=1&&channels!=2)|| + (application != OPUS_APPLICATION_VOIP && application != OPUS_APPLICATION_AUDIO + && application != OPUS_APPLICATION_RESTRICTED_LOWDELAY)) + return OPUS_BAD_ARG; + + OPUS_CLEAR((char*)st, opus_encoder_get_size(channels)); + /* Create SILK encoder */ + ret = silk_Get_Encoder_Size( &silkEncSizeBytes ); + if (ret) + return OPUS_BAD_ARG; + silkEncSizeBytes = align(silkEncSizeBytes); + st->silk_enc_offset = align(sizeof(OpusEncoder)); + st->celt_enc_offset = st->silk_enc_offset+silkEncSizeBytes; + silk_enc = (char*)st+st->silk_enc_offset; + celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset); + + st->stream_channels = st->channels = channels; + + st->Fs = Fs; + + st->arch = opus_select_arch(); + + ret = silk_InitEncoder( silk_enc, st->arch, &st->silk_mode ); + if(ret)return OPUS_INTERNAL_ERROR; + + /* default SILK parameters */ + st->silk_mode.nChannelsAPI = channels; + st->silk_mode.nChannelsInternal = channels; + st->silk_mode.API_sampleRate = st->Fs; + st->silk_mode.maxInternalSampleRate = 16000; + st->silk_mode.minInternalSampleRate = 8000; + st->silk_mode.desiredInternalSampleRate = 16000; + st->silk_mode.payloadSize_ms = 20; + st->silk_mode.bitRate = 25000; + st->silk_mode.packetLossPercentage = 0; + st->silk_mode.complexity = 9; + st->silk_mode.useInBandFEC = 0; + st->silk_mode.useDTX = 0; + st->silk_mode.useCBR = 0; + st->silk_mode.reducedDependency = 0; + + /* Create CELT encoder */ + /* Initialize CELT encoder */ + err = celt_encoder_init(celt_enc, Fs, channels, st->arch); + if(err!=OPUS_OK)return OPUS_INTERNAL_ERROR; + + celt_encoder_ctl(celt_enc, CELT_SET_SIGNALLING(0)); + celt_encoder_ctl(celt_enc, OPUS_SET_COMPLEXITY(st->silk_mode.complexity)); + + st->use_vbr = 1; + /* Makes constrained VBR the default (safer for real-time use) */ + st->vbr_constraint = 1; + st->user_bitrate_bps = OPUS_AUTO; + st->bitrate_bps = 3000+Fs*channels; + st->application = application; + st->signal_type = OPUS_AUTO; + st->user_bandwidth = OPUS_AUTO; + st->max_bandwidth = OPUS_BANDWIDTH_FULLBAND; + st->force_channels = OPUS_AUTO; + st->user_forced_mode = OPUS_AUTO; + st->voice_ratio = -1; + st->encoder_buffer = st->Fs/100; + st->lsb_depth = 24; + st->variable_duration = OPUS_FRAMESIZE_ARG; + + /* Delay compensation of 4 ms (2.5 ms for SILK's extra look-ahead + + 1.5 ms for SILK resamplers and stereo prediction) */ + st->delay_compensation = st->Fs/250; + + st->hybrid_stereo_width_Q14 = 1 << 14; + st->prev_HB_gain = Q15ONE; + st->variable_HP_smth2_Q15 = silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 ); + st->first = 1; + st->mode = MODE_HYBRID; + st->bandwidth = OPUS_BANDWIDTH_FULLBAND; + + return OPUS_OK; +} + +static unsigned char gen_toc(int mode, int framerate, int bandwidth, int channels) +{ + int period; + unsigned char toc; + period = 0; + while (framerate < 400) + { + framerate <<= 1; + period++; + } + if (mode == MODE_SILK_ONLY) + { + toc = (bandwidth-OPUS_BANDWIDTH_NARROWBAND)<<5; + toc |= (period-2)<<3; + } else if (mode == MODE_CELT_ONLY) + { + int tmp = bandwidth-OPUS_BANDWIDTH_MEDIUMBAND; + if (tmp < 0) + tmp = 0; + toc = 0x80; + toc |= tmp << 5; + toc |= period<<3; + } else /* Hybrid */ + { + toc = 0x60; + toc |= (bandwidth-OPUS_BANDWIDTH_SUPERWIDEBAND)<<4; + toc |= (period-2)<<3; + } + toc |= (channels==2)<<2; + return toc; +} + +#ifndef FIXED_POINT +static void silk_biquad_float( + const opus_val16 *in, /* I: Input signal */ + const opus_int32 *B_Q28, /* I: MA coefficients [3] */ + const opus_int32 *A_Q28, /* I: AR coefficients [2] */ + opus_val32 *S, /* I/O: State vector [2] */ + opus_val16 *out, /* O: Output signal */ + const opus_int32 len, /* I: Signal length (must be even) */ + int stride +) +{ + /* DIRECT FORM II TRANSPOSED (uses 2 element state vector) */ + opus_int k; + opus_val32 vout; + opus_val32 inval; + opus_val32 A[2], B[3]; + + A[0] = (opus_val32)(A_Q28[0] * (1.f/((opus_int32)1<<28))); + A[1] = (opus_val32)(A_Q28[1] * (1.f/((opus_int32)1<<28))); + B[0] = (opus_val32)(B_Q28[0] * (1.f/((opus_int32)1<<28))); + B[1] = (opus_val32)(B_Q28[1] * (1.f/((opus_int32)1<<28))); + B[2] = (opus_val32)(B_Q28[2] * (1.f/((opus_int32)1<<28))); + + /* Negate A_Q28 values and split in two parts */ + + for( k = 0; k < len; k++ ) { + /* S[ 0 ], S[ 1 ]: Q12 */ + inval = in[ k*stride ]; + vout = S[ 0 ] + B[0]*inval; + + S[ 0 ] = S[1] - vout*A[0] + B[1]*inval; + + S[ 1 ] = - vout*A[1] + B[2]*inval + VERY_SMALL; + + /* Scale back to Q0 and saturate */ + out[ k*stride ] = vout; + } +} +#endif + +static void hp_cutoff(const opus_val16 *in, opus_int32 cutoff_Hz, opus_val16 *out, opus_val32 *hp_mem, int len, int channels, opus_int32 Fs) +{ + opus_int32 B_Q28[ 3 ], A_Q28[ 2 ]; + opus_int32 Fc_Q19, r_Q28, r_Q22; + + silk_assert( cutoff_Hz <= silk_int32_MAX / SILK_FIX_CONST( 1.5 * 3.14159 / 1000, 19 ) ); + Fc_Q19 = silk_DIV32_16( silk_SMULBB( SILK_FIX_CONST( 1.5 * 3.14159 / 1000, 19 ), cutoff_Hz ), Fs/1000 ); + silk_assert( Fc_Q19 > 0 && Fc_Q19 < 32768 ); + + r_Q28 = SILK_FIX_CONST( 1.0, 28 ) - silk_MUL( SILK_FIX_CONST( 0.92, 9 ), Fc_Q19 ); + + /* b = r * [ 1; -2; 1 ]; */ + /* a = [ 1; -2 * r * ( 1 - 0.5 * Fc^2 ); r^2 ]; */ + B_Q28[ 0 ] = r_Q28; + B_Q28[ 1 ] = silk_LSHIFT( -r_Q28, 1 ); + B_Q28[ 2 ] = r_Q28; + + /* -r * ( 2 - Fc * Fc ); */ + r_Q22 = silk_RSHIFT( r_Q28, 6 ); + A_Q28[ 0 ] = silk_SMULWW( r_Q22, silk_SMULWW( Fc_Q19, Fc_Q19 ) - SILK_FIX_CONST( 2.0, 22 ) ); + A_Q28[ 1 ] = silk_SMULWW( r_Q22, r_Q22 ); + +#ifdef FIXED_POINT + silk_biquad_alt( in, B_Q28, A_Q28, hp_mem, out, len, channels ); + if( channels == 2 ) { + silk_biquad_alt( in+1, B_Q28, A_Q28, hp_mem+2, out+1, len, channels ); + } +#else + silk_biquad_float( in, B_Q28, A_Q28, hp_mem, out, len, channels ); + if( channels == 2 ) { + silk_biquad_float( in+1, B_Q28, A_Q28, hp_mem+2, out+1, len, channels ); + } +#endif +} + +#ifdef FIXED_POINT +static void dc_reject(const opus_val16 *in, opus_int32 cutoff_Hz, opus_val16 *out, opus_val32 *hp_mem, int len, int channels, opus_int32 Fs) +{ + int c, i; + int shift; + + /* Approximates -round(log2(4.*cutoff_Hz/Fs)) */ + shift=celt_ilog2(Fs/(cutoff_Hz*3)); + for (c=0;cFs/400; + if (st->user_bitrate_bps==OPUS_AUTO) + return 60*st->Fs/frame_size + st->Fs*st->channels; + else if (st->user_bitrate_bps==OPUS_BITRATE_MAX) + return max_data_bytes*8*st->Fs/frame_size; + else + return st->user_bitrate_bps; +} + +#ifndef DISABLE_FLOAT_API +/* Don't use more than 60 ms for the frame size analysis */ +#define MAX_DYNAMIC_FRAMESIZE 24 +/* Estimates how much the bitrate will be boosted based on the sub-frame energy */ +static float transient_boost(const float *E, const float *E_1, int LM, int maxM) +{ + int i; + int M; + float sumE=0, sumE_1=0; + float metric; + + M = IMIN(maxM, (1<10 ? 1 : 0;*/ + /*return MAX16(0,1-exp(-.25*(metric-2.)));*/ + return MIN16(1,(float)sqrt(MAX16(0,.05f*(metric-2)))); +} + +/* Viterbi decoding trying to find the best frame size combination using look-ahead + + State numbering: + 0: unused + 1: 2.5 ms + 2: 5 ms (#1) + 3: 5 ms (#2) + 4: 10 ms (#1) + 5: 10 ms (#2) + 6: 10 ms (#3) + 7: 10 ms (#4) + 8: 20 ms (#1) + 9: 20 ms (#2) + 10: 20 ms (#3) + 11: 20 ms (#4) + 12: 20 ms (#5) + 13: 20 ms (#6) + 14: 20 ms (#7) + 15: 20 ms (#8) +*/ +static int transient_viterbi(const float *E, const float *E_1, int N, int frame_cost, int rate) +{ + int i; + float cost[MAX_DYNAMIC_FRAMESIZE][16]; + int states[MAX_DYNAMIC_FRAMESIZE][16]; + float best_cost; + int best_state; + float factor; + /* Take into account that we damp VBR in the 32 kb/s to 64 kb/s range. */ + if (rate<80) + factor=0; + else if (rate>160) + factor=1; + else + factor = (rate-80.f)/80.f; + /* Makes variable framesize less aggressive at lower bitrates, but I can't + find any valid theoretical justification for this (other than it seems + to help) */ + for (i=0;i<16;i++) + { + /* Impossible state */ + states[0][i] = -1; + cost[0][i] = 1e10; + } + for (i=0;i<4;i++) + { + cost[0][1<=0;i--) + { + /*printf("%d ", best_state);*/ + best_state = states[i][best_state]; + } + /*printf("%d\n", best_state);*/ + return best_state; +} + +int optimize_framesize(const opus_val16 *x, int len, int C, opus_int32 Fs, + int bitrate, opus_val16 tonality, float *mem, int buffering, + downmix_func downmix) +{ + int N; + int i; + float e[MAX_DYNAMIC_FRAMESIZE+4]; + float e_1[MAX_DYNAMIC_FRAMESIZE+3]; + opus_val32 memx; + int bestLM=0; + int subframe; + int pos; + VARDECL(opus_val32, sub); + + subframe = Fs/400; + ALLOC(sub, subframe, opus_val32); + e[0]=mem[0]; + e_1[0]=1.f/(EPSILON+mem[0]); + if (buffering) + { + /* Consider the CELT delay when not in restricted-lowdelay */ + /* We assume the buffering is between 2.5 and 5 ms */ + int offset = 2*subframe - buffering; + celt_assert(offset>=0 && offset <= subframe); + x += C*offset; + len -= offset; + e[1]=mem[1]; + e_1[1]=1.f/(EPSILON+mem[1]); + e[2]=mem[2]; + e_1[2]=1.f/(EPSILON+mem[2]); + pos = 3; + } else { + pos=1; + } + N=IMIN(len/subframe, MAX_DYNAMIC_FRAMESIZE); + /* Just silencing a warning, it's really initialized later */ + memx = 0; + for (i=0;i-1) + { + for (j=0;j-1) + { + for (j=0;j= OPUS_FRAMESIZE_2_5_MS && variable_duration <= OPUS_FRAMESIZE_60_MS) + new_size = IMIN(3*Fs/50, (Fs/400)<<(variable_duration-OPUS_FRAMESIZE_2_5_MS)); + else + return -1; + if (new_size>frame_size) + return -1; + if (400*new_size!=Fs && 200*new_size!=Fs && 100*new_size!=Fs && + 50*new_size!=Fs && 25*new_size!=Fs && 50*new_size!=3*Fs) + return -1; + return new_size; +} + +opus_int32 compute_frame_size(const void *analysis_pcm, int frame_size, + int variable_duration, int C, opus_int32 Fs, int bitrate_bps, + int delay_compensation, downmix_func downmix +#ifndef DISABLE_FLOAT_API + , float *subframe_mem +#endif + ) +{ +#ifndef DISABLE_FLOAT_API + if (variable_duration == OPUS_FRAMESIZE_VARIABLE && frame_size >= Fs/200) + { + int LM = 3; + LM = optimize_framesize(analysis_pcm, frame_size, C, Fs, bitrate_bps, + 0, subframe_mem, delay_compensation, downmix); + while ((Fs/400<frame_size) + LM--; + frame_size = (Fs/400<XX += MULT16_32_Q15(short_alpha, xx-mem->XX); + mem->XY += MULT16_32_Q15(short_alpha, xy-mem->XY); + mem->YY += MULT16_32_Q15(short_alpha, yy-mem->YY); + mem->XX = MAX32(0, mem->XX); + mem->XY = MAX32(0, mem->XY); + mem->YY = MAX32(0, mem->YY); + if (MAX32(mem->XX, mem->YY)>QCONST16(8e-4f, 18)) + { + sqrt_xx = celt_sqrt(mem->XX); + sqrt_yy = celt_sqrt(mem->YY); + qrrt_xx = celt_sqrt(sqrt_xx); + qrrt_yy = celt_sqrt(sqrt_yy); + /* Inter-channel correlation */ + mem->XY = MIN32(mem->XY, sqrt_xx*sqrt_yy); + corr = SHR32(frac_div32(mem->XY,EPSILON+MULT16_16(sqrt_xx,sqrt_yy)),16); + /* Approximate loudness difference */ + ldiff = Q15ONE*ABS16(qrrt_xx-qrrt_yy)/(EPSILON+qrrt_xx+qrrt_yy); + width = MULT16_16_Q15(celt_sqrt(QCONST32(1.f,30)-MULT16_16(corr,corr)), ldiff); + /* Smoothing over one second */ + mem->smoothed_width += (width-mem->smoothed_width)/frame_rate; + /* Peak follower */ + mem->max_follower = MAX16(mem->max_follower-QCONST16(.02f,15)/frame_rate, mem->smoothed_width); + } else { + width = 0; + corr=Q15ONE; + ldiff=0; + } + /*printf("%f %f %f %f %f ", corr/(float)Q15ONE, ldiff/(float)Q15ONE, width/(float)Q15ONE, mem->smoothed_width/(float)Q15ONE, mem->max_follower/(float)Q15ONE);*/ + return EXTRACT16(MIN32(Q15ONE,20*mem->max_follower)); +} + +opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_size, + unsigned char *data, opus_int32 out_data_bytes, int lsb_depth, + const void *analysis_pcm, opus_int32 analysis_size, int c1, int c2, int analysis_channels, downmix_func downmix) +{ + void *silk_enc; + CELTEncoder *celt_enc; + int i; + int ret=0; + opus_int32 nBytes; + ec_enc enc; + int bytes_target; + int prefill=0; + int start_band = 0; + int redundancy = 0; + int redundancy_bytes = 0; /* Number of bytes to use for redundancy frame */ + int celt_to_silk = 0; + VARDECL(opus_val16, pcm_buf); + int nb_compr_bytes; + int to_celt = 0; + opus_uint32 redundant_rng = 0; + int cutoff_Hz, hp_freq_smth1; + int voice_est; /* Probability of voice in Q7 */ + opus_int32 equiv_rate; + int delay_compensation; + int frame_rate; + opus_int32 max_rate; /* Max bitrate we're allowed to use */ + int curr_bandwidth; + opus_val16 HB_gain; + opus_int32 max_data_bytes; /* Max number of bytes we're allowed to use */ + int total_buffer; + opus_val16 stereo_width; + const CELTMode *celt_mode; + AnalysisInfo analysis_info; + int analysis_read_pos_bak=-1; + int analysis_read_subframe_bak=-1; + VARDECL(opus_val16, tmp_prefill); + + ALLOC_STACK; + + max_data_bytes = IMIN(1276, out_data_bytes); + + st->rangeFinal = 0; + if ((!st->variable_duration && 400*frame_size != st->Fs && 200*frame_size != st->Fs && 100*frame_size != st->Fs && + 50*frame_size != st->Fs && 25*frame_size != st->Fs && 50*frame_size != 3*st->Fs) + || (400*frame_size < st->Fs) + || max_data_bytes<=0 + ) + { + RESTORE_STACK; + return OPUS_BAD_ARG; + } + silk_enc = (char*)st+st->silk_enc_offset; + celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset); + if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY) + delay_compensation = 0; + else + delay_compensation = st->delay_compensation; + + lsb_depth = IMIN(lsb_depth, st->lsb_depth); + + analysis_info.valid = 0; + celt_encoder_ctl(celt_enc, CELT_GET_MODE(&celt_mode)); +#ifndef DISABLE_FLOAT_API +#ifdef FIXED_POINT + if (st->silk_mode.complexity >= 10 && st->Fs==48000) +#else + if (st->silk_mode.complexity >= 7 && st->Fs==48000) +#endif + { + analysis_read_pos_bak = st->analysis.read_pos; + analysis_read_subframe_bak = st->analysis.read_subframe; + run_analysis(&st->analysis, celt_mode, analysis_pcm, analysis_size, frame_size, + c1, c2, analysis_channels, st->Fs, + lsb_depth, downmix, &analysis_info); + } +#endif + + st->voice_ratio = -1; + +#ifndef DISABLE_FLOAT_API + st->detected_bandwidth = 0; + if (analysis_info.valid) + { + int analysis_bandwidth; + if (st->signal_type == OPUS_AUTO) + st->voice_ratio = (int)floor(.5+100*(1-analysis_info.music_prob)); + + analysis_bandwidth = analysis_info.bandwidth; + if (analysis_bandwidth<=12) + st->detected_bandwidth = OPUS_BANDWIDTH_NARROWBAND; + else if (analysis_bandwidth<=14) + st->detected_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND; + else if (analysis_bandwidth<=16) + st->detected_bandwidth = OPUS_BANDWIDTH_WIDEBAND; + else if (analysis_bandwidth<=18) + st->detected_bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND; + else + st->detected_bandwidth = OPUS_BANDWIDTH_FULLBAND; + } +#endif + + if (st->channels==2 && st->force_channels!=1) + stereo_width = compute_stereo_width(pcm, frame_size, st->Fs, &st->width_mem); + else + stereo_width = 0; + total_buffer = delay_compensation; + st->bitrate_bps = user_bitrate_to_bitrate(st, frame_size, max_data_bytes); + + frame_rate = st->Fs/frame_size; + if (max_data_bytes<3 || st->bitrate_bps < 3*frame_rate*8 + || (frame_rate<50 && (max_data_bytes*frame_rate<300 || st->bitrate_bps < 2400))) + { + /*If the space is too low to do something useful, emit 'PLC' frames.*/ + int tocmode = st->mode; + int bw = st->bandwidth == 0 ? OPUS_BANDWIDTH_NARROWBAND : st->bandwidth; + if (tocmode==0) + tocmode = MODE_SILK_ONLY; + if (frame_rate>100) + tocmode = MODE_CELT_ONLY; + if (frame_rate < 50) + tocmode = MODE_SILK_ONLY; + if(tocmode==MODE_SILK_ONLY&&bw>OPUS_BANDWIDTH_WIDEBAND) + bw=OPUS_BANDWIDTH_WIDEBAND; + else if (tocmode==MODE_CELT_ONLY&&bw==OPUS_BANDWIDTH_MEDIUMBAND) + bw=OPUS_BANDWIDTH_NARROWBAND; + else if (bw<=OPUS_BANDWIDTH_SUPERWIDEBAND) + bw=OPUS_BANDWIDTH_SUPERWIDEBAND; + data[0] = gen_toc(tocmode, frame_rate, bw, st->stream_channels); + RESTORE_STACK; + return 1; + } + if (!st->use_vbr) + { + int cbrBytes; + cbrBytes = IMIN( (st->bitrate_bps + 4*frame_rate)/(8*frame_rate) , max_data_bytes); + st->bitrate_bps = cbrBytes * (8*frame_rate); + max_data_bytes = cbrBytes; + } + max_rate = frame_rate*max_data_bytes*8; + + /* Equivalent 20-ms rate for mode/channel/bandwidth decisions */ + equiv_rate = st->bitrate_bps - (40*st->channels+20)*(st->Fs/frame_size - 50); + + if (st->signal_type == OPUS_SIGNAL_VOICE) + voice_est = 127; + else if (st->signal_type == OPUS_SIGNAL_MUSIC) + voice_est = 0; + else if (st->voice_ratio >= 0) + { + voice_est = st->voice_ratio*327>>8; + /* For AUDIO, never be more than 90% confident of having speech */ + if (st->application == OPUS_APPLICATION_AUDIO) + voice_est = IMIN(voice_est, 115); + } else if (st->application == OPUS_APPLICATION_VOIP) + voice_est = 115; + else + voice_est = 48; + + if (st->force_channels!=OPUS_AUTO && st->channels == 2) + { + st->stream_channels = st->force_channels; + } else { +#ifdef FUZZING + /* Random mono/stereo decision */ + if (st->channels == 2 && (rand()&0x1F)==0) + st->stream_channels = 3-st->stream_channels; +#else + /* Rate-dependent mono-stereo decision */ + if (st->channels == 2) + { + opus_int32 stereo_threshold; + stereo_threshold = stereo_music_threshold + ((voice_est*voice_est*(stereo_voice_threshold-stereo_music_threshold))>>14); + if (st->stream_channels == 2) + stereo_threshold -= 1000; + else + stereo_threshold += 1000; + st->stream_channels = (equiv_rate > stereo_threshold) ? 2 : 1; + } else { + st->stream_channels = st->channels; + } +#endif + } + equiv_rate = st->bitrate_bps - (40*st->stream_channels+20)*(st->Fs/frame_size - 50); + + /* Mode selection depending on application and signal type */ + if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY) + { + st->mode = MODE_CELT_ONLY; + } else if (st->user_forced_mode == OPUS_AUTO) + { +#ifdef FUZZING + /* Random mode switching */ + if ((rand()&0xF)==0) + { + if ((rand()&0x1)==0) + st->mode = MODE_CELT_ONLY; + else + st->mode = MODE_SILK_ONLY; + } else { + if (st->prev_mode==MODE_CELT_ONLY) + st->mode = MODE_CELT_ONLY; + else + st->mode = MODE_SILK_ONLY; + } +#else + opus_int32 mode_voice, mode_music; + opus_int32 threshold; + + /* Interpolate based on stereo width */ + mode_voice = (opus_int32)(MULT16_32_Q15(Q15ONE-stereo_width,mode_thresholds[0][0]) + + MULT16_32_Q15(stereo_width,mode_thresholds[1][0])); + mode_music = (opus_int32)(MULT16_32_Q15(Q15ONE-stereo_width,mode_thresholds[1][1]) + + MULT16_32_Q15(stereo_width,mode_thresholds[1][1])); + /* Interpolate based on speech/music probability */ + threshold = mode_music + ((voice_est*voice_est*(mode_voice-mode_music))>>14); + /* Bias towards SILK for VoIP because of some useful features */ + if (st->application == OPUS_APPLICATION_VOIP) + threshold += 8000; + + /*printf("%f %d\n", stereo_width/(float)Q15ONE, threshold);*/ + /* Hysteresis */ + if (st->prev_mode == MODE_CELT_ONLY) + threshold -= 4000; + else if (st->prev_mode>0) + threshold += 4000; + + st->mode = (equiv_rate >= threshold) ? MODE_CELT_ONLY: MODE_SILK_ONLY; + + /* When FEC is enabled and there's enough packet loss, use SILK */ + if (st->silk_mode.useInBandFEC && st->silk_mode.packetLossPercentage > (128-voice_est)>>4) + st->mode = MODE_SILK_ONLY; + /* When encoding voice and DTX is enabled, set the encoder to SILK mode (at least for now) */ + if (st->silk_mode.useDTX && voice_est > 100) + st->mode = MODE_SILK_ONLY; +#endif + } else { + st->mode = st->user_forced_mode; + } + + /* Override the chosen mode to make sure we meet the requested frame size */ + if (st->mode != MODE_CELT_ONLY && frame_size < st->Fs/100) + st->mode = MODE_CELT_ONLY; + if (st->lfe) + st->mode = MODE_CELT_ONLY; + /* If max_data_bytes represents less than 8 kb/s, switch to CELT-only mode */ + if (max_data_bytes < (frame_rate > 50 ? 12000 : 8000)*frame_size / (st->Fs * 8)) + st->mode = MODE_CELT_ONLY; + + if (st->stream_channels == 1 && st->prev_channels ==2 && st->silk_mode.toMono==0 + && st->mode != MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY) + { + /* Delay stereo->mono transition by two frames so that SILK can do a smooth downmix */ + st->silk_mode.toMono = 1; + st->stream_channels = 2; + } else { + st->silk_mode.toMono = 0; + } + + if (st->prev_mode > 0 && + ((st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) || + (st->mode == MODE_CELT_ONLY && st->prev_mode != MODE_CELT_ONLY))) + { + redundancy = 1; + celt_to_silk = (st->mode != MODE_CELT_ONLY); + if (!celt_to_silk) + { + /* Switch to SILK/hybrid if frame size is 10 ms or more*/ + if (frame_size >= st->Fs/100) + { + st->mode = st->prev_mode; + to_celt = 1; + } else { + redundancy=0; + } + } + } + /* For the first frame at a new SILK bandwidth */ + if (st->silk_bw_switch) + { + redundancy = 1; + celt_to_silk = 1; + st->silk_bw_switch = 0; + prefill=1; + } + + if (redundancy) + { + /* Fair share of the max size allowed */ + redundancy_bytes = IMIN(257, max_data_bytes*(opus_int32)(st->Fs/200)/(frame_size+st->Fs/200)); + /* For VBR, target the actual bitrate (subject to the limit above) */ + if (st->use_vbr) + redundancy_bytes = IMIN(redundancy_bytes, st->bitrate_bps/1600); + } + + if (st->mode != MODE_CELT_ONLY && st->prev_mode == MODE_CELT_ONLY) + { + silk_EncControlStruct dummy; + silk_InitEncoder( silk_enc, st->arch, &dummy); + prefill=1; + } + + /* Automatic (rate-dependent) bandwidth selection */ + if (st->mode == MODE_CELT_ONLY || st->first || st->silk_mode.allowBandwidthSwitch) + { + const opus_int32 *voice_bandwidth_thresholds, *music_bandwidth_thresholds; + opus_int32 bandwidth_thresholds[8]; + int bandwidth = OPUS_BANDWIDTH_FULLBAND; + opus_int32 equiv_rate2; + + equiv_rate2 = equiv_rate; + if (st->mode != MODE_CELT_ONLY) + { + /* Adjust the threshold +/- 10% depending on complexity */ + equiv_rate2 = equiv_rate2 * (45+st->silk_mode.complexity)/50; + /* CBR is less efficient by ~1 kb/s */ + if (!st->use_vbr) + equiv_rate2 -= 1000; + } + if (st->channels==2 && st->force_channels!=1) + { + voice_bandwidth_thresholds = stereo_voice_bandwidth_thresholds; + music_bandwidth_thresholds = stereo_music_bandwidth_thresholds; + } else { + voice_bandwidth_thresholds = mono_voice_bandwidth_thresholds; + music_bandwidth_thresholds = mono_music_bandwidth_thresholds; + } + /* Interpolate bandwidth thresholds depending on voice estimation */ + for (i=0;i<8;i++) + { + bandwidth_thresholds[i] = music_bandwidth_thresholds[i] + + ((voice_est*voice_est*(voice_bandwidth_thresholds[i]-music_bandwidth_thresholds[i]))>>14); + } + do { + int threshold, hysteresis; + threshold = bandwidth_thresholds[2*(bandwidth-OPUS_BANDWIDTH_MEDIUMBAND)]; + hysteresis = bandwidth_thresholds[2*(bandwidth-OPUS_BANDWIDTH_MEDIUMBAND)+1]; + if (!st->first) + { + if (st->bandwidth >= bandwidth) + threshold -= hysteresis; + else + threshold += hysteresis; + } + if (equiv_rate2 >= threshold) + break; + } while (--bandwidth>OPUS_BANDWIDTH_NARROWBAND); + st->bandwidth = bandwidth; + /* Prevents any transition to SWB/FB until the SILK layer has fully + switched to WB mode and turned the variable LP filter off */ + if (!st->first && st->mode != MODE_CELT_ONLY && !st->silk_mode.inWBmodeWithoutVariableLP && st->bandwidth > OPUS_BANDWIDTH_WIDEBAND) + st->bandwidth = OPUS_BANDWIDTH_WIDEBAND; + } + + if (st->bandwidth>st->max_bandwidth) + st->bandwidth = st->max_bandwidth; + + if (st->user_bandwidth != OPUS_AUTO) + st->bandwidth = st->user_bandwidth; + + /* This prevents us from using hybrid at unsafe CBR/max rates */ + if (st->mode != MODE_CELT_ONLY && max_rate < 15000) + { + st->bandwidth = IMIN(st->bandwidth, OPUS_BANDWIDTH_WIDEBAND); + } + + /* Prevents Opus from wasting bits on frequencies that are above + the Nyquist rate of the input signal */ + if (st->Fs <= 24000 && st->bandwidth > OPUS_BANDWIDTH_SUPERWIDEBAND) + st->bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND; + if (st->Fs <= 16000 && st->bandwidth > OPUS_BANDWIDTH_WIDEBAND) + st->bandwidth = OPUS_BANDWIDTH_WIDEBAND; + if (st->Fs <= 12000 && st->bandwidth > OPUS_BANDWIDTH_MEDIUMBAND) + st->bandwidth = OPUS_BANDWIDTH_MEDIUMBAND; + if (st->Fs <= 8000 && st->bandwidth > OPUS_BANDWIDTH_NARROWBAND) + st->bandwidth = OPUS_BANDWIDTH_NARROWBAND; +#ifndef DISABLE_FLOAT_API + /* Use detected bandwidth to reduce the encoded bandwidth. */ + if (st->detected_bandwidth && st->user_bandwidth == OPUS_AUTO) + { + int min_detected_bandwidth; + /* Makes bandwidth detection more conservative just in case the detector + gets it wrong when we could have coded a high bandwidth transparently. + When operating in SILK/hybrid mode, we don't go below wideband to avoid + more complicated switches that require redundancy. */ + if (equiv_rate <= 18000*st->stream_channels && st->mode == MODE_CELT_ONLY) + min_detected_bandwidth = OPUS_BANDWIDTH_NARROWBAND; + else if (equiv_rate <= 24000*st->stream_channels && st->mode == MODE_CELT_ONLY) + min_detected_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND; + else if (equiv_rate <= 30000*st->stream_channels) + min_detected_bandwidth = OPUS_BANDWIDTH_WIDEBAND; + else if (equiv_rate <= 44000*st->stream_channels) + min_detected_bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND; + else + min_detected_bandwidth = OPUS_BANDWIDTH_FULLBAND; + + st->detected_bandwidth = IMAX(st->detected_bandwidth, min_detected_bandwidth); + st->bandwidth = IMIN(st->bandwidth, st->detected_bandwidth); + } +#endif + celt_encoder_ctl(celt_enc, OPUS_SET_LSB_DEPTH(lsb_depth)); + + /* CELT mode doesn't support mediumband, use wideband instead */ + if (st->mode == MODE_CELT_ONLY && st->bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) + st->bandwidth = OPUS_BANDWIDTH_WIDEBAND; + if (st->lfe) + st->bandwidth = OPUS_BANDWIDTH_NARROWBAND; + + /* Can't support higher than wideband for >20 ms frames */ + if (frame_size > st->Fs/50 && (st->mode == MODE_CELT_ONLY || st->bandwidth > OPUS_BANDWIDTH_WIDEBAND)) + { + VARDECL(unsigned char, tmp_data); + int nb_frames; + int bak_mode, bak_bandwidth, bak_channels, bak_to_mono; + VARDECL(OpusRepacketizer, rp); + opus_int32 bytes_per_frame; + opus_int32 repacketize_len; + +#ifndef DISABLE_FLOAT_API + if (analysis_read_pos_bak!= -1) + { + st->analysis.read_pos = analysis_read_pos_bak; + st->analysis.read_subframe = analysis_read_subframe_bak; + } +#endif + + nb_frames = frame_size > st->Fs/25 ? 3 : 2; + bytes_per_frame = IMIN(1276,(out_data_bytes-3)/nb_frames); + + ALLOC(tmp_data, nb_frames*bytes_per_frame, unsigned char); + + ALLOC(rp, 1, OpusRepacketizer); + opus_repacketizer_init(rp); + + bak_mode = st->user_forced_mode; + bak_bandwidth = st->user_bandwidth; + bak_channels = st->force_channels; + + st->user_forced_mode = st->mode; + st->user_bandwidth = st->bandwidth; + st->force_channels = st->stream_channels; + bak_to_mono = st->silk_mode.toMono; + + if (bak_to_mono) + st->force_channels = 1; + else + st->prev_channels = st->stream_channels; + for (i=0;isilk_mode.toMono = 0; + /* When switching from SILK/Hybrid to CELT, only ask for a switch at the last frame */ + if (to_celt && i==nb_frames-1) + st->user_forced_mode = MODE_CELT_ONLY; + tmp_len = opus_encode_native(st, pcm+i*(st->channels*st->Fs/50), st->Fs/50, + tmp_data+i*bytes_per_frame, bytes_per_frame, lsb_depth, + NULL, 0, c1, c2, analysis_channels, downmix); + if (tmp_len<0) + { + RESTORE_STACK; + return OPUS_INTERNAL_ERROR; + } + ret = opus_repacketizer_cat(rp, tmp_data+i*bytes_per_frame, tmp_len); + if (ret<0) + { + RESTORE_STACK; + return OPUS_INTERNAL_ERROR; + } + } + if (st->use_vbr) + repacketize_len = out_data_bytes; + else + repacketize_len = IMIN(3*st->bitrate_bps/(3*8*50/nb_frames), out_data_bytes); + ret = opus_repacketizer_out_range_impl(rp, 0, nb_frames, data, repacketize_len, 0, !st->use_vbr); + if (ret<0) + { + RESTORE_STACK; + return OPUS_INTERNAL_ERROR; + } + st->user_forced_mode = bak_mode; + st->user_bandwidth = bak_bandwidth; + st->force_channels = bak_channels; + st->silk_mode.toMono = bak_to_mono; + RESTORE_STACK; + return ret; + } + curr_bandwidth = st->bandwidth; + + /* Chooses the appropriate mode for speech + *NEVER* switch to/from CELT-only mode here as this will invalidate some assumptions */ + if (st->mode == MODE_SILK_ONLY && curr_bandwidth > OPUS_BANDWIDTH_WIDEBAND) + st->mode = MODE_HYBRID; + if (st->mode == MODE_HYBRID && curr_bandwidth <= OPUS_BANDWIDTH_WIDEBAND) + st->mode = MODE_SILK_ONLY; + + /* printf("%d %d %d %d\n", st->bitrate_bps, st->stream_channels, st->mode, curr_bandwidth); */ + bytes_target = IMIN(max_data_bytes-redundancy_bytes, st->bitrate_bps * frame_size / (st->Fs * 8)) - 1; + + data += 1; + + ec_enc_init(&enc, data, max_data_bytes-1); + + ALLOC(pcm_buf, (total_buffer+frame_size)*st->channels, opus_val16); + for (i=0;ichannels;i++) + pcm_buf[i] = st->delay_buffer[(st->encoder_buffer-total_buffer)*st->channels+i]; + + if (st->mode == MODE_CELT_ONLY) + hp_freq_smth1 = silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 ); + else + hp_freq_smth1 = ((silk_encoder*)silk_enc)->state_Fxx[0].sCmn.variable_HP_smth1_Q15; + + st->variable_HP_smth2_Q15 = silk_SMLAWB( st->variable_HP_smth2_Q15, + hp_freq_smth1 - st->variable_HP_smth2_Q15, SILK_FIX_CONST( VARIABLE_HP_SMTH_COEF2, 16 ) ); + + /* convert from log scale to Hertz */ + cutoff_Hz = silk_log2lin( silk_RSHIFT( st->variable_HP_smth2_Q15, 8 ) ); + + if (st->application == OPUS_APPLICATION_VOIP) + { + hp_cutoff(pcm, cutoff_Hz, &pcm_buf[total_buffer*st->channels], st->hp_mem, frame_size, st->channels, st->Fs); + } else { + dc_reject(pcm, 3, &pcm_buf[total_buffer*st->channels], st->hp_mem, frame_size, st->channels, st->Fs); + } + + + + /* SILK processing */ + HB_gain = Q15ONE; + if (st->mode != MODE_CELT_ONLY) + { + opus_int32 total_bitRate, celt_rate; +#ifdef FIXED_POINT + const opus_int16 *pcm_silk; +#else + VARDECL(opus_int16, pcm_silk); + ALLOC(pcm_silk, st->channels*frame_size, opus_int16); +#endif + + /* Distribute bits between SILK and CELT */ + total_bitRate = 8 * bytes_target * frame_rate; + if( st->mode == MODE_HYBRID ) { + int HB_gain_ref; + /* Base rate for SILK */ + st->silk_mode.bitRate = st->stream_channels * ( 5000 + 1000 * ( st->Fs == 100 * frame_size ) ); + if( curr_bandwidth == OPUS_BANDWIDTH_SUPERWIDEBAND ) { + /* SILK gets 2/3 of the remaining bits */ + st->silk_mode.bitRate += ( total_bitRate - st->silk_mode.bitRate ) * 2 / 3; + } else { /* FULLBAND */ + /* SILK gets 3/5 of the remaining bits */ + st->silk_mode.bitRate += ( total_bitRate - st->silk_mode.bitRate ) * 3 / 5; + } + /* Don't let SILK use more than 80% */ + if( st->silk_mode.bitRate > total_bitRate * 4/5 ) { + st->silk_mode.bitRate = total_bitRate * 4/5; + } + if (!st->energy_masking) + { + /* Increasingly attenuate high band when it gets allocated fewer bits */ + celt_rate = total_bitRate - st->silk_mode.bitRate; + HB_gain_ref = (curr_bandwidth == OPUS_BANDWIDTH_SUPERWIDEBAND) ? 3000 : 3600; + HB_gain = SHL32((opus_val32)celt_rate, 9) / SHR32((opus_val32)celt_rate + st->stream_channels * HB_gain_ref, 6); + HB_gain = HB_gain < Q15ONE*6/7 ? HB_gain + Q15ONE/7 : Q15ONE; + } + } else { + /* SILK gets all bits */ + st->silk_mode.bitRate = total_bitRate; + } + + /* Surround masking for SILK */ + if (st->energy_masking && st->use_vbr && !st->lfe) + { + opus_val32 mask_sum=0; + opus_val16 masking_depth; + opus_int32 rate_offset; + int c; + int end = 17; + opus_int16 srate = 16000; + if (st->bandwidth == OPUS_BANDWIDTH_NARROWBAND) + { + end = 13; + srate = 8000; + } else if (st->bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) + { + end = 15; + srate = 12000; + } + for (c=0;cchannels;c++) + { + for(i=0;ienergy_masking[21*c+i], + QCONST16(.5f, DB_SHIFT)), -QCONST16(2.0f, DB_SHIFT)); + if (mask > 0) + mask = HALF16(mask); + mask_sum += mask; + } + } + /* Conservative rate reduction, we cut the masking in half */ + masking_depth = mask_sum / end*st->channels; + masking_depth += QCONST16(.2f, DB_SHIFT); + rate_offset = (opus_int32)PSHR32(MULT16_16(srate, masking_depth), DB_SHIFT); + rate_offset = MAX32(rate_offset, -2*st->silk_mode.bitRate/3); + /* Split the rate change between the SILK and CELT part for hybrid. */ + if (st->bandwidth==OPUS_BANDWIDTH_SUPERWIDEBAND || st->bandwidth==OPUS_BANDWIDTH_FULLBAND) + st->silk_mode.bitRate += 3*rate_offset/5; + else + st->silk_mode.bitRate += rate_offset; + bytes_target += rate_offset * frame_size / (8 * st->Fs); + } + + st->silk_mode.payloadSize_ms = 1000 * frame_size / st->Fs; + st->silk_mode.nChannelsAPI = st->channels; + st->silk_mode.nChannelsInternal = st->stream_channels; + if (curr_bandwidth == OPUS_BANDWIDTH_NARROWBAND) { + st->silk_mode.desiredInternalSampleRate = 8000; + } else if (curr_bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) { + st->silk_mode.desiredInternalSampleRate = 12000; + } else { + silk_assert( st->mode == MODE_HYBRID || curr_bandwidth == OPUS_BANDWIDTH_WIDEBAND ); + st->silk_mode.desiredInternalSampleRate = 16000; + } + if( st->mode == MODE_HYBRID ) { + /* Don't allow bandwidth reduction at lowest bitrates in hybrid mode */ + st->silk_mode.minInternalSampleRate = 16000; + } else { + st->silk_mode.minInternalSampleRate = 8000; + } + + if (st->mode == MODE_SILK_ONLY) + { + opus_int32 effective_max_rate = max_rate; + st->silk_mode.maxInternalSampleRate = 16000; + if (frame_rate > 50) + effective_max_rate = effective_max_rate*2/3; + if (effective_max_rate < 13000) + { + st->silk_mode.maxInternalSampleRate = 12000; + st->silk_mode.desiredInternalSampleRate = IMIN(12000, st->silk_mode.desiredInternalSampleRate); + } + if (effective_max_rate < 9600) + { + st->silk_mode.maxInternalSampleRate = 8000; + st->silk_mode.desiredInternalSampleRate = IMIN(8000, st->silk_mode.desiredInternalSampleRate); + } + } else { + st->silk_mode.maxInternalSampleRate = 16000; + } + + st->silk_mode.useCBR = !st->use_vbr; + + /* Call SILK encoder for the low band */ + nBytes = IMIN(1275, max_data_bytes-1-redundancy_bytes); + + st->silk_mode.maxBits = nBytes*8; + /* Only allow up to 90% of the bits for hybrid mode*/ + if (st->mode == MODE_HYBRID) + st->silk_mode.maxBits = (opus_int32)st->silk_mode.maxBits*9/10; + if (st->silk_mode.useCBR) + { + st->silk_mode.maxBits = (st->silk_mode.bitRate * frame_size / (st->Fs * 8))*8; + /* Reduce the initial target to make it easier to reach the CBR rate */ + st->silk_mode.bitRate = IMAX(1, st->silk_mode.bitRate-2000); + } + + if (prefill) + { + opus_int32 zero=0; + int prefill_offset; + /* Use a smooth onset for the SILK prefill to avoid the encoder trying to encode + a discontinuity. The exact location is what we need to avoid leaving any "gap" + in the audio when mixing with the redundant CELT frame. Here we can afford to + overwrite st->delay_buffer because the only thing that uses it before it gets + rewritten is tmp_prefill[] and even then only the part after the ramp really + gets used (rather than sent to the encoder and discarded) */ + prefill_offset = st->channels*(st->encoder_buffer-st->delay_compensation-st->Fs/400); + gain_fade(st->delay_buffer+prefill_offset, st->delay_buffer+prefill_offset, + 0, Q15ONE, celt_mode->overlap, st->Fs/400, st->channels, celt_mode->window, st->Fs); + for(i=0;idelay_buffer[i]=0; +#ifdef FIXED_POINT + pcm_silk = st->delay_buffer; +#else + for (i=0;iencoder_buffer*st->channels;i++) + pcm_silk[i] = FLOAT2INT16(st->delay_buffer[i]); +#endif + silk_Encode( silk_enc, &st->silk_mode, pcm_silk, st->encoder_buffer, NULL, &zero, 1 ); + } + +#ifdef FIXED_POINT + pcm_silk = pcm_buf+total_buffer*st->channels; +#else + for (i=0;ichannels;i++) + pcm_silk[i] = FLOAT2INT16(pcm_buf[total_buffer*st->channels + i]); +#endif + ret = silk_Encode( silk_enc, &st->silk_mode, pcm_silk, frame_size, &enc, &nBytes, 0 ); + if( ret ) { + /*fprintf (stderr, "SILK encode error: %d\n", ret);*/ + /* Handle error */ + RESTORE_STACK; + return OPUS_INTERNAL_ERROR; + } + if (nBytes==0) + { + st->rangeFinal = 0; + data[-1] = gen_toc(st->mode, st->Fs/frame_size, curr_bandwidth, st->stream_channels); + RESTORE_STACK; + return 1; + } + /* Extract SILK internal bandwidth for signaling in first byte */ + if( st->mode == MODE_SILK_ONLY ) { + if( st->silk_mode.internalSampleRate == 8000 ) { + curr_bandwidth = OPUS_BANDWIDTH_NARROWBAND; + } else if( st->silk_mode.internalSampleRate == 12000 ) { + curr_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND; + } else if( st->silk_mode.internalSampleRate == 16000 ) { + curr_bandwidth = OPUS_BANDWIDTH_WIDEBAND; + } + } else { + silk_assert( st->silk_mode.internalSampleRate == 16000 ); + } + + st->silk_mode.opusCanSwitch = st->silk_mode.switchReady; + /* FIXME: How do we allocate the redundancy for CBR? */ + if (st->silk_mode.opusCanSwitch) + { + redundancy = 1; + celt_to_silk = 0; + st->silk_bw_switch = 1; + } + } + + /* CELT processing */ + { + int endband=21; + + switch(curr_bandwidth) + { + case OPUS_BANDWIDTH_NARROWBAND: + endband = 13; + break; + case OPUS_BANDWIDTH_MEDIUMBAND: + case OPUS_BANDWIDTH_WIDEBAND: + endband = 17; + break; + case OPUS_BANDWIDTH_SUPERWIDEBAND: + endband = 19; + break; + case OPUS_BANDWIDTH_FULLBAND: + endband = 21; + break; + } + celt_encoder_ctl(celt_enc, CELT_SET_END_BAND(endband)); + celt_encoder_ctl(celt_enc, CELT_SET_CHANNELS(st->stream_channels)); + } + celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(OPUS_BITRATE_MAX)); + if (st->mode != MODE_SILK_ONLY) + { + opus_val32 celt_pred=2; + celt_encoder_ctl(celt_enc, OPUS_SET_VBR(0)); + /* We may still decide to disable prediction later */ + if (st->silk_mode.reducedDependency) + celt_pred = 0; + celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(celt_pred)); + + if (st->mode == MODE_HYBRID) + { + int len; + + len = (ec_tell(&enc)+7)>>3; + if (redundancy) + len += st->mode == MODE_HYBRID ? 3 : 1; + if( st->use_vbr ) { + nb_compr_bytes = len + bytes_target - (st->silk_mode.bitRate * frame_size) / (8 * st->Fs); + } else { + /* check if SILK used up too much */ + nb_compr_bytes = len > bytes_target ? len : bytes_target; + } + } else { + if (st->use_vbr) + { + opus_int32 bonus=0; +#ifndef DISABLE_FLOAT_API + if (st->variable_duration==OPUS_FRAMESIZE_VARIABLE && frame_size != st->Fs/50) + { + bonus = (60*st->stream_channels+40)*(st->Fs/frame_size-50); + if (analysis_info.valid) + bonus = (opus_int32)(bonus*(1.f+.5f*analysis_info.tonality)); + } +#endif + celt_encoder_ctl(celt_enc, OPUS_SET_VBR(1)); + celt_encoder_ctl(celt_enc, OPUS_SET_VBR_CONSTRAINT(st->vbr_constraint)); + celt_encoder_ctl(celt_enc, OPUS_SET_BITRATE(st->bitrate_bps+bonus)); + nb_compr_bytes = max_data_bytes-1-redundancy_bytes; + } else { + nb_compr_bytes = bytes_target; + } + } + + } else { + nb_compr_bytes = 0; + } + + ALLOC(tmp_prefill, st->channels*st->Fs/400, opus_val16); + if (st->mode != MODE_SILK_ONLY && st->mode != st->prev_mode && st->prev_mode > 0) + { + for (i=0;ichannels*st->Fs/400;i++) + tmp_prefill[i] = st->delay_buffer[(st->encoder_buffer-total_buffer-st->Fs/400)*st->channels + i]; + } + + for (i=0;ichannels*(st->encoder_buffer-(frame_size+total_buffer));i++) + st->delay_buffer[i] = st->delay_buffer[i+st->channels*frame_size]; + for (;iencoder_buffer*st->channels;i++) + st->delay_buffer[i] = pcm_buf[(frame_size+total_buffer-st->encoder_buffer)*st->channels+i]; + + /* gain_fade() and stereo_fade() need to be after the buffer copying + because we don't want any of this to affect the SILK part */ + if( st->prev_HB_gain < Q15ONE || HB_gain < Q15ONE ) { + gain_fade(pcm_buf, pcm_buf, + st->prev_HB_gain, HB_gain, celt_mode->overlap, frame_size, st->channels, celt_mode->window, st->Fs); + } + st->prev_HB_gain = HB_gain; + if (st->mode != MODE_HYBRID || st->stream_channels==1) + st->silk_mode.stereoWidth_Q14 = IMIN((1<<14),2*IMAX(0,equiv_rate-30000)); + if( !st->energy_masking && st->channels == 2 ) { + /* Apply stereo width reduction (at low bitrates) */ + if( st->hybrid_stereo_width_Q14 < (1 << 14) || st->silk_mode.stereoWidth_Q14 < (1 << 14) ) { + opus_val16 g1, g2; + g1 = st->hybrid_stereo_width_Q14; + g2 = (opus_val16)(st->silk_mode.stereoWidth_Q14); +#ifdef FIXED_POINT + g1 = g1==16384 ? Q15ONE : SHL16(g1,1); + g2 = g2==16384 ? Q15ONE : SHL16(g2,1); +#else + g1 *= (1.f/16384); + g2 *= (1.f/16384); +#endif + stereo_fade(pcm_buf, pcm_buf, g1, g2, celt_mode->overlap, + frame_size, st->channels, celt_mode->window, st->Fs); + st->hybrid_stereo_width_Q14 = st->silk_mode.stereoWidth_Q14; + } + } + + if ( st->mode != MODE_CELT_ONLY && ec_tell(&enc)+17+20*(st->mode == MODE_HYBRID) <= 8*(max_data_bytes-1)) + { + /* For SILK mode, the redundancy is inferred from the length */ + if (st->mode == MODE_HYBRID && (redundancy || ec_tell(&enc)+37 <= 8*nb_compr_bytes)) + ec_enc_bit_logp(&enc, redundancy, 12); + if (redundancy) + { + int max_redundancy; + ec_enc_bit_logp(&enc, celt_to_silk, 1); + if (st->mode == MODE_HYBRID) + max_redundancy = (max_data_bytes-1)-nb_compr_bytes; + else + max_redundancy = (max_data_bytes-1)-((ec_tell(&enc)+7)>>3); + /* Target the same bit-rate for redundancy as for the rest, + up to a max of 257 bytes */ + redundancy_bytes = IMIN(max_redundancy, st->bitrate_bps/1600); + redundancy_bytes = IMIN(257, IMAX(2, redundancy_bytes)); + if (st->mode == MODE_HYBRID) + ec_enc_uint(&enc, redundancy_bytes-2, 256); + } + } else { + redundancy = 0; + } + + if (!redundancy) + { + st->silk_bw_switch = 0; + redundancy_bytes = 0; + } + if (st->mode != MODE_CELT_ONLY)start_band=17; + + if (st->mode == MODE_SILK_ONLY) + { + ret = (ec_tell(&enc)+7)>>3; + ec_enc_done(&enc); + nb_compr_bytes = ret; + } else { + nb_compr_bytes = IMIN((max_data_bytes-1)-redundancy_bytes, nb_compr_bytes); + ec_enc_shrink(&enc, nb_compr_bytes); + } + +#ifndef DISABLE_FLOAT_API + if (redundancy || st->mode != MODE_SILK_ONLY) + celt_encoder_ctl(celt_enc, CELT_SET_ANALYSIS(&analysis_info)); +#endif + + /* 5 ms redundant frame for CELT->SILK */ + if (redundancy && celt_to_silk) + { + int err; + celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0)); + celt_encoder_ctl(celt_enc, OPUS_SET_VBR(0)); + err = celt_encode_with_ec(celt_enc, pcm_buf, st->Fs/200, data+nb_compr_bytes, redundancy_bytes, NULL); + if (err < 0) + { + RESTORE_STACK; + return OPUS_INTERNAL_ERROR; + } + celt_encoder_ctl(celt_enc, OPUS_GET_FINAL_RANGE(&redundant_rng)); + celt_encoder_ctl(celt_enc, OPUS_RESET_STATE); + } + + celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(start_band)); + + if (st->mode != MODE_SILK_ONLY) + { + if (st->mode != st->prev_mode && st->prev_mode > 0) + { + unsigned char dummy[2]; + celt_encoder_ctl(celt_enc, OPUS_RESET_STATE); + + /* Prefilling */ + celt_encode_with_ec(celt_enc, tmp_prefill, st->Fs/400, dummy, 2, NULL); + celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(0)); + } + /* If false, we already busted the budget and we'll end up with a "PLC packet" */ + if (ec_tell(&enc) <= 8*nb_compr_bytes) + { + ret = celt_encode_with_ec(celt_enc, pcm_buf, frame_size, NULL, nb_compr_bytes, &enc); + if (ret < 0) + { + RESTORE_STACK; + return OPUS_INTERNAL_ERROR; + } + } + } + + /* 5 ms redundant frame for SILK->CELT */ + if (redundancy && !celt_to_silk) + { + int err; + unsigned char dummy[2]; + int N2, N4; + N2 = st->Fs/200; + N4 = st->Fs/400; + + celt_encoder_ctl(celt_enc, OPUS_RESET_STATE); + celt_encoder_ctl(celt_enc, CELT_SET_START_BAND(0)); + celt_encoder_ctl(celt_enc, CELT_SET_PREDICTION(0)); + + /* NOTE: We could speed this up slightly (at the expense of code size) by just adding a function that prefills the buffer */ + celt_encode_with_ec(celt_enc, pcm_buf+st->channels*(frame_size-N2-N4), N4, dummy, 2, NULL); + + err = celt_encode_with_ec(celt_enc, pcm_buf+st->channels*(frame_size-N2), N2, data+nb_compr_bytes, redundancy_bytes, NULL); + if (err < 0) + { + RESTORE_STACK; + return OPUS_INTERNAL_ERROR; + } + celt_encoder_ctl(celt_enc, OPUS_GET_FINAL_RANGE(&redundant_rng)); + } + + + + /* Signalling the mode in the first byte */ + data--; + data[0] = gen_toc(st->mode, st->Fs/frame_size, curr_bandwidth, st->stream_channels); + + st->rangeFinal = enc.rng ^ redundant_rng; + + if (to_celt) + st->prev_mode = MODE_CELT_ONLY; + else + st->prev_mode = st->mode; + st->prev_channels = st->stream_channels; + st->prev_framesize = frame_size; + + st->first = 0; + + /* In the unlikely case that the SILK encoder busted its target, tell + the decoder to call the PLC */ + if (ec_tell(&enc) > (max_data_bytes-1)*8) + { + if (max_data_bytes < 2) + { + RESTORE_STACK; + return OPUS_BUFFER_TOO_SMALL; + } + data[1] = 0; + ret = 1; + st->rangeFinal = 0; + } else if (st->mode==MODE_SILK_ONLY&&!redundancy) + { + /*When in LPC only mode it's perfectly + reasonable to strip off trailing zero bytes as + the required range decoder behavior is to + fill these in. This can't be done when the MDCT + modes are used because the decoder needs to know + the actual length for allocation purposes.*/ + while(ret>2&&data[ret]==0)ret--; + } + /* Count ToC and redundancy */ + ret += 1+redundancy_bytes; + if (!st->use_vbr) + { + if (opus_packet_pad(data, ret, max_data_bytes) != OPUS_OK) + + { + RESTORE_STACK; + return OPUS_INTERNAL_ERROR; + } + ret = max_data_bytes; + } + RESTORE_STACK; + return ret; +} + +#ifdef FIXED_POINT + +#ifndef DISABLE_FLOAT_API +opus_int32 opus_encode_float(OpusEncoder *st, const float *pcm, int analysis_frame_size, + unsigned char *data, opus_int32 max_data_bytes) +{ + int i, ret; + int frame_size; + int delay_compensation; + VARDECL(opus_int16, in); + ALLOC_STACK; + + if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY) + delay_compensation = 0; + else + delay_compensation = st->delay_compensation; + frame_size = compute_frame_size(pcm, analysis_frame_size, + st->variable_duration, st->channels, st->Fs, st->bitrate_bps, + delay_compensation, downmix_float, st->analysis.subframe_mem); + + ALLOC(in, frame_size*st->channels, opus_int16); + + for (i=0;ichannels;i++) + in[i] = FLOAT2INT16(pcm[i]); + ret = opus_encode_native(st, in, frame_size, data, max_data_bytes, 16, pcm, analysis_frame_size, 0, -2, st->channels, downmix_float); + RESTORE_STACK; + return ret; +} +#endif + +opus_int32 opus_encode(OpusEncoder *st, const opus_int16 *pcm, int analysis_frame_size, + unsigned char *data, opus_int32 out_data_bytes) +{ + int frame_size; + int delay_compensation; + if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY) + delay_compensation = 0; + else + delay_compensation = st->delay_compensation; + frame_size = compute_frame_size(pcm, analysis_frame_size, + st->variable_duration, st->channels, st->Fs, st->bitrate_bps, + delay_compensation, downmix_int +#ifndef DISABLE_FLOAT_API + , st->analysis.subframe_mem +#endif + ); + return opus_encode_native(st, pcm, frame_size, data, out_data_bytes, 16, pcm, analysis_frame_size, 0, -2, st->channels, downmix_int); +} + +#else +opus_int32 opus_encode(OpusEncoder *st, const opus_int16 *pcm, int analysis_frame_size, + unsigned char *data, opus_int32 max_data_bytes) +{ + int i, ret; + int frame_size; + int delay_compensation; + VARDECL(float, in); + ALLOC_STACK; + + if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY) + delay_compensation = 0; + else + delay_compensation = st->delay_compensation; + frame_size = compute_frame_size(pcm, analysis_frame_size, + st->variable_duration, st->channels, st->Fs, st->bitrate_bps, + delay_compensation, downmix_int, st->analysis.subframe_mem); + + ALLOC(in, frame_size*st->channels, float); + + for (i=0;ichannels;i++) + in[i] = (1.0f/32768)*pcm[i]; + ret = opus_encode_native(st, in, frame_size, data, max_data_bytes, 16, pcm, analysis_frame_size, 0, -2, st->channels, downmix_int); + RESTORE_STACK; + return ret; +} +opus_int32 opus_encode_float(OpusEncoder *st, const float *pcm, int analysis_frame_size, + unsigned char *data, opus_int32 out_data_bytes) +{ + int frame_size; + int delay_compensation; + if (st->application == OPUS_APPLICATION_RESTRICTED_LOWDELAY) + delay_compensation = 0; + else + delay_compensation = st->delay_compensation; + frame_size = compute_frame_size(pcm, analysis_frame_size, + st->variable_duration, st->channels, st->Fs, st->bitrate_bps, + delay_compensation, downmix_float, st->analysis.subframe_mem); + return opus_encode_native(st, pcm, frame_size, data, out_data_bytes, 24, + pcm, analysis_frame_size, 0, -2, st->channels, downmix_float); +} +#endif + + +int opus_encoder_ctl(OpusEncoder *st, int request, ...) +{ + int ret; + CELTEncoder *celt_enc; + va_list ap; + + ret = OPUS_OK; + va_start(ap, request); + + celt_enc = (CELTEncoder*)((char*)st+st->celt_enc_offset); + + switch (request) + { + case OPUS_SET_APPLICATION_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if ( (value != OPUS_APPLICATION_VOIP && value != OPUS_APPLICATION_AUDIO + && value != OPUS_APPLICATION_RESTRICTED_LOWDELAY) + || (!st->first && st->application != value)) + { + ret = OPUS_BAD_ARG; + break; + } + st->application = value; + } + break; + case OPUS_GET_APPLICATION_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } + *value = st->application; + } + break; + case OPUS_SET_BITRATE_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if (value != OPUS_AUTO && value != OPUS_BITRATE_MAX) + { + if (value <= 0) + goto bad_arg; + else if (value <= 500) + value = 500; + else if (value > (opus_int32)300000*st->channels) + value = (opus_int32)300000*st->channels; + } + st->user_bitrate_bps = value; + } + break; + case OPUS_GET_BITRATE_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } + *value = user_bitrate_to_bitrate(st, st->prev_framesize, 1276); + } + break; + case OPUS_SET_FORCE_CHANNELS_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if((value<1 || value>st->channels) && value != OPUS_AUTO) + { + goto bad_arg; + } + st->force_channels = value; + } + break; + case OPUS_GET_FORCE_CHANNELS_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } + *value = st->force_channels; + } + break; + case OPUS_SET_MAX_BANDWIDTH_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if (value < OPUS_BANDWIDTH_NARROWBAND || value > OPUS_BANDWIDTH_FULLBAND) + { + goto bad_arg; + } + st->max_bandwidth = value; + if (st->max_bandwidth == OPUS_BANDWIDTH_NARROWBAND) { + st->silk_mode.maxInternalSampleRate = 8000; + } else if (st->max_bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) { + st->silk_mode.maxInternalSampleRate = 12000; + } else { + st->silk_mode.maxInternalSampleRate = 16000; + } + } + break; + case OPUS_GET_MAX_BANDWIDTH_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } + *value = st->max_bandwidth; + } + break; + case OPUS_SET_BANDWIDTH_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if ((value < OPUS_BANDWIDTH_NARROWBAND || value > OPUS_BANDWIDTH_FULLBAND) && value != OPUS_AUTO) + { + goto bad_arg; + } + st->user_bandwidth = value; + if (st->user_bandwidth == OPUS_BANDWIDTH_NARROWBAND) { + st->silk_mode.maxInternalSampleRate = 8000; + } else if (st->user_bandwidth == OPUS_BANDWIDTH_MEDIUMBAND) { + st->silk_mode.maxInternalSampleRate = 12000; + } else { + st->silk_mode.maxInternalSampleRate = 16000; + } + } + break; + case OPUS_GET_BANDWIDTH_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } + *value = st->bandwidth; + } + break; + case OPUS_SET_DTX_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if(value<0 || value>1) + { + goto bad_arg; + } + st->silk_mode.useDTX = value; + } + break; + case OPUS_GET_DTX_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } + *value = st->silk_mode.useDTX; + } + break; + case OPUS_SET_COMPLEXITY_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if(value<0 || value>10) + { + goto bad_arg; + } + st->silk_mode.complexity = value; + celt_encoder_ctl(celt_enc, OPUS_SET_COMPLEXITY(value)); + } + break; + case OPUS_GET_COMPLEXITY_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } + *value = st->silk_mode.complexity; + } + break; + case OPUS_SET_INBAND_FEC_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if(value<0 || value>1) + { + goto bad_arg; + } + st->silk_mode.useInBandFEC = value; + } + break; + case OPUS_GET_INBAND_FEC_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } + *value = st->silk_mode.useInBandFEC; + } + break; + case OPUS_SET_PACKET_LOSS_PERC_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if (value < 0 || value > 100) + { + goto bad_arg; + } + st->silk_mode.packetLossPercentage = value; + celt_encoder_ctl(celt_enc, OPUS_SET_PACKET_LOSS_PERC(value)); + } + break; + case OPUS_GET_PACKET_LOSS_PERC_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } + *value = st->silk_mode.packetLossPercentage; + } + break; + case OPUS_SET_VBR_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if(value<0 || value>1) + { + goto bad_arg; + } + st->use_vbr = value; + st->silk_mode.useCBR = 1-value; + } + break; + case OPUS_GET_VBR_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } + *value = st->use_vbr; + } + break; + case OPUS_SET_VOICE_RATIO_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if (value<-1 || value>100) + { + goto bad_arg; + } + st->voice_ratio = value; + } + break; + case OPUS_GET_VOICE_RATIO_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } + *value = st->voice_ratio; + } + break; + case OPUS_SET_VBR_CONSTRAINT_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if(value<0 || value>1) + { + goto bad_arg; + } + st->vbr_constraint = value; + } + break; + case OPUS_GET_VBR_CONSTRAINT_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } + *value = st->vbr_constraint; + } + break; + case OPUS_SET_SIGNAL_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if(value!=OPUS_AUTO && value!=OPUS_SIGNAL_VOICE && value!=OPUS_SIGNAL_MUSIC) + { + goto bad_arg; + } + st->signal_type = value; + } + break; + case OPUS_GET_SIGNAL_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } + *value = st->signal_type; + } + break; + case OPUS_GET_LOOKAHEAD_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } + *value = st->Fs/400; + if (st->application != OPUS_APPLICATION_RESTRICTED_LOWDELAY) + *value += st->delay_compensation; + } + break; + case OPUS_GET_SAMPLE_RATE_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } + *value = st->Fs; + } + break; + case OPUS_GET_FINAL_RANGE_REQUEST: + { + opus_uint32 *value = va_arg(ap, opus_uint32*); + if (!value) + { + goto bad_arg; + } + *value = st->rangeFinal; + } + break; + case OPUS_SET_LSB_DEPTH_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if (value<8 || value>24) + { + goto bad_arg; + } + st->lsb_depth=value; + } + break; + case OPUS_GET_LSB_DEPTH_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } + *value = st->lsb_depth; + } + break; + case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if (value != OPUS_FRAMESIZE_ARG && value != OPUS_FRAMESIZE_2_5_MS && + value != OPUS_FRAMESIZE_5_MS && value != OPUS_FRAMESIZE_10_MS && + value != OPUS_FRAMESIZE_20_MS && value != OPUS_FRAMESIZE_40_MS && + value != OPUS_FRAMESIZE_60_MS && value != OPUS_FRAMESIZE_VARIABLE) + { + goto bad_arg; + } + st->variable_duration = value; + celt_encoder_ctl(celt_enc, OPUS_SET_EXPERT_FRAME_DURATION(value)); + } + break; + case OPUS_GET_EXPERT_FRAME_DURATION_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } + *value = st->variable_duration; + } + break; + case OPUS_SET_PREDICTION_DISABLED_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if (value > 1 || value < 0) + goto bad_arg; + st->silk_mode.reducedDependency = value; + } + break; + case OPUS_GET_PREDICTION_DISABLED_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + goto bad_arg; + *value = st->silk_mode.reducedDependency; + } + break; + case OPUS_RESET_STATE: + { + void *silk_enc; + silk_EncControlStruct dummy; + silk_enc = (char*)st+st->silk_enc_offset; + + OPUS_CLEAR((char*)&st->OPUS_ENCODER_RESET_START, + sizeof(OpusEncoder)- + ((char*)&st->OPUS_ENCODER_RESET_START - (char*)st)); + + celt_encoder_ctl(celt_enc, OPUS_RESET_STATE); + silk_InitEncoder( silk_enc, st->arch, &dummy ); + st->stream_channels = st->channels; + st->hybrid_stereo_width_Q14 = 1 << 14; + st->prev_HB_gain = Q15ONE; + st->first = 1; + st->mode = MODE_HYBRID; + st->bandwidth = OPUS_BANDWIDTH_FULLBAND; + st->variable_HP_smth2_Q15 = silk_LSHIFT( silk_lin2log( VARIABLE_HP_MIN_CUTOFF_HZ ), 8 ); + } + break; + case OPUS_SET_FORCE_MODE_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + if ((value < MODE_SILK_ONLY || value > MODE_CELT_ONLY) && value != OPUS_AUTO) + { + goto bad_arg; + } + st->user_forced_mode = value; + } + break; + case OPUS_SET_LFE_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + st->lfe = value; + ret = celt_encoder_ctl(celt_enc, OPUS_SET_LFE(value)); + } + break; + case OPUS_SET_ENERGY_MASK_REQUEST: + { + opus_val16 *value = va_arg(ap, opus_val16*); + st->energy_masking = value; + ret = celt_encoder_ctl(celt_enc, OPUS_SET_ENERGY_MASK(value)); + } + break; + + case CELT_GET_MODE_REQUEST: + { + const CELTMode ** value = va_arg(ap, const CELTMode**); + if (!value) + { + goto bad_arg; + } + ret = celt_encoder_ctl(celt_enc, CELT_GET_MODE(value)); + } + break; + default: + /* fprintf(stderr, "unknown opus_encoder_ctl() request: %d", request);*/ + ret = OPUS_UNIMPLEMENTED; + break; + } + va_end(ap); + return ret; +bad_arg: + va_end(ap); + return OPUS_BAD_ARG; +} + +void opus_encoder_destroy(OpusEncoder *st) +{ + opus_free(st); +} diff --git a/src/opus-1.1/src/opus_multistream.c b/src/opus-1.1/src/opus_multistream.c new file mode 100644 index 00000000..09c3639b --- /dev/null +++ b/src/opus-1.1/src/opus_multistream.c @@ -0,0 +1,92 @@ +/* Copyright (c) 2011 Xiph.Org Foundation + Written by Jean-Marc Valin */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "opus_multistream.h" +#include "opus.h" +#include "opus_private.h" +#include "stack_alloc.h" +#include +#include "float_cast.h" +#include "os_support.h" + + +int validate_layout(const ChannelLayout *layout) +{ + int i, max_channel; + + max_channel = layout->nb_streams+layout->nb_coupled_streams; + if (max_channel>255) + return 0; + for (i=0;inb_channels;i++) + { + if (layout->mapping[i] >= max_channel && layout->mapping[i] != 255) + return 0; + } + return 1; +} + + +int get_left_channel(const ChannelLayout *layout, int stream_id, int prev) +{ + int i; + i = (prev<0) ? 0 : prev+1; + for (;inb_channels;i++) + { + if (layout->mapping[i]==stream_id*2) + return i; + } + return -1; +} + +int get_right_channel(const ChannelLayout *layout, int stream_id, int prev) +{ + int i; + i = (prev<0) ? 0 : prev+1; + for (;inb_channels;i++) + { + if (layout->mapping[i]==stream_id*2+1) + return i; + } + return -1; +} + +int get_mono_channel(const ChannelLayout *layout, int stream_id, int prev) +{ + int i; + i = (prev<0) ? 0 : prev+1; + for (;inb_channels;i++) + { + if (layout->mapping[i]==stream_id+layout->nb_coupled_streams) + return i; + } + return -1; +} + diff --git a/src/opus-1.1/src/opus_multistream_decoder.c b/src/opus-1.1/src/opus_multistream_decoder.c new file mode 100644 index 00000000..a05fa1e7 --- /dev/null +++ b/src/opus-1.1/src/opus_multistream_decoder.c @@ -0,0 +1,537 @@ +/* Copyright (c) 2011 Xiph.Org Foundation + Written by Jean-Marc Valin */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "opus_multistream.h" +#include "opus.h" +#include "opus_private.h" +#include "stack_alloc.h" +#include +#include "float_cast.h" +#include "os_support.h" + +struct OpusMSDecoder { + ChannelLayout layout; + /* Decoder states go here */ +}; + + + + +/* DECODER */ + +opus_int32 opus_multistream_decoder_get_size(int nb_streams, int nb_coupled_streams) +{ + int coupled_size; + int mono_size; + + if(nb_streams<1||nb_coupled_streams>nb_streams||nb_coupled_streams<0)return 0; + coupled_size = opus_decoder_get_size(2); + mono_size = opus_decoder_get_size(1); + return align(sizeof(OpusMSDecoder)) + + nb_coupled_streams * align(coupled_size) + + (nb_streams-nb_coupled_streams) * align(mono_size); +} + +int opus_multistream_decoder_init( + OpusMSDecoder *st, + opus_int32 Fs, + int channels, + int streams, + int coupled_streams, + const unsigned char *mapping +) +{ + int coupled_size; + int mono_size; + int i, ret; + char *ptr; + + if ((channels>255) || (channels<1) || (coupled_streams>streams) || + (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0)) + return OPUS_BAD_ARG; + + st->layout.nb_channels = channels; + st->layout.nb_streams = streams; + st->layout.nb_coupled_streams = coupled_streams; + + for (i=0;ilayout.nb_channels;i++) + st->layout.mapping[i] = mapping[i]; + if (!validate_layout(&st->layout)) + return OPUS_BAD_ARG; + + ptr = (char*)st + align(sizeof(OpusMSDecoder)); + coupled_size = opus_decoder_get_size(2); + mono_size = opus_decoder_get_size(1); + + for (i=0;ilayout.nb_coupled_streams;i++) + { + ret=opus_decoder_init((OpusDecoder*)ptr, Fs, 2); + if(ret!=OPUS_OK)return ret; + ptr += align(coupled_size); + } + for (;ilayout.nb_streams;i++) + { + ret=opus_decoder_init((OpusDecoder*)ptr, Fs, 1); + if(ret!=OPUS_OK)return ret; + ptr += align(mono_size); + } + return OPUS_OK; +} + + +OpusMSDecoder *opus_multistream_decoder_create( + opus_int32 Fs, + int channels, + int streams, + int coupled_streams, + const unsigned char *mapping, + int *error +) +{ + int ret; + OpusMSDecoder *st; + if ((channels>255) || (channels<1) || (coupled_streams>streams) || + (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0)) + { + if (error) + *error = OPUS_BAD_ARG; + return NULL; + } + st = (OpusMSDecoder *)opus_alloc(opus_multistream_decoder_get_size(streams, coupled_streams)); + if (st==NULL) + { + if (error) + *error = OPUS_ALLOC_FAIL; + return NULL; + } + ret = opus_multistream_decoder_init(st, Fs, channels, streams, coupled_streams, mapping); + if (error) + *error = ret; + if (ret != OPUS_OK) + { + opus_free(st); + st = NULL; + } + return st; +} + +typedef void (*opus_copy_channel_out_func)( + void *dst, + int dst_stride, + int dst_channel, + const opus_val16 *src, + int src_stride, + int frame_size +); + +static int opus_multistream_packet_validate(const unsigned char *data, + opus_int32 len, int nb_streams, opus_int32 Fs) +{ + int s; + int count; + unsigned char toc; + opus_int16 size[48]; + int samples=0; + opus_int32 packet_offset; + + for (s=0;slayout.nb_streams-1) + { + RESTORE_STACK; + return OPUS_INVALID_PACKET; + } + if (!do_plc) + { + int ret = opus_multistream_packet_validate(data, len, st->layout.nb_streams, Fs); + if (ret < 0) + { + RESTORE_STACK; + return ret; + } else if (ret > frame_size) + { + RESTORE_STACK; + return OPUS_BUFFER_TOO_SMALL; + } + } + for (s=0;slayout.nb_streams;s++) + { + OpusDecoder *dec; + int packet_offset, ret; + + dec = (OpusDecoder*)ptr; + ptr += (s < st->layout.nb_coupled_streams) ? align(coupled_size) : align(mono_size); + + if (!do_plc && len<=0) + { + RESTORE_STACK; + return OPUS_INTERNAL_ERROR; + } + packet_offset = 0; + ret = opus_decode_native(dec, data, len, buf, frame_size, decode_fec, s!=st->layout.nb_streams-1, &packet_offset, soft_clip); + data += packet_offset; + len -= packet_offset; + if (ret <= 0) + { + RESTORE_STACK; + return ret; + } + frame_size = ret; + if (s < st->layout.nb_coupled_streams) + { + int chan, prev; + prev = -1; + /* Copy "left" audio to the channel(s) where it belongs */ + while ( (chan = get_left_channel(&st->layout, s, prev)) != -1) + { + (*copy_channel_out)(pcm, st->layout.nb_channels, chan, + buf, 2, frame_size); + prev = chan; + } + prev = -1; + /* Copy "right" audio to the channel(s) where it belongs */ + while ( (chan = get_right_channel(&st->layout, s, prev)) != -1) + { + (*copy_channel_out)(pcm, st->layout.nb_channels, chan, + buf+1, 2, frame_size); + prev = chan; + } + } else { + int chan, prev; + prev = -1; + /* Copy audio to the channel(s) where it belongs */ + while ( (chan = get_mono_channel(&st->layout, s, prev)) != -1) + { + (*copy_channel_out)(pcm, st->layout.nb_channels, chan, + buf, 1, frame_size); + prev = chan; + } + } + } + /* Handle muted channels */ + for (c=0;clayout.nb_channels;c++) + { + if (st->layout.mapping[c] == 255) + { + (*copy_channel_out)(pcm, st->layout.nb_channels, c, + NULL, 0, frame_size); + } + } + RESTORE_STACK; + return frame_size; +} + +#if !defined(DISABLE_FLOAT_API) +static void opus_copy_channel_out_float( + void *dst, + int dst_stride, + int dst_channel, + const opus_val16 *src, + int src_stride, + int frame_size +) +{ + float *float_dst; + opus_int32 i; + float_dst = (float*)dst; + if (src != NULL) + { + for (i=0;ilayout.nb_streams;s++) + { + OpusDecoder *dec; + dec = (OpusDecoder*)ptr; + if (s < st->layout.nb_coupled_streams) + ptr += align(coupled_size); + else + ptr += align(mono_size); + ret = opus_decoder_ctl(dec, request, &tmp); + if (ret != OPUS_OK) break; + *value ^= tmp; + } + } + break; + case OPUS_RESET_STATE: + { + int s; + for (s=0;slayout.nb_streams;s++) + { + OpusDecoder *dec; + + dec = (OpusDecoder*)ptr; + if (s < st->layout.nb_coupled_streams) + ptr += align(coupled_size); + else + ptr += align(mono_size); + ret = opus_decoder_ctl(dec, OPUS_RESET_STATE); + if (ret != OPUS_OK) + break; + } + } + break; + case OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST: + { + int s; + opus_int32 stream_id; + OpusDecoder **value; + stream_id = va_arg(ap, opus_int32); + if (stream_id<0 || stream_id >= st->layout.nb_streams) + ret = OPUS_BAD_ARG; + value = va_arg(ap, OpusDecoder**); + if (!value) + { + goto bad_arg; + } + for (s=0;slayout.nb_coupled_streams) + ptr += align(coupled_size); + else + ptr += align(mono_size); + } + *value = (OpusDecoder*)ptr; + } + break; + case OPUS_SET_GAIN_REQUEST: + { + int s; + /* This works for int32 params */ + opus_int32 value = va_arg(ap, opus_int32); + for (s=0;slayout.nb_streams;s++) + { + OpusDecoder *dec; + + dec = (OpusDecoder*)ptr; + if (s < st->layout.nb_coupled_streams) + ptr += align(coupled_size); + else + ptr += align(mono_size); + ret = opus_decoder_ctl(dec, request, value); + if (ret != OPUS_OK) + break; + } + } + break; + default: + ret = OPUS_UNIMPLEMENTED; + break; + } + + va_end(ap); + return ret; +bad_arg: + va_end(ap); + return OPUS_BAD_ARG; +} + + +void opus_multistream_decoder_destroy(OpusMSDecoder *st) +{ + opus_free(st); +} diff --git a/src/opus-1.1/src/opus_multistream_encoder.c b/src/opus-1.1/src/opus_multistream_encoder.c new file mode 100644 index 00000000..49e27913 --- /dev/null +++ b/src/opus-1.1/src/opus_multistream_encoder.c @@ -0,0 +1,1174 @@ +/* Copyright (c) 2011 Xiph.Org Foundation + Written by Jean-Marc Valin */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "opus_multistream.h" +#include "opus.h" +#include "opus_private.h" +#include "stack_alloc.h" +#include +#include "float_cast.h" +#include "os_support.h" +#include "mathops.h" +#include "mdct.h" +#include "modes.h" +#include "bands.h" +#include "quant_bands.h" + +typedef struct { + int nb_streams; + int nb_coupled_streams; + unsigned char mapping[8]; +} VorbisLayout; + +/* Index is nb_channel-1*/ +static const VorbisLayout vorbis_mappings[8] = { + {1, 0, {0}}, /* 1: mono */ + {1, 1, {0, 1}}, /* 2: stereo */ + {2, 1, {0, 2, 1}}, /* 3: 1-d surround */ + {2, 2, {0, 1, 2, 3}}, /* 4: quadraphonic surround */ + {3, 2, {0, 4, 1, 2, 3}}, /* 5: 5-channel surround */ + {4, 2, {0, 4, 1, 2, 3, 5}}, /* 6: 5.1 surround */ + {4, 3, {0, 4, 1, 2, 3, 5, 6}}, /* 7: 6.1 surround */ + {5, 3, {0, 6, 1, 2, 3, 4, 5, 7}}, /* 8: 7.1 surround */ +}; + +typedef void (*opus_copy_channel_in_func)( + opus_val16 *dst, + int dst_stride, + const void *src, + int src_stride, + int src_channel, + int frame_size +); + +struct OpusMSEncoder { + ChannelLayout layout; + int lfe_stream; + int application; + int variable_duration; + int surround; + opus_int32 bitrate_bps; + float subframe_mem[3]; + /* Encoder states go here */ + /* then opus_val32 window_mem[channels*120]; */ + /* then opus_val32 preemph_mem[channels]; */ +}; + +static opus_val32 *ms_get_preemph_mem(OpusMSEncoder *st) +{ + int s; + char *ptr; + int coupled_size, mono_size; + + coupled_size = opus_encoder_get_size(2); + mono_size = opus_encoder_get_size(1); + ptr = (char*)st + align(sizeof(OpusMSEncoder)); + for (s=0;slayout.nb_streams;s++) + { + if (s < st->layout.nb_coupled_streams) + ptr += align(coupled_size); + else + ptr += align(mono_size); + } + return (opus_val32*)(ptr+st->layout.nb_channels*120*sizeof(opus_val32)); +} + +static opus_val32 *ms_get_window_mem(OpusMSEncoder *st) +{ + int s; + char *ptr; + int coupled_size, mono_size; + + coupled_size = opus_encoder_get_size(2); + mono_size = opus_encoder_get_size(1); + ptr = (char*)st + align(sizeof(OpusMSEncoder)); + for (s=0;slayout.nb_streams;s++) + { + if (s < st->layout.nb_coupled_streams) + ptr += align(coupled_size); + else + ptr += align(mono_size); + } + return (opus_val32*)ptr; +} + +static int validate_encoder_layout(const ChannelLayout *layout) +{ + int s; + for (s=0;snb_streams;s++) + { + if (s < layout->nb_coupled_streams) + { + if (get_left_channel(layout, s, -1)==-1) + return 0; + if (get_right_channel(layout, s, -1)==-1) + return 0; + } else { + if (get_mono_channel(layout, s, -1)==-1) + return 0; + } + } + return 1; +} + +static void channel_pos(int channels, int pos[8]) +{ + /* Position in the mix: 0 don't mix, 1: left, 2: center, 3:right */ + if (channels==4) + { + pos[0]=1; + pos[1]=3; + pos[2]=1; + pos[3]=3; + } else if (channels==3||channels==5||channels==6) + { + pos[0]=1; + pos[1]=2; + pos[2]=3; + pos[3]=1; + pos[4]=3; + pos[5]=0; + } else if (channels==7) + { + pos[0]=1; + pos[1]=2; + pos[2]=3; + pos[3]=1; + pos[4]=3; + pos[5]=2; + pos[6]=0; + } else if (channels==8) + { + pos[0]=1; + pos[1]=2; + pos[2]=3; + pos[3]=1; + pos[4]=3; + pos[5]=1; + pos[6]=3; + pos[7]=0; + } +} + +#if 1 +/* Computes a rough approximation of log2(2^a + 2^b) */ +static opus_val16 logSum(opus_val16 a, opus_val16 b) +{ + opus_val16 max; + opus_val32 diff; + opus_val16 frac; + static const opus_val16 diff_table[17] = { + QCONST16(0.5000000f, DB_SHIFT), QCONST16(0.2924813f, DB_SHIFT), QCONST16(0.1609640f, DB_SHIFT), QCONST16(0.0849625f, DB_SHIFT), + QCONST16(0.0437314f, DB_SHIFT), QCONST16(0.0221971f, DB_SHIFT), QCONST16(0.0111839f, DB_SHIFT), QCONST16(0.0056136f, DB_SHIFT), + QCONST16(0.0028123f, DB_SHIFT) + }; + int low; + if (a>b) + { + max = a; + diff = SUB32(EXTEND32(a),EXTEND32(b)); + } else { + max = b; + diff = SUB32(EXTEND32(b),EXTEND32(a)); + } + if (diff >= QCONST16(8.f, DB_SHIFT)) + return max; +#ifdef FIXED_POINT + low = SHR32(diff, DB_SHIFT-1); + frac = SHL16(diff - SHL16(low, DB_SHIFT-1), 16-DB_SHIFT); +#else + low = (int)floor(2*diff); + frac = 2*diff - low; +#endif + return max + diff_table[low] + MULT16_16_Q15(frac, SUB16(diff_table[low+1], diff_table[low])); +} +#else +opus_val16 logSum(opus_val16 a, opus_val16 b) +{ + return log2(pow(4, a)+ pow(4, b))/2; +} +#endif + +void surround_analysis(const CELTMode *celt_mode, const void *pcm, opus_val16 *bandLogE, opus_val32 *mem, opus_val32 *preemph_mem, + int len, int overlap, int channels, int rate, opus_copy_channel_in_func copy_channel_in +) +{ + int c; + int i; + int LM; + int pos[8] = {0}; + int upsample; + int frame_size; + opus_val16 channel_offset; + opus_val32 bandE[21]; + opus_val16 maskLogE[3][21]; + VARDECL(opus_val32, in); + VARDECL(opus_val16, x); + VARDECL(opus_val32, freq); + SAVE_STACK; + + upsample = resampling_factor(rate); + frame_size = len*upsample; + + for (LM=0;LMmaxLM;LM++) + if (celt_mode->shortMdctSize<preemph, preemph_mem+c, 0); + clt_mdct_forward(&celt_mode->mdct, in, freq, celt_mode->window, overlap, celt_mode->maxLM-LM, 1); + if (upsample != 1) + { + int bound = len; + for (i=0;i=0;i--) + bandLogE[21*c+i] = MAX16(bandLogE[21*c+i], bandLogE[21*c+i+1]-QCONST16(2.f, DB_SHIFT)); + if (pos[c]==1) + { + for (i=0;i<21;i++) + maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]); + } else if (pos[c]==3) + { + for (i=0;i<21;i++) + maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]); + } else if (pos[c]==2) + { + for (i=0;i<21;i++) + { + maskLogE[0][i] = logSum(maskLogE[0][i], bandLogE[21*c+i]-QCONST16(.5f, DB_SHIFT)); + maskLogE[2][i] = logSum(maskLogE[2][i], bandLogE[21*c+i]-QCONST16(.5f, DB_SHIFT)); + } + } +#if 0 + for (i=0;i<21;i++) + printf("%f ", bandLogE[21*c+i]); + float sum=0; + for (i=0;i<21;i++) + sum += bandLogE[21*c+i]; + printf("%f ", sum/21); +#endif + OPUS_COPY(mem+c*overlap, in+frame_size, overlap); + } + for (i=0;i<21;i++) + maskLogE[1][i] = MIN32(maskLogE[0][i],maskLogE[2][i]); + channel_offset = HALF16(celt_log2(QCONST32(2.f,14)/(channels-1))); + for (c=0;c<3;c++) + for (i=0;i<21;i++) + maskLogE[c][i] += channel_offset; +#if 0 + for (c=0;c<3;c++) + { + for (i=0;i<21;i++) + printf("%f ", maskLogE[c][i]); + } +#endif + for (c=0;cnb_streams||nb_coupled_streams<0)return 0; + coupled_size = opus_encoder_get_size(2); + mono_size = opus_encoder_get_size(1); + return align(sizeof(OpusMSEncoder)) + + nb_coupled_streams * align(coupled_size) + + (nb_streams-nb_coupled_streams) * align(mono_size); +} + +opus_int32 opus_multistream_surround_encoder_get_size(int channels, int mapping_family) +{ + int nb_streams; + int nb_coupled_streams; + opus_int32 size; + + if (mapping_family==0) + { + if (channels==1) + { + nb_streams=1; + nb_coupled_streams=0; + } else if (channels==2) + { + nb_streams=1; + nb_coupled_streams=1; + } else + return 0; + } else if (mapping_family==1 && channels<=8 && channels>=1) + { + nb_streams=vorbis_mappings[channels-1].nb_streams; + nb_coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams; + } else if (mapping_family==255) + { + nb_streams=channels; + nb_coupled_streams=0; + } else + return 0; + size = opus_multistream_encoder_get_size(nb_streams, nb_coupled_streams); + if (channels>2) + { + size += channels*(120*sizeof(opus_val32) + sizeof(opus_val32)); + } + return size; +} + + +static int opus_multistream_encoder_init_impl( + OpusMSEncoder *st, + opus_int32 Fs, + int channels, + int streams, + int coupled_streams, + const unsigned char *mapping, + int application, + int surround +) +{ + int coupled_size; + int mono_size; + int i, ret; + char *ptr; + + if ((channels>255) || (channels<1) || (coupled_streams>streams) || + (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0)) + return OPUS_BAD_ARG; + + st->layout.nb_channels = channels; + st->layout.nb_streams = streams; + st->layout.nb_coupled_streams = coupled_streams; + st->subframe_mem[0]=st->subframe_mem[1]=st->subframe_mem[2]=0; + if (!surround) + st->lfe_stream = -1; + st->bitrate_bps = OPUS_AUTO; + st->application = application; + st->variable_duration = OPUS_FRAMESIZE_ARG; + for (i=0;ilayout.nb_channels;i++) + st->layout.mapping[i] = mapping[i]; + if (!validate_layout(&st->layout) || !validate_encoder_layout(&st->layout)) + return OPUS_BAD_ARG; + ptr = (char*)st + align(sizeof(OpusMSEncoder)); + coupled_size = opus_encoder_get_size(2); + mono_size = opus_encoder_get_size(1); + + for (i=0;ilayout.nb_coupled_streams;i++) + { + ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 2, application); + if(ret!=OPUS_OK)return ret; + if (i==st->lfe_stream) + opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1)); + ptr += align(coupled_size); + } + for (;ilayout.nb_streams;i++) + { + ret = opus_encoder_init((OpusEncoder*)ptr, Fs, 1, application); + if (i==st->lfe_stream) + opus_encoder_ctl((OpusEncoder*)ptr, OPUS_SET_LFE(1)); + if(ret!=OPUS_OK)return ret; + ptr += align(mono_size); + } + if (surround) + { + OPUS_CLEAR(ms_get_preemph_mem(st), channels); + OPUS_CLEAR(ms_get_window_mem(st), channels*120); + } + st->surround = surround; + return OPUS_OK; +} + +int opus_multistream_encoder_init( + OpusMSEncoder *st, + opus_int32 Fs, + int channels, + int streams, + int coupled_streams, + const unsigned char *mapping, + int application +) +{ + return opus_multistream_encoder_init_impl(st, Fs, channels, streams, coupled_streams, mapping, application, 0); +} + +int opus_multistream_surround_encoder_init( + OpusMSEncoder *st, + opus_int32 Fs, + int channels, + int mapping_family, + int *streams, + int *coupled_streams, + unsigned char *mapping, + int application +) +{ + if ((channels>255) || (channels<1)) + return OPUS_BAD_ARG; + st->lfe_stream = -1; + if (mapping_family==0) + { + if (channels==1) + { + *streams=1; + *coupled_streams=0; + mapping[0]=0; + } else if (channels==2) + { + *streams=1; + *coupled_streams=1; + mapping[0]=0; + mapping[1]=1; + } else + return OPUS_UNIMPLEMENTED; + } else if (mapping_family==1 && channels<=8 && channels>=1) + { + int i; + *streams=vorbis_mappings[channels-1].nb_streams; + *coupled_streams=vorbis_mappings[channels-1].nb_coupled_streams; + for (i=0;i=6) + st->lfe_stream = *streams-1; + } else if (mapping_family==255) + { + int i; + *streams=channels; + *coupled_streams=0; + for(i=0;i2&&mapping_family==1); +} + +OpusMSEncoder *opus_multistream_encoder_create( + opus_int32 Fs, + int channels, + int streams, + int coupled_streams, + const unsigned char *mapping, + int application, + int *error +) +{ + int ret; + OpusMSEncoder *st; + if ((channels>255) || (channels<1) || (coupled_streams>streams) || + (coupled_streams+streams>255) || (streams<1) || (coupled_streams<0)) + { + if (error) + *error = OPUS_BAD_ARG; + return NULL; + } + st = (OpusMSEncoder *)opus_alloc(opus_multistream_encoder_get_size(streams, coupled_streams)); + if (st==NULL) + { + if (error) + *error = OPUS_ALLOC_FAIL; + return NULL; + } + ret = opus_multistream_encoder_init(st, Fs, channels, streams, coupled_streams, mapping, application); + if (ret != OPUS_OK) + { + opus_free(st); + st = NULL; + } + if (error) + *error = ret; + return st; +} + +OpusMSEncoder *opus_multistream_surround_encoder_create( + opus_int32 Fs, + int channels, + int mapping_family, + int *streams, + int *coupled_streams, + unsigned char *mapping, + int application, + int *error +) +{ + int ret; + OpusMSEncoder *st; + if ((channels>255) || (channels<1)) + { + if (error) + *error = OPUS_BAD_ARG; + return NULL; + } + st = (OpusMSEncoder *)opus_alloc(opus_multistream_surround_encoder_get_size(channels, mapping_family)); + if (st==NULL) + { + if (error) + *error = OPUS_ALLOC_FAIL; + return NULL; + } + ret = opus_multistream_surround_encoder_init(st, Fs, channels, mapping_family, streams, coupled_streams, mapping, application); + if (ret != OPUS_OK) + { + opus_free(st); + st = NULL; + } + if (error) + *error = ret; + return st; +} + +static void surround_rate_allocation( + OpusMSEncoder *st, + opus_int32 *rate, + int frame_size + ) +{ + int i; + opus_int32 channel_rate; + opus_int32 Fs; + char *ptr; + int stream_offset; + int lfe_offset; + int coupled_ratio; /* Q8 */ + int lfe_ratio; /* Q8 */ + + ptr = (char*)st + align(sizeof(OpusMSEncoder)); + opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs)); + + if (st->bitrate_bps > st->layout.nb_channels*40000) + stream_offset = 20000; + else + stream_offset = st->bitrate_bps/st->layout.nb_channels/2; + stream_offset += 60*(Fs/frame_size-50); + /* We start by giving each stream (coupled or uncoupled) the same bitrate. + This models the main saving of coupled channels over uncoupled. */ + /* The LFE stream is an exception to the above and gets fewer bits. */ + lfe_offset = 3500 + 60*(Fs/frame_size-50); + /* Coupled streams get twice the mono rate after the first 20 kb/s. */ + coupled_ratio = 512; + /* Should depend on the bitrate, for now we assume LFE gets 1/8 the bits of mono */ + lfe_ratio = 32; + + /* Compute bitrate allocation between streams */ + if (st->bitrate_bps==OPUS_AUTO) + { + channel_rate = Fs+60*Fs/frame_size; + } else if (st->bitrate_bps==OPUS_BITRATE_MAX) + { + channel_rate = 300000; + } else { + int nb_lfe; + int nb_uncoupled; + int nb_coupled; + int total; + nb_lfe = (st->lfe_stream!=-1); + nb_coupled = st->layout.nb_coupled_streams; + nb_uncoupled = st->layout.nb_streams-nb_coupled-nb_lfe; + total = (nb_uncoupled<<8) /* mono */ + + coupled_ratio*nb_coupled /* stereo */ + + nb_lfe*lfe_ratio; + channel_rate = 256*(st->bitrate_bps-lfe_offset*nb_lfe-stream_offset*(nb_coupled+nb_uncoupled))/total; + } +#ifndef FIXED_POINT + if (st->variable_duration==OPUS_FRAMESIZE_VARIABLE && frame_size != Fs/50) + { + opus_int32 bonus; + bonus = 60*(Fs/frame_size-50); + channel_rate += bonus; + } +#endif + + for (i=0;ilayout.nb_streams;i++) + { + if (ilayout.nb_coupled_streams) + rate[i] = stream_offset+(channel_rate*coupled_ratio>>8); + else if (i!=st->lfe_stream) + rate[i] = stream_offset+channel_rate; + else + rate[i] = lfe_offset+(channel_rate*lfe_ratio>>8); + } +} + +/* Max size in case the encoder decides to return three frames */ +#define MS_FRAME_TMP (3*1275+7) +static int opus_multistream_encode_native +( + OpusMSEncoder *st, + opus_copy_channel_in_func copy_channel_in, + const void *pcm, + int analysis_frame_size, + unsigned char *data, + opus_int32 max_data_bytes, + int lsb_depth, + downmix_func downmix +) +{ + opus_int32 Fs; + int coupled_size; + int mono_size; + int s; + char *ptr; + int tot_size; + VARDECL(opus_val16, buf); + VARDECL(opus_val16, bandSMR); + unsigned char tmp_data[MS_FRAME_TMP]; + OpusRepacketizer rp; + opus_int32 vbr; + const CELTMode *celt_mode; + opus_int32 bitrates[256]; + opus_val16 bandLogE[42]; + opus_val32 *mem = NULL; + opus_val32 *preemph_mem=NULL; + int frame_size; + ALLOC_STACK; + + if (st->surround) + { + preemph_mem = ms_get_preemph_mem(st); + mem = ms_get_window_mem(st); + } + + ptr = (char*)st + align(sizeof(OpusMSEncoder)); + opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_SAMPLE_RATE(&Fs)); + opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_VBR(&vbr)); + opus_encoder_ctl((OpusEncoder*)ptr, CELT_GET_MODE(&celt_mode)); + + { + opus_int32 delay_compensation; + int channels; + + channels = st->layout.nb_streams + st->layout.nb_coupled_streams; + opus_encoder_ctl((OpusEncoder*)ptr, OPUS_GET_LOOKAHEAD(&delay_compensation)); + delay_compensation -= Fs/400; + frame_size = compute_frame_size(pcm, analysis_frame_size, + st->variable_duration, channels, Fs, st->bitrate_bps, + delay_compensation, downmix +#ifndef DISABLE_FLOAT_API + , st->subframe_mem +#endif + ); + } + + if (400*frame_size < Fs) + { + RESTORE_STACK; + return OPUS_BAD_ARG; + } + /* Validate frame_size before using it to allocate stack space. + This mirrors the checks in opus_encode[_float](). */ + if (400*frame_size != Fs && 200*frame_size != Fs && + 100*frame_size != Fs && 50*frame_size != Fs && + 25*frame_size != Fs && 50*frame_size != 3*Fs) + { + RESTORE_STACK; + return OPUS_BAD_ARG; + } + ALLOC(buf, 2*frame_size, opus_val16); + coupled_size = opus_encoder_get_size(2); + mono_size = opus_encoder_get_size(1); + + ALLOC(bandSMR, 21*st->layout.nb_channels, opus_val16); + if (st->surround) + { + surround_analysis(celt_mode, pcm, bandSMR, mem, preemph_mem, frame_size, 120, st->layout.nb_channels, Fs, copy_channel_in); + } + + if (max_data_bytes < 4*st->layout.nb_streams-1) + { + RESTORE_STACK; + return OPUS_BUFFER_TOO_SMALL; + } + + /* Compute bitrate allocation between streams (this could be a lot better) */ + surround_rate_allocation(st, bitrates, frame_size); + + if (!vbr) + max_data_bytes = IMIN(max_data_bytes, 3*st->bitrate_bps/(3*8*Fs/frame_size)); + + ptr = (char*)st + align(sizeof(OpusMSEncoder)); + for (s=0;slayout.nb_streams;s++) + { + OpusEncoder *enc; + enc = (OpusEncoder*)ptr; + if (s < st->layout.nb_coupled_streams) + ptr += align(coupled_size); + else + ptr += align(mono_size); + opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrates[s])); + if (st->surround) + { + opus_int32 equiv_rate; + equiv_rate = st->bitrate_bps; + if (frame_size*50 < Fs) + equiv_rate -= 60*(Fs/frame_size - 50)*st->layout.nb_channels; + if (equiv_rate > 10000*st->layout.nb_channels) + opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_FULLBAND)); + else if (equiv_rate > 7000*st->layout.nb_channels) + opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_SUPERWIDEBAND)); + else if (equiv_rate > 5000*st->layout.nb_channels) + opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_WIDEBAND)); + else + opus_encoder_ctl(enc, OPUS_SET_BANDWIDTH(OPUS_BANDWIDTH_NARROWBAND)); + if (s < st->layout.nb_coupled_streams) + { + /* To preserve the spatial image, force stereo CELT on coupled streams */ + opus_encoder_ctl(enc, OPUS_SET_FORCE_MODE(MODE_CELT_ONLY)); + opus_encoder_ctl(enc, OPUS_SET_FORCE_CHANNELS(2)); + } + } + } + + ptr = (char*)st + align(sizeof(OpusMSEncoder)); + /* Counting ToC */ + tot_size = 0; + for (s=0;slayout.nb_streams;s++) + { + OpusEncoder *enc; + int len; + int curr_max; + int c1, c2; + + opus_repacketizer_init(&rp); + enc = (OpusEncoder*)ptr; + if (s < st->layout.nb_coupled_streams) + { + int i; + int left, right; + left = get_left_channel(&st->layout, s, -1); + right = get_right_channel(&st->layout, s, -1); + (*copy_channel_in)(buf, 2, + pcm, st->layout.nb_channels, left, frame_size); + (*copy_channel_in)(buf+1, 2, + pcm, st->layout.nb_channels, right, frame_size); + ptr += align(coupled_size); + if (st->surround) + { + for (i=0;i<21;i++) + { + bandLogE[i] = bandSMR[21*left+i]; + bandLogE[21+i] = bandSMR[21*right+i]; + } + } + c1 = left; + c2 = right; + } else { + int i; + int chan = get_mono_channel(&st->layout, s, -1); + (*copy_channel_in)(buf, 1, + pcm, st->layout.nb_channels, chan, frame_size); + ptr += align(mono_size); + if (st->surround) + { + for (i=0;i<21;i++) + bandLogE[i] = bandSMR[21*chan+i]; + } + c1 = chan; + c2 = -1; + } + if (st->surround) + opus_encoder_ctl(enc, OPUS_SET_ENERGY_MASK(bandLogE)); + /* number of bytes left (+Toc) */ + curr_max = max_data_bytes - tot_size; + /* Reserve three bytes for the last stream and four for the others */ + curr_max -= IMAX(0,4*(st->layout.nb_streams-s-1)-1); + curr_max = IMIN(curr_max,MS_FRAME_TMP); + if (!vbr && s == st->layout.nb_streams-1) + opus_encoder_ctl(enc, OPUS_SET_BITRATE(curr_max*(8*Fs/frame_size))); + len = opus_encode_native(enc, buf, frame_size, tmp_data, curr_max, lsb_depth, + pcm, analysis_frame_size, c1, c2, st->layout.nb_channels, downmix); + if (len<0) + { + RESTORE_STACK; + return len; + } + /* We need to use the repacketizer to add the self-delimiting lengths + while taking into account the fact that the encoder can now return + more than one frame at a time (e.g. 60 ms CELT-only) */ + opus_repacketizer_cat(&rp, tmp_data, len); + len = opus_repacketizer_out_range_impl(&rp, 0, opus_repacketizer_get_nb_frames(&rp), + data, max_data_bytes-tot_size, s != st->layout.nb_streams-1, !vbr && s == st->layout.nb_streams-1); + data += len; + tot_size += len; + } + /*printf("\n");*/ + RESTORE_STACK; + return tot_size; +} + +#if !defined(DISABLE_FLOAT_API) +static void opus_copy_channel_in_float( + opus_val16 *dst, + int dst_stride, + const void *src, + int src_stride, + int src_channel, + int frame_size +) +{ + const float *float_src; + opus_int32 i; + float_src = (const float *)src; + for (i=0;ibitrate_bps = value; + } + break; + case OPUS_GET_BITRATE_REQUEST: + { + int s; + opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } + *value = 0; + for (s=0;slayout.nb_streams;s++) + { + opus_int32 rate; + OpusEncoder *enc; + enc = (OpusEncoder*)ptr; + if (s < st->layout.nb_coupled_streams) + ptr += align(coupled_size); + else + ptr += align(mono_size); + opus_encoder_ctl(enc, request, &rate); + *value += rate; + } + } + break; + case OPUS_GET_LSB_DEPTH_REQUEST: + case OPUS_GET_VBR_REQUEST: + case OPUS_GET_APPLICATION_REQUEST: + case OPUS_GET_BANDWIDTH_REQUEST: + case OPUS_GET_COMPLEXITY_REQUEST: + case OPUS_GET_PACKET_LOSS_PERC_REQUEST: + case OPUS_GET_DTX_REQUEST: + case OPUS_GET_VOICE_RATIO_REQUEST: + case OPUS_GET_VBR_CONSTRAINT_REQUEST: + case OPUS_GET_SIGNAL_REQUEST: + case OPUS_GET_LOOKAHEAD_REQUEST: + case OPUS_GET_SAMPLE_RATE_REQUEST: + case OPUS_GET_INBAND_FEC_REQUEST: + case OPUS_GET_FORCE_CHANNELS_REQUEST: + case OPUS_GET_PREDICTION_DISABLED_REQUEST: + { + OpusEncoder *enc; + /* For int32* GET params, just query the first stream */ + opus_int32 *value = va_arg(ap, opus_int32*); + enc = (OpusEncoder*)ptr; + ret = opus_encoder_ctl(enc, request, value); + } + break; + case OPUS_GET_FINAL_RANGE_REQUEST: + { + int s; + opus_uint32 *value = va_arg(ap, opus_uint32*); + opus_uint32 tmp; + if (!value) + { + goto bad_arg; + } + *value=0; + for (s=0;slayout.nb_streams;s++) + { + OpusEncoder *enc; + enc = (OpusEncoder*)ptr; + if (s < st->layout.nb_coupled_streams) + ptr += align(coupled_size); + else + ptr += align(mono_size); + ret = opus_encoder_ctl(enc, request, &tmp); + if (ret != OPUS_OK) break; + *value ^= tmp; + } + } + break; + case OPUS_SET_LSB_DEPTH_REQUEST: + case OPUS_SET_COMPLEXITY_REQUEST: + case OPUS_SET_VBR_REQUEST: + case OPUS_SET_VBR_CONSTRAINT_REQUEST: + case OPUS_SET_MAX_BANDWIDTH_REQUEST: + case OPUS_SET_BANDWIDTH_REQUEST: + case OPUS_SET_SIGNAL_REQUEST: + case OPUS_SET_APPLICATION_REQUEST: + case OPUS_SET_INBAND_FEC_REQUEST: + case OPUS_SET_PACKET_LOSS_PERC_REQUEST: + case OPUS_SET_DTX_REQUEST: + case OPUS_SET_FORCE_MODE_REQUEST: + case OPUS_SET_FORCE_CHANNELS_REQUEST: + case OPUS_SET_PREDICTION_DISABLED_REQUEST: + { + int s; + /* This works for int32 params */ + opus_int32 value = va_arg(ap, opus_int32); + for (s=0;slayout.nb_streams;s++) + { + OpusEncoder *enc; + + enc = (OpusEncoder*)ptr; + if (s < st->layout.nb_coupled_streams) + ptr += align(coupled_size); + else + ptr += align(mono_size); + ret = opus_encoder_ctl(enc, request, value); + if (ret != OPUS_OK) + break; + } + } + break; + case OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST: + { + int s; + opus_int32 stream_id; + OpusEncoder **value; + stream_id = va_arg(ap, opus_int32); + if (stream_id<0 || stream_id >= st->layout.nb_streams) + ret = OPUS_BAD_ARG; + value = va_arg(ap, OpusEncoder**); + if (!value) + { + goto bad_arg; + } + for (s=0;slayout.nb_coupled_streams) + ptr += align(coupled_size); + else + ptr += align(mono_size); + } + *value = (OpusEncoder*)ptr; + } + break; + case OPUS_SET_EXPERT_FRAME_DURATION_REQUEST: + { + opus_int32 value = va_arg(ap, opus_int32); + st->variable_duration = value; + } + break; + case OPUS_GET_EXPERT_FRAME_DURATION_REQUEST: + { + opus_int32 *value = va_arg(ap, opus_int32*); + if (!value) + { + goto bad_arg; + } + *value = st->variable_duration; + } + break; + case OPUS_RESET_STATE: + { + int s; + st->subframe_mem[0] = st->subframe_mem[1] = st->subframe_mem[2] = 0; + if (st->surround) + { + OPUS_CLEAR(ms_get_preemph_mem(st), st->layout.nb_channels); + OPUS_CLEAR(ms_get_window_mem(st), st->layout.nb_channels*120); + } + for (s=0;slayout.nb_streams;s++) + { + OpusEncoder *enc; + enc = (OpusEncoder*)ptr; + if (s < st->layout.nb_coupled_streams) + ptr += align(coupled_size); + else + ptr += align(mono_size); + ret = opus_encoder_ctl(enc, OPUS_RESET_STATE); + if (ret != OPUS_OK) + break; + } + } + break; + default: + ret = OPUS_UNIMPLEMENTED; + break; + } + + va_end(ap); + return ret; +bad_arg: + va_end(ap); + return OPUS_BAD_ARG; +} + +void opus_multistream_encoder_destroy(OpusMSEncoder *st) +{ + opus_free(st); +} diff --git a/src/opus-1.1/src/opus_private.h b/src/opus-1.1/src/opus_private.h new file mode 100644 index 00000000..83225f2b --- /dev/null +++ b/src/opus-1.1/src/opus_private.h @@ -0,0 +1,129 @@ +/* Copyright (c) 2012 Xiph.Org Foundation + Written by Jean-Marc Valin */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#ifndef OPUS_PRIVATE_H +#define OPUS_PRIVATE_H + +#include "arch.h" +#include "opus.h" +#include "celt.h" + +struct OpusRepacketizer { + unsigned char toc; + int nb_frames; + const unsigned char *frames[48]; + opus_int16 len[48]; + int framesize; +}; + +typedef struct ChannelLayout { + int nb_channels; + int nb_streams; + int nb_coupled_streams; + unsigned char mapping[256]; +} ChannelLayout; + +int validate_layout(const ChannelLayout *layout); +int get_left_channel(const ChannelLayout *layout, int stream_id, int prev); +int get_right_channel(const ChannelLayout *layout, int stream_id, int prev); +int get_mono_channel(const ChannelLayout *layout, int stream_id, int prev); + + + +#define MODE_SILK_ONLY 1000 +#define MODE_HYBRID 1001 +#define MODE_CELT_ONLY 1002 + +#define OPUS_SET_VOICE_RATIO_REQUEST 11018 +#define OPUS_GET_VOICE_RATIO_REQUEST 11019 + +/** Configures the encoder's expected percentage of voice + * opposed to music or other signals. + * + * @note This interface is currently more aspiration than actuality. It's + * ultimately expected to bias an automatic signal classifier, but it currently + * just shifts the static bitrate to mode mapping around a little bit. + * + * @param[in] x int: Voice percentage in the range 0-100, inclusive. + * @hideinitializer */ +#define OPUS_SET_VOICE_RATIO(x) OPUS_SET_VOICE_RATIO_REQUEST, __opus_check_int(x) +/** Gets the encoder's configured voice ratio value, @see OPUS_SET_VOICE_RATIO + * + * @param[out] x int*: Voice percentage in the range 0-100, inclusive. + * @hideinitializer */ +#define OPUS_GET_VOICE_RATIO(x) OPUS_GET_VOICE_RATIO_REQUEST, __opus_check_int_ptr(x) + + +#define OPUS_SET_FORCE_MODE_REQUEST 11002 +#define OPUS_SET_FORCE_MODE(x) OPUS_SET_FORCE_MODE_REQUEST, __opus_check_int(x) + +typedef void (*downmix_func)(const void *, opus_val32 *, int, int, int, int, int); +void downmix_float(const void *_x, opus_val32 *sub, int subframe, int offset, int c1, int c2, int C); +void downmix_int(const void *_x, opus_val32 *sub, int subframe, int offset, int c1, int c2, int C); + +int optimize_framesize(const opus_val16 *x, int len, int C, opus_int32 Fs, + int bitrate, opus_val16 tonality, float *mem, int buffering, + downmix_func downmix); + +int encode_size(int size, unsigned char *data); + +opus_int32 frame_size_select(opus_int32 frame_size, int variable_duration, opus_int32 Fs); + +opus_int32 compute_frame_size(const void *analysis_pcm, int frame_size, + int variable_duration, int C, opus_int32 Fs, int bitrate_bps, + int delay_compensation, downmix_func downmix +#ifndef DISABLE_FLOAT_API + , float *subframe_mem +#endif + ); + +opus_int32 opus_encode_native(OpusEncoder *st, const opus_val16 *pcm, int frame_size, + unsigned char *data, opus_int32 out_data_bytes, int lsb_depth, + const void *analysis_pcm, opus_int32 analysis_size, int c1, int c2, int analysis_channels, downmix_func downmix); + +int opus_decode_native(OpusDecoder *st, const unsigned char *data, opus_int32 len, + opus_val16 *pcm, int frame_size, int decode_fec, int self_delimited, + opus_int32 *packet_offset, int soft_clip); + +/* Make sure everything's aligned to sizeof(void *) bytes */ +static OPUS_INLINE int align(int i) +{ + return (i+(int)sizeof(void *)-1)&-(int)sizeof(void *); +} + +int opus_packet_parse_impl(const unsigned char *data, opus_int32 len, + int self_delimited, unsigned char *out_toc, + const unsigned char *frames[48], opus_int16 size[48], + int *payload_offset, opus_int32 *packet_offset); + +opus_int32 opus_repacketizer_out_range_impl(OpusRepacketizer *rp, int begin, int end, + unsigned char *data, opus_int32 maxlen, int self_delimited, int pad); + +int pad_frame(unsigned char *data, opus_int32 len, opus_int32 new_len); + +#endif /* OPUS_PRIVATE_H */ diff --git a/src/opus-1.1/src/repacketizer.c b/src/opus-1.1/src/repacketizer.c new file mode 100644 index 00000000..a62675ce --- /dev/null +++ b/src/opus-1.1/src/repacketizer.c @@ -0,0 +1,345 @@ +/* Copyright (c) 2011 Xiph.Org Foundation + Written by Jean-Marc Valin */ +/* + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + - Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "opus.h" +#include "opus_private.h" +#include "os_support.h" + + +int opus_repacketizer_get_size(void) +{ + return sizeof(OpusRepacketizer); +} + +OpusRepacketizer *opus_repacketizer_init(OpusRepacketizer *rp) +{ + rp->nb_frames = 0; + return rp; +} + +OpusRepacketizer *opus_repacketizer_create(void) +{ + OpusRepacketizer *rp; + rp=(OpusRepacketizer *)opus_alloc(opus_repacketizer_get_size()); + if(rp==NULL)return NULL; + return opus_repacketizer_init(rp); +} + +void opus_repacketizer_destroy(OpusRepacketizer *rp) +{ + opus_free(rp); +} + +static int opus_repacketizer_cat_impl(OpusRepacketizer *rp, const unsigned char *data, opus_int32 len, int self_delimited) +{ + unsigned char tmp_toc; + int curr_nb_frames,ret; + /* Set of check ToC */ + if (len<1) return OPUS_INVALID_PACKET; + if (rp->nb_frames == 0) + { + rp->toc = data[0]; + rp->framesize = opus_packet_get_samples_per_frame(data, 8000); + } else if ((rp->toc&0xFC) != (data[0]&0xFC)) + { + /*fprintf(stderr, "toc mismatch: 0x%x vs 0x%x\n", rp->toc, data[0]);*/ + return OPUS_INVALID_PACKET; + } + curr_nb_frames = opus_packet_get_nb_frames(data, len); + if(curr_nb_frames<1) return OPUS_INVALID_PACKET; + + /* Check the 120 ms maximum packet size */ + if ((curr_nb_frames+rp->nb_frames)*rp->framesize > 960) + { + return OPUS_INVALID_PACKET; + } + + ret=opus_packet_parse_impl(data, len, self_delimited, &tmp_toc, &rp->frames[rp->nb_frames], &rp->len[rp->nb_frames], NULL, NULL); + if(ret<1)return ret; + + rp->nb_frames += curr_nb_frames; + return OPUS_OK; +} + +int opus_repacketizer_cat(OpusRepacketizer *rp, const unsigned char *data, opus_int32 len) +{ + return opus_repacketizer_cat_impl(rp, data, len, 0); +} + +int opus_repacketizer_get_nb_frames(OpusRepacketizer *rp) +{ + return rp->nb_frames; +} + +opus_int32 opus_repacketizer_out_range_impl(OpusRepacketizer *rp, int begin, int end, + unsigned char *data, opus_int32 maxlen, int self_delimited, int pad) +{ + int i, count; + opus_int32 tot_size; + opus_int16 *len; + const unsigned char **frames; + unsigned char * ptr; + + if (begin<0 || begin>=end || end>rp->nb_frames) + { + /*fprintf(stderr, "%d %d %d\n", begin, end, rp->nb_frames);*/ + return OPUS_BAD_ARG; + } + count = end-begin; + + len = rp->len+begin; + frames = rp->frames+begin; + if (self_delimited) + tot_size = 1 + (len[count-1]>=252); + else + tot_size = 0; + + ptr = data; + if (count==1) + { + /* Code 0 */ + tot_size += len[0]+1; + if (tot_size > maxlen) + return OPUS_BUFFER_TOO_SMALL; + *ptr++ = rp->toc&0xFC; + } else if (count==2) + { + if (len[1] == len[0]) + { + /* Code 1 */ + tot_size += 2*len[0]+1; + if (tot_size > maxlen) + return OPUS_BUFFER_TOO_SMALL; + *ptr++ = (rp->toc&0xFC) | 0x1; + } else { + /* Code 2 */ + tot_size += len[0]+len[1]+2+(len[0]>=252); + if (tot_size > maxlen) + return OPUS_BUFFER_TOO_SMALL; + *ptr++ = (rp->toc&0xFC) | 0x2; + ptr += encode_size(len[0], ptr); + } + } + if (count > 2 || (pad && tot_size < maxlen)) + { + /* Code 3 */ + int vbr; + int pad_amount=0; + + /* Restart the process for the padding case */ + ptr = data; + if (self_delimited) + tot_size = 1 + (len[count-1]>=252); + else + tot_size = 0; + vbr = 0; + for (i=1;i=252) + len[i]; + tot_size += len[count-1]; + + if (tot_size > maxlen) + return OPUS_BUFFER_TOO_SMALL; + *ptr++ = (rp->toc&0xFC) | 0x3; + *ptr++ = count | 0x80; + } else { + tot_size += count*len[0]+2; + if (tot_size > maxlen) + return OPUS_BUFFER_TOO_SMALL; + *ptr++ = (rp->toc&0xFC) | 0x3; + *ptr++ = count; + } + pad_amount = pad ? (maxlen-tot_size) : 0; + if (pad_amount != 0) + { + int nb_255s; + data[1] |= 0x40; + nb_255s = (pad_amount-1)/255; + for (i=0;inb_frames, data, maxlen, 0, 0); +} + +int opus_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len) +{ + OpusRepacketizer rp; + opus_int32 ret; + if (len < 1) + return OPUS_BAD_ARG; + if (len==new_len) + return OPUS_OK; + else if (len > new_len) + return OPUS_BAD_ARG; + opus_repacketizer_init(&rp); + /* Moving payload to the end of the packet so we can do in-place padding */ + OPUS_MOVE(data+new_len-len, data, len); + opus_repacketizer_cat(&rp, data+new_len-len, len); + ret = opus_repacketizer_out_range_impl(&rp, 0, rp.nb_frames, data, new_len, 0, 1); + if (ret > 0) + return OPUS_OK; + else + return ret; +} + +opus_int32 opus_packet_unpad(unsigned char *data, opus_int32 len) +{ + OpusRepacketizer rp; + opus_int32 ret; + if (len < 1) + return OPUS_BAD_ARG; + opus_repacketizer_init(&rp); + ret = opus_repacketizer_cat(&rp, data, len); + if (ret < 0) + return ret; + ret = opus_repacketizer_out_range_impl(&rp, 0, rp.nb_frames, data, len, 0, 0); + celt_assert(ret > 0 && ret <= len); + return ret; +} + +int opus_multistream_packet_pad(unsigned char *data, opus_int32 len, opus_int32 new_len, int nb_streams) +{ + int s; + int count; + unsigned char toc; + opus_int16 size[48]; + opus_int32 packet_offset; + opus_int32 amount; + + if (len < 1) + return OPUS_BAD_ARG; + if (len==new_len) + return OPUS_OK; + else if (len > new_len) + return OPUS_BAD_ARG; + amount = new_len - len; + /* Seek to last stream */ + for (s=0;s